From a78cc9fc54736368dbb0999cc061cd2f27e8f921 Mon Sep 17 00:00:00 2001 From: Esa-Matti Suuronen Date: Sun, 20 Oct 2013 23:46:07 +0300 Subject: [PATCH] Implement drop privileges --- config_test.yml | 1 + drop_privileges.go | 43 +++++++++++++++++++++++++++++++++++++++++++ hooktftp.go | 18 ++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 drop_privileges.go diff --git a/config_test.yml b/config_test.yml index cfb5211..f2f6194 100644 --- a/config_test.yml +++ b/config_test.yml @@ -1,4 +1,5 @@ port: 1234 +# user: hooktftp hooks: - name: Shell hook diff --git a/drop_privileges.go b/drop_privileges.go new file mode 100644 index 0000000..ffe94a5 --- /dev/null +++ b/drop_privileges.go @@ -0,0 +1,43 @@ +package main + +import ( + "os/user" + "strconv" + "syscall" +) + +func DropPrivileges(username string) error { + userInfo, err := user.Lookup(username) + if err != nil { + return err + } + + uid, err := strconv.Atoi(userInfo.Uid) + if err != nil { + return err + } + + gid, err := strconv.Atoi(userInfo.Gid) + if err != nil { + return err + } + + // TODO: should set secondary groups too + err = syscall.Setgroups([]int{gid}) + if err != nil { + return err + } + + err = syscall.Setgid(gid) + if err != nil { + return err + } + + err = syscall.Setuid(uid) + if err != nil { + return err + } + + return nil +} + diff --git a/hooktftp.go b/hooktftp.go index 0743ced..b70809e 100644 --- a/hooktftp.go +++ b/hooktftp.go @@ -10,6 +10,8 @@ import ( "io/ioutil" "net" "os" + "os/user" + "syscall" "time" ) @@ -154,6 +156,22 @@ func main() { fmt.Println("Listening on", conf.Port) + if conf.User != "" { + err := DropPrivileges(conf.User) + if err != nil { + fmt.Printf("Failed to drop privileges to '%s' error: %v", conf.User, err) + return + } + currentUser, _ := user.Current() + fmt.Println("Dropped privileges to", currentUser) + } + + if conf.User == "" && syscall.Getuid() == 0 { + fmt.Println("!!!!!!!!!") + fmt.Println("WARNING: Running as root and 'user' is not set in", CONFIG_PATH) + fmt.Println("!!!!!!!!!") + } + for { res, err := server.Accept() if err != nil {