From 132b6d2e126cfdaee05223f19c96ede7d207853e Mon Sep 17 00:00:00 2001 From: nervuri Date: Thu, 26 May 2022 00:00:00 +0000 Subject: [PATCH] add drop root capability and -u option Drop root code by Jon Jenkins: https://stackoverflow.com/a/48991783 --- server.go | 72 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 14 deletions(-) diff --git a/server.go b/server.go index 60dfa9a..fd69547 100644 --- a/server.go +++ b/server.go @@ -14,11 +14,19 @@ import ( "net" "net/url" "log" - "os" + "os/user" + "strconv" "strings" + "syscall" "time" ) +import( + //#include + //#include + "C" +) + type tlsConnectionInfo struct { TlsVersion uint16 `json:"tls_version"` CipherSuite uint16 `json:"cipher_suite"` @@ -257,25 +265,19 @@ func tlsHandler(conn *tls.Conn, rawClientHello []byte) { func main() { var certFile, keyFile string + var userToSwitchTo string var hostAndPort string // Parse arguments - if len(os.Args) != 6 { + flag.StringVar(&certFile, "c", "", "path to certificate file") + flag.StringVar(&keyFile, "k", "", "path to private key file") + flag.StringVar(&userToSwitchTo, "u", "www-data", "user to switch to, if running as root") + flag.Parse() + hostAndPort = flag.Arg(0) + if certFile == "" || keyFile == "" || hostAndPort == "" { fmt.Println("usage: client-hello-mirror -c cert.pem -k key.pem host:port") return } - flag.StringVar(&certFile, "c", "", "path to certificate file") - flag.StringVar(&keyFile, "k", "", "path to private key file") - flag.Parse() - hostAndPort = flag.Arg(0) - - // Listen for connections - ln, err := net.Listen("tcp", hostAndPort) - if err != nil { - log.Println(err) - return - } - defer ln.Close() // Load cert cert, err := tls.LoadX509KeyPair(certFile, keyFile) @@ -289,6 +291,48 @@ func main() { //MaxVersion: tls.VersionTLS12, } + // Listen for connections + ln, err := net.Listen("tcp", hostAndPort) + if err != nil { + log.Println(err) + return + } + defer ln.Close() + + // Drop root + if syscall.Getuid() == 0 { + if userToSwitchTo == "" { + fmt.Println("Running as root. Please specify an unprivileged user to switch to, using the -u flag") + return + } + userInfo, err := user.Lookup(userToSwitchTo) + if err != nil { + fmt.Println(err) + if userToSwitchTo == "www-data" { + fmt.Println("Running as root. Please specify an unprivileged user to switch to, using the -u flag") + } + return + } + uid, err := strconv.ParseInt(userInfo.Uid, 10, 32) + if err != nil { + fmt.Println(err) + return + } + gid, err := strconv.ParseInt(userInfo.Gid, 10, 32) + if err != nil { + fmt.Println(err) + return + } + cerr, errno := C.setgid(C.__gid_t(gid)) + if cerr != 0 { + log.Fatalln("Unable to set GID due to error:", errno) + } + cerr, errno = C.setuid(C.__uid_t(uid)) + if cerr != 0 { + log.Fatalln("Unable to set UID due to error:", errno) + } + } + log.Println("Server started") for {