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 }
// 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 }