Exemplo n.º 1
0
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
}
Exemplo n.º 2
0
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
}
Exemplo n.º 3
0
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)
}
Exemplo n.º 4
0
// 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
}
Exemplo n.º 5
0
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)
}