summaryrefslogtreecommitdiff
path: root/vendor/github.com
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com')
-rw-r--r--vendor/github.com/sarnowski/mitigation/LICENSE13
-rw-r--r--vendor/github.com/sarnowski/mitigation/README50
-rw-r--r--vendor/github.com/sarnowski/mitigation/mitigation.go118
-rw-r--r--vendor/github.com/sarnowski/mitigation/mitigation_test.go173
4 files changed, 354 insertions, 0 deletions
diff --git a/vendor/github.com/sarnowski/mitigation/LICENSE b/vendor/github.com/sarnowski/mitigation/LICENSE
new file mode 100644
index 0000000..1c949b5
--- /dev/null
+++ b/vendor/github.com/sarnowski/mitigation/LICENSE
@@ -0,0 +1,13 @@
+Copyright (c) 2012 Tobias Sarnowski <tobias@trustedco.de>
+
+Permission to use, copy, modify, and 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/vendor/github.com/sarnowski/mitigation/README b/vendor/github.com/sarnowski/mitigation/README
new file mode 100644
index 0000000..e7779eb
--- /dev/null
+++ b/vendor/github.com/sarnowski/mitigation/README
@@ -0,0 +1,50 @@
+mitigation for go applications
+=============================================================================
+
+Package mitigation provides the possibility to prevent damage caused by bugs
+or exploits.
+
+
+Techniques
+-----------------------------------------------------------------------------
+
+The package uses multiple techniques to mitigate damage:
+
+ - privilege revocation: switch to an unprivileged user
+ - chroot jail: restrict filesystem access
+ - defined environment: reset all environment variables
+
+Enables the ability to implement system-supported privilege seperation.
+
+
+Installation
+-----------------------------------------------------------------------------
+
+To install and use the mitigation execute the following command:
+
+ go get github.com/sarnowski/mitigation
+
+
+Documentation
+-----------------------------------------------------------------------------
+
+Documentation is provided in the go way and is accessible through "godoc".
+You will find explanation, requirements and examples.
+
+
+License
+-----------------------------------------------------------------------------
+
+Copyright (c) 2012 Tobias Sarnowski <tobias@trustedco.de>
+
+Permission to use, copy, modify, and 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/vendor/github.com/sarnowski/mitigation/mitigation.go b/vendor/github.com/sarnowski/mitigation/mitigation.go
new file mode 100644
index 0000000..a1110e4
--- /dev/null
+++ b/vendor/github.com/sarnowski/mitigation/mitigation.go
@@ -0,0 +1,118 @@
+/*
+Package mitigation provides the possibility to prevent damage through bugs or exploits.
+
+The package uses multiple techniques to mitigate damage:
+ - privilege revocation: switch to an unprivileged user
+ - chroot jail: restrict filesystem access
+ - defined environment: reset all environment variables
+
+The following prerequisites are nessecary:
+ - The application must run as root
+ - You need to provide a valid user id
+ - You need to provide a valid group id
+ - You need to provide an existing path
+
+Activate() will not return any error. It will panic as soon as anything
+goes wrong because there is no good way to recover. To provide a sensible
+fallback you can use the CanActivate() function.
+
+WARNING: Windows is not supported. Windows has no equivalents for the used
+techniques.
+
+WARNING: Linux is not POSIX compatible and therefor setuid() only changes the
+user ID of the current thread. At the time, there is no way to safely use
+this within go as there may already be other threads spawned at the time
+this library is called. More about this issue here:
+ http://code.google.com/p/go/issues/detail?id=1435
+ http://groups.google.com/group/golang-nuts/browse_thread/thread/059597aafdd84a0e
+
+The following table summarizes the behaviours:
+ openbsd: safe
+ freebsd: safe
+ darwin: safe
+ linux: unsafe
+ windows: not supported
+
+*/
+package mitigation
+
+import (
+ "os"
+ "runtime"
+ "syscall"
+)
+
+// Checks if it is possible to activate the mitigation.
+func CanActivate() bool {
+ if runtime.GOOS == "windows" || runtime.GOARCH == "arm" {
+ return false
+ }
+
+ uid := syscall.Getuid()
+ return uid == 0
+}
+
+// Activates the mitigation measurements.
+func Activate(uid int, gid int, path string) {
+ if !CanActivate() {
+ panic("Cannot activate mitigation measurements!")
+ }
+
+ // chroot directory
+ err := syscall.Chroot(path)
+ if err != nil {
+ panic(err)
+ }
+
+ // change directory to new /
+ err = syscall.Chdir("/")
+ if err != nil {
+ panic(err)
+ }
+
+ // drop all other groups
+ err = syscall.Setgroups([]int{gid})
+ if err != nil {
+ panic(err)
+ }
+
+ // verify the empty group list
+ gids, err := syscall.Getgroups()
+ if err != nil {
+ panic("Could not read groups!")
+ }
+ if len(gids) > 1 {
+ panic("Could not drop groups!")
+ } else if len(gids) == 1 {
+ if gids[0] != gid {
+ panic("Could not drop foreign groups!")
+ }
+ }
+
+ // change group
+ err = syscall.Setgid(gid)
+ if err != nil {
+ panic(err)
+ }
+
+ // verify the group change
+ ngid := syscall.Getgid()
+ if ngid != gid {
+ panic("Could not change group id!")
+ }
+
+ // change user
+ err = syscall.Setuid(uid)
+ if err != nil {
+ panic(err)
+ }
+
+ // verify the user change
+ nuid := syscall.Getuid()
+ if nuid != uid {
+ panic("Could not change user id!")
+ }
+
+ // now drop all environment variables
+ os.Clearenv()
+}
diff --git a/vendor/github.com/sarnowski/mitigation/mitigation_test.go b/vendor/github.com/sarnowski/mitigation/mitigation_test.go
new file mode 100644
index 0000000..0fafeab
--- /dev/null
+++ b/vendor/github.com/sarnowski/mitigation/mitigation_test.go
@@ -0,0 +1,173 @@
+package mitigation
+
+import (
+ "io/ioutil"
+ "log"
+ "net"
+ "net/http"
+ "os"
+ "os/user"
+ "runtime"
+ "strconv"
+ "syscall"
+ "testing"
+)
+
+const (
+ TEST_UID = 1000
+ TEST_GID = 1000
+
+ TEST_ROUTINES_COUNT = 100
+)
+
+// The test will only work when running as root.
+func TestCanActivate(t *testing.T) {
+ if !CanActivate() {
+ t.Fatal("Tests must run as root!")
+ }
+}
+
+// The test will only work when running as root.
+func TestActivate(t *testing.T) {
+ // create temporary directory to test chrooting
+ tmp, err := ioutil.TempDir("", "mitigationtest")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.Remove(tmp)
+ err = syscall.Chmod(tmp, 0755)
+ if err != nil {
+ t.Fatal("Could not change temporary directory permissions!")
+ }
+
+ // improve cpu usage to test for broken os implementations of setuid()
+ runtime.GOMAXPROCS(2)
+
+ // create some go routines as root to later test them
+ var sync chan bool = make(chan bool)
+ for i := 0; i < TEST_ROUTINES_COUNT; i++ {
+ go func() {
+ // no op
+ sync <- true
+ }()
+ }
+ for i := 0; i < TEST_ROUTINES_COUNT; i++ {
+ <-sync
+ }
+
+ // modify environment
+ err = os.Setenv("malicous_env", "bad string")
+ if err != nil {
+ t.Fatal("Cannot setup environment variables!")
+ }
+ if len(os.Environ()) == 0 {
+ t.Fatal("Environ() or Setenv() are broken!")
+ }
+
+ // do it!
+ Activate(TEST_UID, TEST_GID, tmp)
+
+ // verify uids
+ uid := syscall.Getuid()
+ if uid != TEST_UID {
+ t.Error("Failed to change UID")
+ }
+ euid := syscall.Geteuid()
+ if euid != TEST_UID {
+ t.Error("Failed to change EUID")
+ }
+
+ // verify gid
+ gid := syscall.Getgid()
+ if gid != TEST_GID {
+ t.Error("Failed to change GID")
+ }
+
+ // verify groups
+ gids, err := syscall.Getgroups()
+ if err != nil {
+ t.Fatal("Could not get group list")
+ }
+ if len(gids) > 1 {
+ t.Error("Not all groups are dropped!")
+ } else if len(gids) == 1 {
+ if gids[0] != TEST_GID {
+ t.Error("Not all foreign groups are dropped!")
+ }
+ }
+
+ // verify directory
+ dh, err := os.Open("/")
+ if err != nil {
+ t.Fatal("Cannot open my root directory", err)
+ }
+ files, err := dh.Readdir(-1)
+ if err != nil {
+ t.Fatal("Cannot read my root directory")
+ }
+ if len(files) > 0 {
+ t.Error("Root not changed to empty temporary directory!")
+ }
+
+ // verify environment
+ if len(os.Environ()) > 0 {
+ t.Error("Environment variables found!")
+ }
+
+ // test setuid() behaviour
+ var results chan int = make(chan int)
+
+ // start multiple goroutines, in a good OS, all all routines
+ // should be switched to the new user
+ for i := 0; i < TEST_ROUTINES_COUNT; i++ {
+ go func() {
+ results <- syscall.Getuid()
+ }()
+ }
+
+ // check the results
+ for i := 0; i < TEST_ROUTINES_COUNT; i++ {
+ uid := <-results
+ if uid != TEST_UID {
+ t.Error("false uid: ", uid, " (you are using an unsafe os, read the package documentation!)")
+ break
+ }
+ }
+}
+
+func ExampleActivate() {
+ // prepare application execution and allocate ressources with
+ // root privileges (e.g. open port 80 for an http server)
+ listener, _ := net.Listen("tcp", ":80")
+
+
+ // on OpenBSD, the "www" user is dedicated to serve the
+ // /var/www/htdocs directory in a chrooted way
+ wwwUser, _ := user.Lookup("www")
+ uid, _ := strconv.Atoi(wwwUser.Uid)
+ gid, _ := strconv.Atoi(wwwUser.Gid)
+
+ // now drop all privileges and chroot!
+ Activate(uid, gid, "/var/www/htdocs")
+
+
+ // The application is now chrooted and only runs with "www"
+ // privileges.
+ http.Serve(listener, http.FileServer(http.Dir("/")))
+}
+
+func ExampleCanActivate() {
+ workDir := "/var/www"
+
+ if CanActivate() {
+ // activate the mitigation and reset work directory to "/"
+ Activate(67, 67, workDir)
+ workDir = "/"
+ } else {
+ // we can handle this but log a warning
+ log.Println("WARNING: Cannot activate mitigation!")
+ }
+
+ // use "workDir" to address our files
+ log.Println("Working directory: ", workDir)
+}