diff --git a/src/ldap.go b/src/ldap.go index 152f85f..9f27268 100644 --- a/src/ldap.go +++ b/src/ldap.go @@ -78,5 +78,47 @@ func setupLDAP() error { return err } } + + if config.Auth.BindDN != "" || config.Auth.BindPW != "" { + err = conn.Bind(config.Auth.BindDN, config.Auth.BindPW) + if err != nil { + return err + } + } return nil } + +func ldapLogin(username, password string) (bool, error) { + // TODO: lock + if config.Auth.BindDN != "" || config.Auth.BindPW != "" { + err := conn.Bind(config.Auth.BindDN, config.Auth.BindPW) + if err != nil { + return false, err + } + } + + req := ldap.NewSearchRequest( + config.User.BaseDN, + ldap.ScopeWholeSubtree, + ldap.NeverDerefAliases, + 0, + 0, + false, + strings.Replace(config.User.Filter, "{0}", username, -1), + []string{config.User.UserAttr}, + nil, + ) + + res, err := conn.Search(req) + + if err != nil { + return false, err + } + + if len(res.Entries) != 1 { + return false, nil + } + + err = conn.Bind(res.Entries[0].DN, password) + return err == nil, nil +} diff --git a/src/main.go b/src/main.go index d8028d2..534d50a 100644 --- a/src/main.go +++ b/src/main.go @@ -1,11 +1,13 @@ package main import ( + "encoding/base64" "flag" "fmt" "io/ioutil" "log" "net/http" + "strings" "time" yaml "gopkg.in/yaml.v2" @@ -52,6 +54,7 @@ func main() { http.HandleFunc(config.Path, handler) + fmt.Printf("Serving...\n") err = http.ListenAndServe(config.Web, nil) if err != nil { log.Fatalf("Error on start server: %v\n", err) @@ -59,5 +62,42 @@ func main() { } func handler(w http.ResponseWriter, r *http.Request) { - //w.WriteHeader(http.StatusOK) + header := r.Header.Get("Authorization") + + if header != "" { + auth := strings.SplitN(header, " ", 2) + + if len(auth) == 2 && auth[0] == "Basic" { + decoded, err := base64.StdEncoding.DecodeString(auth[1]) + if err == nil { + secret := strings.SplitN(string(decoded), ":", 2) + + if len(secret) == 2 && validate(secret[0], secret[1]) { + w.WriteHeader(http.StatusOK) + return + } + } else { + log.Printf("Error decode basic auth: %v\n", err) + } + } + } + + w.Header().Set("WWW-Authenticate", "Basic realm=\"LDAP Login\"") + w.WriteHeader(http.StatusUnauthorized) +} + +func validate(username, password string) bool { + ok, found := getCache(username, password) + if found { + return ok + } + + ok, err := ldapLogin(username, password) + if err != nil { + log.Printf("Could not validade user %s: %v\n", username, err) + return false + } + + putCache(username, password, ok) + return ok }