Added username/password auth
This commit is contained in:
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
|
"fmt"
|
||||||
"git.thequux.com/thequux/ipasso/sso-proxy/backend"
|
"git.thequux.com/thequux/ipasso/sso-proxy/backend"
|
||||||
"git.thequux.com/thequux/ipasso/util"
|
"git.thequux.com/thequux/ipasso/util"
|
||||||
"git.thequux.com/thequux/ipasso/util/genpool"
|
"git.thequux.com/thequux/ipasso/util/genpool"
|
||||||
@@ -35,8 +36,10 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrNoValidServer = errors.New("no valid server")
|
ErrNoValidServer = errors.New("no valid server")
|
||||||
ldapRootLogger, ldapPoolLogger *zap.Logger
|
ErrLoginFailed = errors.New("login failed")
|
||||||
|
ldapRootLogger *zap.Logger
|
||||||
|
ldapPoolLogger *zap.Logger
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -67,6 +70,9 @@ func init() {
|
|||||||
ldapRootLogger.Debug("Configured LDAP rootDN", zap.String("rootDN", *ldapRootDN))
|
ldapRootLogger.Debug("Configured LDAP rootDN", zap.String("rootDN", *ldapRootDN))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// configure username basedn
|
||||||
|
ldapUserBase = "cn=users,cn=accounts," + *ldapRootDN
|
||||||
|
|
||||||
krb5Config, err := config.Load(*krb5conf)
|
krb5Config, err := config.Load(*krb5conf)
|
||||||
var realmSource string = ""
|
var realmSource string = ""
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -260,7 +266,31 @@ func getUserByPrincipal(principal string) (*ldap.Entry, error) {
|
|||||||
func getUserByDn(dn string) (*ldap.Entry, error) {
|
func getUserByDn(dn string) (*ldap.Entry, error) {
|
||||||
return ldapSearchSingle(&ldap.SearchRequest{
|
return ldapSearchSingle(&ldap.SearchRequest{
|
||||||
BaseDN: dn,
|
BaseDN: dn,
|
||||||
|
Filter: "(objectClass=top)",
|
||||||
Scope: ldap.ScopeBaseObject,
|
Scope: ldap.ScopeBaseObject,
|
||||||
Attributes: interestingUserAttr,
|
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)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,20 +1,22 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"git.thequux.com/thequux/ipasso/sso-proxy/backend"
|
"git.thequux.com/thequux/ipasso/sso-proxy/backend"
|
||||||
"git.thequux.com/thequux/ipasso/util/startup"
|
"git.thequux.com/thequux/ipasso/util/startup"
|
||||||
|
"github.com/go-ldap/ldap/v3"
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/fcgi"
|
"net/http/fcgi"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
startup.Routes.Add(func(router *httprouter.Router) {
|
startup.Routes.Add(func(router *httprouter.Router) {
|
||||||
router.HandlerFunc("POST", "/login/krb5", loginKrb)
|
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
|
// The fact that we got here implies that the login succeeded
|
||||||
env := fcgi.ProcessEnv(r)
|
env := fcgi.ProcessEnv(r)
|
||||||
user := env["GSS_NAME"]
|
user := env["GSS_NAME"]
|
||||||
uid := strings.Split(user, "@")[0]
|
|
||||||
expirationTxt, hasExpiration := env["GSS_SESSION_EXPIRATION"]
|
expirationTxt, hasExpiration := env["GSS_SESSION_EXPIRATION"]
|
||||||
var expiration time.Time
|
var expiration time.Time
|
||||||
if hasExpiration {
|
if hasExpiration {
|
||||||
@@ -41,21 +42,64 @@ func loginKrb(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
SessionID, err := datastore.NewSessionID()
|
|
||||||
if err != nil {
|
|
||||||
ReportError(w, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
entry, err := getUserByPrincipal(user)
|
entry, err := getUserByPrincipal(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ReportError(w, err)
|
ReportError(w, err)
|
||||||
return
|
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{
|
session := backend.Session{
|
||||||
SessionID: SessionID,
|
SessionID: SessionID,
|
||||||
Expiration: expiration,
|
Expiration: *expiration,
|
||||||
UserID: uid,
|
UserID: uid,
|
||||||
LdapDN: entry.DN,
|
LdapDN: entry.DN,
|
||||||
}
|
}
|
||||||
@@ -65,4 +109,6 @@ func loginKrb(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
_ = datastore.PutSession(session, sessionCache)
|
_ = datastore.PutSession(session, sessionCache)
|
||||||
|
|
||||||
|
// TODO: set cookies, return success
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user