Added username/password auth

This commit is contained in:
2023-10-26 18:35:18 +02:00
parent e890702f8a
commit 17086b1abf
2 changed files with 87 additions and 11 deletions

View File

@@ -3,6 +3,7 @@ package main
import (
"errors"
"flag"
"fmt"
"git.thequux.com/thequux/ipasso/sso-proxy/backend"
"git.thequux.com/thequux/ipasso/util"
"git.thequux.com/thequux/ipasso/util/genpool"
@@ -35,8 +36,10 @@ var (
)
var (
ErrNoValidServer = errors.New("no valid server")
ldapRootLogger, ldapPoolLogger *zap.Logger
ErrNoValidServer = errors.New("no valid server")
ErrLoginFailed = errors.New("login failed")
ldapRootLogger *zap.Logger
ldapPoolLogger *zap.Logger
)
func init() {
@@ -67,6 +70,9 @@ func init() {
ldapRootLogger.Debug("Configured LDAP rootDN", zap.String("rootDN", *ldapRootDN))
}
// configure username basedn
ldapUserBase = "cn=users,cn=accounts," + *ldapRootDN
krb5Config, err := config.Load(*krb5conf)
var realmSource string = ""
if err != nil {
@@ -260,7 +266,31 @@ func getUserByPrincipal(principal string) (*ldap.Entry, error) {
func getUserByDn(dn string) (*ldap.Entry, error) {
return ldapSearchSingle(&ldap.SearchRequest{
BaseDN: dn,
Filter: "(objectClass=top)",
Scope: ldap.ScopeBaseObject,
Attributes: interestingUserAttr,
})
}
func getUserByUsernamePassword(username, password string) (*ldap.Entry, error) {
server := selectServer()
if server == nil {
return nil, ErrNoValidServer
}
conn, err := ldap.DialURL(server.Url)
if err != nil {
return nil, err
}
defer conn.Close()
// try bind
userDN := fmt.Sprintf("uid=%s,%s", username, ldapUserBase)
//ldapRootLogger.Debug("Attempting bind login", zap.String("user", userDN), zap.String("password", password))
err = conn.Bind(userDN, password)
if err != nil {
return nil, ErrLoginFailed
}
//ldapRootLogger.Info("Successfully authorized using simple bind", zap.String("user", username), zap.String("dn", userDN))
return getUserByDn(userDN)
}

View File

@@ -1,20 +1,22 @@
package main
import (
"errors"
"git.thequux.com/thequux/ipasso/sso-proxy/backend"
"git.thequux.com/thequux/ipasso/util/startup"
"github.com/go-ldap/ldap/v3"
"github.com/julienschmidt/httprouter"
"log"
"net/http"
"net/http/fcgi"
"strconv"
"strings"
"time"
)
func init() {
startup.Routes.Add(func(router *httprouter.Router) {
router.HandlerFunc("POST", "/login/krb5", loginKrb)
router.HandlerFunc("POST", "/login/password", loginPassword)
})
}
@@ -23,7 +25,6 @@ func loginKrb(w http.ResponseWriter, r *http.Request) {
// The fact that we got here implies that the login succeeded
env := fcgi.ProcessEnv(r)
user := env["GSS_NAME"]
uid := strings.Split(user, "@")[0]
expirationTxt, hasExpiration := env["GSS_SESSION_EXPIRATION"]
var expiration time.Time
if hasExpiration {
@@ -41,21 +42,64 @@ func loginKrb(w http.ResponseWriter, r *http.Request) {
return
}
SessionID, err := datastore.NewSessionID()
if err != nil {
ReportError(w, err)
return
}
entry, err := getUserByPrincipal(user)
if err != nil {
ReportError(w, err)
return
}
finishLogin(w, r, entry, &expiration)
}
func loginPassword(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
ReportError(w, err)
}
user := r.Form.Get("user")
password := r.Form.Get("password")
if user == "" || password == "" {
ldapRootLogger.Debug("Missing value")
w.WriteHeader(http.StatusUnauthorized)
return
}
entry, err := getUserByUsernamePassword(user, password)
if errors.Is(err, ErrLoginFailed) {
w.WriteHeader(http.StatusUnauthorized)
return
} else if err != nil {
ReportError(w, err)
return
}
finishLogin(w, r, entry, nil)
}
func finishLogin(w http.ResponseWriter, req *http.Request, entry *ldap.Entry, expiration *time.Time) {
SessionID, err := datastore.NewSessionID()
if err != nil {
ReportError(w, err)
return
}
var uid string
for _, attr := range entry.Attributes {
if attr.Name == "uid" && len(attr.Values) > 0 {
uid = attr.Values[0]
}
}
// TODO: make configurable
if expiration == nil {
defExpiration := time.Now().Add(time.Hour * 14)
expiration = &defExpiration
}
session := backend.Session{
SessionID: SessionID,
Expiration: expiration,
Expiration: *expiration,
UserID: uid,
LdapDN: entry.DN,
}
@@ -65,4 +109,6 @@ func loginKrb(w http.ResponseWriter, r *http.Request) {
return
}
_ = datastore.PutSession(session, sessionCache)
// TODO: set cookies, return success
}