package binder import ( "fmt" "net" "os" "os/user" "strconv" "syscall" g "euandre.org/gobang/src" ) type CLIArgs struct { FromAddr string ToAddr string } const USER = "nobody" var EmitActiveConnection = g.MakeGauge("active-connections") func dropPrivileges(username string) { g.Info("Dropping privileges", "drop-root-init") user, err := user.Lookup(username) g.FatalIf(err) gid, err := strconv.Atoi(user.Gid) g.FatalIf(err) uid, err := strconv.Atoi(user.Uid) g.FatalIf(err) err = syscall.Setgid(gid) g.FatalIf(err) err = syscall.Setgroups([]int{}) g.FatalIf(err) err = syscall.Setuid(uid) g.FatalIf(err) g.Info("Privileges dropped", "drop-root-end") } func isRunningAsRoot() bool { return os.Geteuid() == 0 } func ParseArgs(args []string) CLIArgs { if len(args) != 3 { fmt.Fprintf( os.Stderr, "Usage: %s FROM-ADDRESS TO-ADDRESS\n", args[0], ) os.Exit(2) } return CLIArgs { FromAddr: args[1], ToAddr: args[2], } } func Listen(fromAddr string) net.Listener { listener, err := net.Listen("tcp", fromAddr) g.FatalIf(err) g.Info("Started listening", "listen-start", "from-address", fromAddr) return listener } func DropRoot() { if isRunningAsRoot() { dropPrivileges(USER) if isRunningAsRoot() { panic("Failed to drop privileges") } } } func Start(toAddr string, listener net.Listener) { for { connFrom, err := listener.Accept() if err != nil { g.Warning( "Error accepting connection", "accept-connection-error", "err", err, ) continue } defer connFrom.Close() EmitActiveConnection.Inc() connTo, err := net.Dial("unix", toAddr) if err != nil { g.Warning( "Error dialing connection", "dial-connection-error", "err", err, ) connFrom.Close() continue } defer connTo.Close() c := make(chan g.CopyResult) go g.CopyData(c, "c2s", connFrom, connTo) go g.CopyData(c, "s2c", connTo, connFrom) go func() { <- c EmitActiveConnection.Dec() }() } } func Main() { g.Init() args := ParseArgs(os.Args) listener := Listen(args.FromAddr) DropRoot() Start(args.ToAddr, listener) }