mirror of https://github.com/perkeep/perkeep.git
Merge "Modifications allowing /setup to be view on Windows"
This commit is contained in:
commit
306b58afd6
|
@ -19,6 +19,7 @@ package auth
|
|||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
|
@ -38,7 +39,7 @@ type AuthMode interface {
|
|||
// IsAuthorized checks the credentials in req.
|
||||
IsAuthorized(req *http.Request) bool
|
||||
// AddAuthHeader inserts in req the credentials needed
|
||||
// for a client to authenticate.
|
||||
// for a client to authenticate.
|
||||
AddAuthHeader(req *http.Request)
|
||||
}
|
||||
|
||||
|
@ -159,30 +160,30 @@ type DevAuth struct {
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
uid := os.Getuid()
|
||||
from, err := netutil.HostPortToIP(req.RemoteAddr)
|
||||
if err != nil {
|
||||
fmt.Printf("auth: could not resolve the TCPAddr: %v", err)
|
||||
}
|
||||
to, err := netutil.HostPortToIP(req.Host)
|
||||
if err != nil {
|
||||
fmt.Printf("auth: could not resolve the TCPAddr: %v", err)
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
// 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
|
||||
|
@ -191,8 +192,8 @@ func localhostAuthorized(req *http.Request) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func isLocalhost(addrPort string) bool {
|
||||
return strings.HasPrefix(addrPort, "127.0.0.1:") || strings.HasPrefix(addrPort, "[::1]:")
|
||||
func isLocalhost(addrPort net.IP) bool {
|
||||
return addrPort.IsLoopback()
|
||||
}
|
||||
|
||||
func LocalhostAuthorized(req *http.Request) bool {
|
||||
|
|
|
@ -89,7 +89,7 @@ func ReturnJSON(conn http.ResponseWriter, data interface{}) {
|
|||
return
|
||||
}
|
||||
|
||||
conn.Header().Set("Content-Length", strconv.Itoa(len(bytes) + 1))
|
||||
conn.Header().Set("Content-Length", strconv.Itoa(len(bytes)+1))
|
||||
conn.Write(bytes)
|
||||
conn.Write([]byte("\n"))
|
||||
}
|
||||
|
|
|
@ -37,50 +37,50 @@ var ErrNotFound = errors.New("netutil: connection not found")
|
|||
// ConnUserid returns the uid that owns the given localhost connection.
|
||||
// The returned error is ErrNotFound if the connection wasn't found.
|
||||
func ConnUserid(conn net.Conn) (uid int, err error) {
|
||||
return AddrPairUserid(conn.LocalAddr().String(), conn.RemoteAddr().String())
|
||||
return AddrPairUserid(conn.LocalAddr(), conn.RemoteAddr())
|
||||
}
|
||||
|
||||
func splitIPPort(param, value string) (ip net.IP, port int, reterr error) {
|
||||
addrs, ports, err := net.SplitHostPort(value)
|
||||
// This fonction allows parsing of a TCPAddr without resolving names
|
||||
// other than localhost. It will return an error instead of resolving.
|
||||
func HostPortToIP(hostport string) (hostaddr *net.TCPAddr, err error) {
|
||||
host, port, err := net.SplitHostPort(hostport)
|
||||
if err != nil {
|
||||
reterr = fmt.Errorf("netutil: AddrPairUserid invalid %s value of %q: %v", param, value, err)
|
||||
return
|
||||
return nil, err
|
||||
}
|
||||
ip = net.ParseIP(addrs)
|
||||
if ip == nil {
|
||||
reterr = fmt.Errorf("netutil: invalid %s IP %q", param, addrs)
|
||||
return
|
||||
iport, err := strconv.Atoi(port)
|
||||
if err != nil || iport < 0 || iport > 0xFFFF {
|
||||
return nil, fmt.Errorf("invalid port %s", iport)
|
||||
}
|
||||
port, err = strconv.Atoi(ports)
|
||||
if err != nil || port <= 0 || port > 65535 {
|
||||
reterr = fmt.Errorf("netutil: invalid port %q", ports)
|
||||
return
|
||||
var addr net.IP
|
||||
if host == "localhost" {
|
||||
addr = net.IPv4(127, 0, 0, 1)
|
||||
} else if addr = net.ParseIP(host); addr == nil {
|
||||
return nil, fmt.Errorf("could not parse IP %s", host)
|
||||
}
|
||||
return
|
||||
|
||||
return &net.TCPAddr{IP: addr, Port: iport}, nil
|
||||
}
|
||||
|
||||
// AddrPairUserid returns the local userid who owns the TCP connection
|
||||
// given by the local and remote ip:port (lipport and ripport,
|
||||
// respectively). Returns ErrNotFound for the error if the TCP connection
|
||||
// isn't found.
|
||||
func AddrPairUserid(lipport, ripport string) (uid int, err error) {
|
||||
lip, lport, err := splitIPPort("lipport", lipport)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
func AddrPairUserid(local, remote net.Addr) (uid int, err error) {
|
||||
lAddr, lOk := local.(*net.TCPAddr)
|
||||
rAddr, rOk := remote.(*net.TCPAddr)
|
||||
if !(lOk && rOk) {
|
||||
return -1, fmt.Errorf("netutil: Could not convert Addr to TCPAddr.")
|
||||
}
|
||||
rip, rport, err := splitIPPort("ripport", ripport)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
localv4 := (lip.To4() != nil)
|
||||
remotev4 := (rip.To4() != nil)
|
||||
|
||||
localv4 := (lAddr.IP.To4() != nil)
|
||||
remotev4 := (rAddr.IP.To4() != nil)
|
||||
if localv4 != remotev4 {
|
||||
return -1, fmt.Errorf("netutil: address pairs of different families; localv4=%v, remotev4=%v",
|
||||
localv4, remotev4)
|
||||
}
|
||||
|
||||
if runtime.GOOS == "darwin" {
|
||||
return uidFromDarwinLsof(lip, lport, rip, rport)
|
||||
return uidFromDarwinLsof(lAddr.IP, lAddr.Port, rAddr.IP, rAddr.Port)
|
||||
}
|
||||
|
||||
file := "/proc/net/tcp"
|
||||
|
@ -92,7 +92,7 @@ func AddrPairUserid(lipport, ripport string) (uid int, err error) {
|
|||
return -1, fmt.Errorf("Error opening %s: %v", file, err)
|
||||
}
|
||||
defer f.Close()
|
||||
return uidFromReader(lip, lport, rip, rport, f)
|
||||
return uidFromReader(lAddr.IP, lAddr.Port, rAddr.IP, rAddr.Port, f)
|
||||
}
|
||||
|
||||
func toLinuxIPv4Order(b []byte) []byte {
|
||||
|
@ -212,20 +212,14 @@ func uidFromReader(lip net.IP, lport int, rip net.IP, rport int, r io.Reader) (u
|
|||
}
|
||||
|
||||
// Localhost returns the first address found when
|
||||
// doing a lookup on "localhost". It is surrounded
|
||||
// by brackets if it contains a colon.
|
||||
func Localhost() (string, error) {
|
||||
var addr string
|
||||
addrs, err := net.LookupHost("localhost")
|
||||
// doing a lookup on "localhost".
|
||||
func Localhost() (net.IP, error) {
|
||||
ips, err := net.LookupIP("localhost")
|
||||
if err != nil {
|
||||
return addr, err
|
||||
return nil, err
|
||||
}
|
||||
if len(addrs) < 1 {
|
||||
return addr, errors.New("Host lookup for localhost returned no result")
|
||||
if len(ips) < 1 {
|
||||
return nil, errors.New("IP lookup for localhost returned no result")
|
||||
}
|
||||
addr = addrs[0]
|
||||
if strings.Contains(addr, ":") {
|
||||
addr = "[" + addr + "]"
|
||||
}
|
||||
return addr, nil
|
||||
return ips[0], nil
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"syscall"
|
||||
|
||||
|
@ -31,8 +32,13 @@ func setupHome(rw http.ResponseWriter, req *http.Request) {
|
|||
if err != nil {
|
||||
httputil.ServerError(rw, req, err)
|
||||
}
|
||||
ourAddr := fmt.Sprintf("%s:%d", localhostAddr, port)
|
||||
uid, err := netutil.AddrPairUserid(req.RemoteAddr, ourAddr)
|
||||
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.ServerError(rw, req, err)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue