func localhostAuthorized(req *http.Request) bool { if uid := os.Getuid(); uid > 0 { from := req.RemoteAddr to := req.Host if strings.HasPrefix(to, "localhost:") { toPort := to[len("localhost:"):] if strings.Contains(from, "[") { to = "[::1]:" + toPort } else { to = "127.0.0.1:" + toPort } } // TODO(bradfitz): netutil on OS X uses "lsof" to figure out // ownership of tcp connections, but when fuse is mounted and a // request is outstanding (for instance, a fuse request that's // making a request to camlistored and landing in this code // path), lsof then blocks forever waiting on a lock held by the // VFS, leading to a deadlock. Instead, on darwin, just trust // any localhost connection here, which is kinda lame, but // whatever. Macs aren't very multi-user anyway. if runtime.GOOS == "darwin" && isLocalhost(from) && isLocalhost(to) { return true } owner, err := netutil.AddrPairUserid(from, to) if err == nil && owner == uid { return true } } return false }
func localhostAuthorized(req *http.Request) bool { uid := os.Getuid() from, err := netutil.HostPortToIP(req.RemoteAddr) if err != nil { return false } to, err := netutil.HostPortToIP(req.Host) if err != nil { return false } // If our OS doesn't support uid. // TODO(bradfitz): netutil on OS X uses "lsof" to figure out // ownership of tcp connections, but when fuse is mounted and a // request is outstanding (for instance, a fuse request that's // making a request to camlistored and landing in this code // path), lsof then blocks forever waiting on a lock held by the // VFS, leading to a deadlock. Instead, on darwin, just trust // any localhost connection here, which is kinda lame, but // whatever. Macs aren't very multi-user anyway. if uid == -1 || runtime.GOOS == "darwin" { return from.IP.IsLoopback() && to.IP.IsLoopback() } if uid > 0 { owner, err := netutil.AddrPairUserid(from, to) if err == nil && owner == uid { return true } } return false }
func setupHome(rw http.ResponseWriter, req *http.Request) { _, port, _ := net.SplitHostPort(*webserver.Listen) ourAddr := "127.0.0.1:" + port uid, err := netutil.AddrPairUserid(req.RemoteAddr, ourAddr) fmt.Fprintf(rw, "Hello %q\n", req.RemoteAddr) fmt.Fprintf(rw, "<p>uid = %d\n", syscall.Getuid()) fmt.Fprintf(rw, "<p>euid = %d\n", syscall.Geteuid()) fmt.Fprintf(rw, "<p>http_local_uid(%q => %q) = %d (%v)\n", req.RemoteAddr, ourAddr, uid, err) }
// IsLocalhost reports whether the requesting connection is from this machine // and has the same owner as this process. func IsLocalhost(req *http.Request) bool { uid := os.Getuid() from, err := netutil.HostPortToIP(req.RemoteAddr, nil) if err != nil { return false } to, err := netutil.HostPortToIP(req.Host, from) if err != nil { return false } // If our OS doesn't support uid. // TODO(bradfitz): netutil on OS X uses "lsof" to figure out // ownership of tcp connections, but when fuse is mounted and a // request is outstanding (for instance, a fuse request that's // making a request to camlistored and landing in this code // path), lsof then blocks forever waiting on a lock held by the // VFS, leading to a deadlock. Instead, on darwin, just trust // any localhost connection here, which is kinda lame, but // whatever. Macs aren't very multi-user anyway. if uid == -1 || runtime.GOOS == "darwin" { return from.IP.IsLoopback() && to.IP.IsLoopback() } if uid == 0 { log.Printf("camlistored running as root. Don't do that.") return false } if uid > 0 { connUid, err := netutil.AddrPairUserid(from, to) if err == nil { if uid == connUid || connUid == 0 { // If it's the same user who's running the server, allow it. // Also allow root, so users can "sudo camput" files. // Allowing root isn't a security problem because if root wants // to mess with the local user, they already can. This whole mechanism // is about protecting regular users from other regular users // on shared computers. return true } log.Printf("auth: local connection uid %d doesn't match server uid %d", connUid, uid) } } return false }
func setupHome(rw http.ResponseWriter, req *http.Request) { port := httputil.RequestTargetPort(req) localhostAddr, err := netutil.Localhost() if err != nil { httputil.ServeError(rw, req, err) } ourAddr := &net.TCPAddr{IP: localhostAddr, Port: port} rAddr, err := net.ResolveTCPAddr("tcp", req.RemoteAddr) if err != nil { fmt.Printf("camlistored: unable to resolve RemoteAddr %q: %v", req.RemoteAddr, err) return } uid, err := netutil.AddrPairUserid(rAddr, ourAddr) if err != nil { httputil.ServeError(rw, req, err) } fmt.Fprintf(rw, "Hello %q\n", req.RemoteAddr) fmt.Fprintf(rw, "<p>uid = %d\n", syscall.Getuid()) fmt.Fprintf(rw, "<p>euid = %d\n", syscall.Geteuid()) fmt.Fprintf(rw, "<p>http_local_uid(%q => %q) = %d (%v)\n", req.RemoteAddr, ourAddr, uid, err) }