impl cidr as password:CIDR:http://target
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -62,6 +63,9 @@ func (s *Server) Route(src string, dst config.Proxy) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.db.Set(nsRouting, src+"//from", packable.NewString(dst.From)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.db.Set(nsRouting, src+"//auth", packable.NewString(dst.Auth)); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -167,12 +171,44 @@ func (s *Server) Pre(foo http.HandlerFunc) http.HandlerFunc {
|
||||
log.Printf("failed to auth: expected %q but got %q", auth, p)
|
||||
w.Header().Set("WWW-Authenticate", "Basic")
|
||||
http.Error(w, "unexpected basic auth", http.StatusUnauthorized)
|
||||
} else if from, err := s.lookupFrom(mapKey(r.Host)); err != nil {
|
||||
log.Printf("failed to lookup from for %s (%s): %v", r.Host, mapKey(r.Host), err)
|
||||
http.Error(w, err.Error(), http.StatusBadGateway)
|
||||
} else if err := assertFrom(from, r.RemoteAddr); err != nil {
|
||||
log.Printf("failed to from: expected %q but got %q: %v", from, r.RemoteAddr, err)
|
||||
http.Error(w, "unexpected from", http.StatusUnauthorized)
|
||||
} else {
|
||||
foo(w, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func assertFrom(from, remoteAddr string) error {
|
||||
if from == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
pattern := regexp.MustCompile(`[0-9](:[0-9]+)$`).FindStringSubmatchIndex(remoteAddr)
|
||||
if len(pattern) == 4 {
|
||||
remoteAddr = remoteAddr[:pattern[2]]
|
||||
}
|
||||
|
||||
remoteIP := net.ParseIP(remoteAddr)
|
||||
if remoteIP == nil {
|
||||
return fmt.Errorf("cannot parse remote %q", remoteAddr)
|
||||
}
|
||||
|
||||
_, net, err := net.ParseCIDR(from)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if net.Contains(remoteIP) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("expected like %q but got like %q", from, remoteAddr)
|
||||
}
|
||||
|
||||
func withMeta(w http.ResponseWriter, r *http.Request) (*http.Request, func()) {
|
||||
meta := map[string]string{
|
||||
"ts": strconv.FormatInt(time.Now().Unix(), 10),
|
||||
@@ -212,14 +248,19 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
func (s *Server) List(w http.ResponseWriter) {
|
||||
keys := s.db.Keys(nsRouting)
|
||||
hostURL := map[string]string{}
|
||||
hostFrom := map[string]string{}
|
||||
for _, key := range keys {
|
||||
u, _ := s.lookup(key)
|
||||
if u != nil && strings.TrimSuffix(key, "//auth") == key {
|
||||
hostURL[key] = u.String()
|
||||
}
|
||||
if u != nil && strings.TrimSuffix(key, "//from") == key {
|
||||
hostFrom[key] = u.String()
|
||||
}
|
||||
}
|
||||
json.NewEncoder(w).Encode(map[string]any{
|
||||
"hostsToURLs": hostURL,
|
||||
"hostsToFrom": hostFrom,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user