commit 09e64a527745d86a36aa45fb5ccc1f27ac25f04d Author: Andinus Date: Mon Apr 6 12:36:14 2020 +0530 Initial Commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8cb5164 --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2020, Andinus + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/README.org b/README.org new file mode 100644 index 0000000..7c347a8 --- /dev/null +++ b/README.org @@ -0,0 +1,65 @@ +#+HTML_HEAD: +#+HTML_HEAD: +#+EXPORT_FILE_NAME: index +#+OPTIONS: toc:nil +#+TOC: headlines 2 +#+TITLE: Lynx + +Lynx is a simple /unveil/ wrapper. + +| Project Home | [[https://andinus.nand.sh/lynx][Lynx]] | +| Source Code | [[https://tildegit.org/andinus/lynx][Andinus / Lynx]] | +| GitHub (Mirror) | [[https://github.com/andinus/lynx][Lynx - GitHub]] | + +* Examples +** UnveilCommands +UnveilCommands takes a slice of commands & unveils them one by one, it will +return an error if unveil fails at any step. "no such file or directory" error +is ignored because binaries are not placed in every PATH. + +Default permission is "rx". + +#+BEGIN_SRC go +package main + +import "tildegit.org/andinus/lynx" + +func main() { + commands := []string{"cd", "ls", "rm"} + + err = lynx.UnveilCommands(commands) + if err != nil { + log.Fatal(err) + } +} +#+END_SRC +** UnveilPaths / UnveilPathsStrict +UnveilPaths takes a map of path, permission & unveils them one by one, it will +return an error if unveil fails at any step. "no such file or directory" error +is ignored, if you want to get that error too then use UnveilPathsStrict. + +#+BEGIN_SRC go +package main + +import "tildegit.org/andinus/lynx" + +func main() { + paths := make(map[string]string) + + paths["/home"] = "r" + paths["/dev/null"] = "rw" + paths["/etc/examples"] = "rwc" + paths["/root"] = "rwcx" + + err = lynx.UnveilPaths(paths) + if err != nil { + log.Fatal(err) + } + + // This will return an error if the path doesn't exist. + err = lynx.UnveilPathsStrict(paths) + if err != nil { + log.Fatal(err) + } +} +#+END_SRC diff --git a/build/ci/drone.yml b/build/ci/drone.yml new file mode 100644 index 0000000..32e778e --- /dev/null +++ b/build/ci/drone.yml @@ -0,0 +1,14 @@ +--- +kind: pipeline +name: testing + +steps: +- name: vet + image: golang:1.13 + commands: + - go vet ./... + +- name: test + image: golang:1.13 + commands: + - go test -v ./... diff --git a/commands.go b/commands.go new file mode 100644 index 0000000..5d57546 --- /dev/null +++ b/commands.go @@ -0,0 +1,39 @@ +package lynx + +import ( + "fmt" + "os" + "strings" + + "golang.org/x/sys/unix" +) + +// UnveilCommands takes a slice of commands & unveils them one by one, +// it will return an error if unveil fails at any step. "no such file +// or directory" error is ignored. +func UnveilCommands(commands []string) error { + // Get $PATH & split it in a list. + pathList := strings.Split(os.Getenv("PATH"), ":") + + // We work on unveiling each command one by one. + for _, cmd := range commands { + // Unveil this command on every PATH. + for _, path := range pathList { + err := unix.Unveil(fmt.Sprintf("%s/%s", + path, cmd), "rx") + + // "no such file or directory" error is + // ignored because binaries are not placed in + // every PATH. + if err != nil && err.Error() != "no such file or directory" { + // Better error message could be + // returned like one that includes the + // path on which unveil failed. + return err + } + } + } + // Returning nil because err can be "no such file or + // directory" which needs to be ignored. + return nil +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..e00ede7 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module tildegit.org/andinus/lynx + +go 1.13 + +require golang.org/x/sys v0.0.0-20200331124033-c3d80250170d diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..ad99652 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d h1:nc5K6ox/4lTFbMVSL9WRR81ixkcwXThoiF6yf+R9scA= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/paths.go b/paths.go new file mode 100644 index 0000000..2a3986e --- /dev/null +++ b/paths.go @@ -0,0 +1,38 @@ +// Package lynx is a simple wrapper to unveil. +package lynx + +import "golang.org/x/sys/unix" + +// UnveilPaths takes a map of path, permission & unveils them one by +// one, it will return an error if unveil fails at any step. "no such +// file or directory" error is ignored. +func UnveilPaths(paths map[string]string) error { + for k, v := range paths { + err := unix.Unveil(k, v) + + // "no such file or directory" error is ignored. + if err != nil && err.Error() != "no such file or directory" { + // Better error message could be returned like + // one that includes the path on which unveil + // failed. + return err + } + } + // Returning nil because err can be "no such file or + // directory" which needs to be ignored. + return nil +} + +// UnveilPathsStrict takes a map of path, permission & unveils them +// one by one, it will return an error if unveil fails at any steop. +// No error is ignored. +func UnveilPathsStrict(paths map[string]string) (err error) { + for k, v := range paths { + err = unix.Unveil(k, v) + + if err != nil { + return + } + } + return +}