From 37c097e4ae1ff4a846edb615cc322ee5e547a709 Mon Sep 17 00:00:00 2001 From: Andinus Date: Sat, 4 Apr 2020 18:40:04 +0530 Subject: Add support for unveil on OpenBSD --- cmd/cetus/app.go | 99 +++++++++++++++++++++++++++++++++++++++++++++ cmd/cetus/main.go | 100 ---------------------------------------------- cmd/cetus/main_openbsd.go | 75 ++++++++++++++++++++++++++++++++++ cmd/cetus/main_other.go | 7 ++++ 4 files changed, 181 insertions(+), 100 deletions(-) create mode 100644 cmd/cetus/app.go delete mode 100644 cmd/cetus/main.go create mode 100644 cmd/cetus/main_openbsd.go create mode 100644 cmd/cetus/main_other.go (limited to 'cmd') diff --git a/cmd/cetus/app.go b/cmd/cetus/app.go new file mode 100644 index 0000000..c82fb29 --- /dev/null +++ b/cmd/cetus/app.go @@ -0,0 +1,99 @@ +package main + +import ( + "flag" + "fmt" + "math/rand" + "os" + "time" +) + +var ( + version string = "v0.6.3" + dump bool + random bool + notify bool + print bool + + err error + body string + file string + reqInfo map[string]string + + apodDate string +) + +func app() { + // Early Check: If command was not passed then print usage and + // exit. Later command & service both are checked, this check + // is for version command. If not checked then running cetus + // without any args will fail because os.Args[1] will panic + // the program & produce runtime error. + if len(os.Args) == 1 { + printUsage() + os.Exit(0) + } + + parseArgs() +} + +// parseArgs will be parsing the arguments, it will verify if they are +// correct. Flag values are also set by parseArgs. +func parseArgs() { + // Running just `cetus` would've paniced the program if length + // of os.Args was not checked beforehand because there would + // be no os.Args[1]. + switch os.Args[1] { + case "version", "-version", "--version", "-v": + fmt.Printf("Cetus %s\n", version) + os.Exit(0) + + case "help", "-help", "--help", "-h": + // If help was passed then the program shouldn't exit + // with non-zero error code. + printUsage() + os.Exit(0) + + case "set", "fetch": + // If command & service was not passed then print + // usage and exit. + if len(os.Args) < 3 { + printUsage() + os.Exit(1) + } + + default: + fmt.Printf("Invalid command: %q\n", os.Args[1]) + printUsage() + os.Exit(1) + } + + rand.Seed(time.Now().Unix()) + + // If the program has reached this far then that means a valid + // command was passed & now we should check if a valid service + // was passed and parse the flags. + cetus := flag.NewFlagSet("cetus", flag.ExitOnError) + + // We first declare common flags then service specific flags. + cetus.BoolVar(&dump, "dump", false, "Dump the response") + cetus.BoolVar(¬ify, "notify", false, "Send a desktop notification with info") + cetus.BoolVar(&print, "print", false, "Print information") + cetus.BoolVar(&random, "random", false, "Choose a random image") + + switch os.Args[2] { + case "apod", "nasa": + defDate := time.Now().UTC().Format("2006-01-02") + cetus.StringVar(&apodDate, "date", defDate, "Date of NASA APOD to retrieve") + cetus.Parse(os.Args[3:]) + + execAPOD() + case "bpod", "bing": + cetus.Parse(os.Args[3:]) + execBPOD() + default: + fmt.Printf("Invalid service: %q\n", os.Args[2]) + printUsage() + os.Exit(1) + } +} diff --git a/cmd/cetus/main.go b/cmd/cetus/main.go deleted file mode 100644 index 8efc17c..0000000 --- a/cmd/cetus/main.go +++ /dev/null @@ -1,100 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "math/rand" - "os" - "time" -) - -var ( - version string = "v0.6.3" - dump bool - random bool - notify bool - print bool - - err error - body string - file string - reqInfo map[string]string - - apodDate string -) - -func main() { - - // Early Check: If command was not passed then print usage and - // exit. Later command & service both are checked, this check - // is for version command. If not checked then running cetus - // without any args will fail because os.Args[1] will panic - // the program & produce runtime error. - if len(os.Args) == 1 { - printUsage() - os.Exit(0) - } - - parseArgs() -} - -// parseArgs will be parsing the arguments, it will verify if they are -// correct. Flag values are also set by parseArgs. -func parseArgs() { - // Running just `cetus` would've paniced the program if length - // of os.Args was not checked beforehand because there would - // be no os.Args[1]. - switch os.Args[1] { - case "version", "-version", "--version", "-v": - fmt.Printf("Cetus %s\n", version) - os.Exit(0) - - case "help", "-help", "--help", "-h": - // If help was passed then the program shouldn't exit - // with non-zero error code. - printUsage() - os.Exit(0) - - case "set", "fetch": - // If command & service was not passed then print - // usage and exit. - if len(os.Args) < 3 { - printUsage() - os.Exit(1) - } - - default: - fmt.Printf("Invalid command: %q\n", os.Args[1]) - printUsage() - os.Exit(1) - } - - rand.Seed(time.Now().Unix()) - - // If the program has reached this far then that means a valid - // command was passed & now we should check if a valid service - // was passed and parse the flags. - cetus := flag.NewFlagSet("cetus", flag.ExitOnError) - - // We first declare common flags then service specific flags. - cetus.BoolVar(&dump, "dump", false, "Dump the response") - cetus.BoolVar(¬ify, "notify", false, "Send a desktop notification with info") - cetus.BoolVar(&print, "print", false, "Print information") - cetus.BoolVar(&random, "random", false, "Choose a random image") - - switch os.Args[2] { - case "apod", "nasa": - defDate := time.Now().UTC().Format("2006-01-02") - cetus.StringVar(&apodDate, "date", defDate, "Date of NASA APOD to retrieve") - cetus.Parse(os.Args[3:]) - - execAPOD() - case "bpod", "bing": - cetus.Parse(os.Args[3:]) - execBPOD() - default: - fmt.Printf("Invalid service: %q\n", os.Args[2]) - printUsage() - os.Exit(1) - } -} diff --git a/cmd/cetus/main_openbsd.go b/cmd/cetus/main_openbsd.go new file mode 100644 index 0000000..562d239 --- /dev/null +++ b/cmd/cetus/main_openbsd.go @@ -0,0 +1,75 @@ +// +build openbsd + +package main + +import ( + "fmt" + "log" + "strings" + + "golang.org/x/sys/unix" + "tildegit.org/andinus/cetus/cache" +) + +func main() { + unveil() + app() +} + +func unveil() { + unveilL := make(map[string]string) + + unveilL[cache.GetDir()] = "rw" + unveilL["/dev/null"] = "rw" // required by feh + + unveilL["/etc/resolv.conf"] = "r" + + // ktrace output + unveilL["/usr/libexec/ld.so"] = "r" + unveilL["/var/run/ld.so.hints"] = "r" + unveilL["/usr/lib/libpthread.so.26.1"] = "r" + unveilL["/usr/lib/libc.so.95.1"] = "r" + unveilL["/dev/urandom"] = "r" + unveilL["/etc/mdns.allow"] = "r" + unveilL["/etc/hosts"] = "r" + unveilL["/usr/local/etc/ssl/cert.pem"] = "r" + unveilL["/etc/ssl/cert.pem"] = "r" + unveilL["/etc/ssl/certs"] = "r" + unveilL["/system/etc/security/cacerts"] = "r" + unveilL["/usr/local/share/certs"] = "r" + unveilL["/etc/pki/tls/certs"] = "r" + unveilL["/etc/openssl/certs"] = "r" + unveilL["/var/ssl/certs"] = "r" + + for k, v := range unveilL { + err = unix.Unveil(k, v) + if err != nil && err.Error() != "no such file or directory" { + log.Fatal(fmt.Sprintf("%s :: %s\n%s", k, v, + err.Error())) + } + } + + err = unveilCmd("feh") + if err != nil { + log.Fatal(err) + } + + // Block further unveil calls + err = unix.UnveilBlock() + if err != nil { + log.Fatal(err) + } +} + +// unveilCmd will unveil commands. +func unveilCmd(cmd string) error { + pathList := strings.Split(getEnv("PATH", ""), ":") + for _, path := range pathList { + err = unix.Unveil(fmt.Sprintf("%s/%s", path, cmd), "rx") + + if err != nil && err.Error() != "no such file or directory" { + return err + } + } + return nil +} diff --git a/cmd/cetus/main_other.go b/cmd/cetus/main_other.go new file mode 100644 index 0000000..d39e66f --- /dev/null +++ b/cmd/cetus/main_other.go @@ -0,0 +1,7 @@ +// +build !openbsd + +package main + +func main() { + app() +} -- cgit 1.4.1-2-gfad0