2019-04-24 21:52:08 +00:00
|
|
|
package authentication
|
|
|
|
|
2022-05-02 01:51:38 +00:00
|
|
|
import (
|
|
|
|
"crypto/tls"
|
2022-07-18 00:56:09 +00:00
|
|
|
"net/mail"
|
2023-04-14 11:42:31 +00:00
|
|
|
"time"
|
2022-05-02 01:51:38 +00:00
|
|
|
|
|
|
|
"github.com/go-ldap/ldap/v3"
|
|
|
|
)
|
|
|
|
|
2022-05-10 04:38:36 +00:00
|
|
|
// LDAPClientFactory an interface of factory of LDAP clients.
|
|
|
|
type LDAPClientFactory interface {
|
|
|
|
DialURL(addr string, opts ...ldap.DialOpt) (client LDAPClient, err error)
|
2022-05-02 01:51:38 +00:00
|
|
|
}
|
|
|
|
|
2022-05-10 04:38:36 +00:00
|
|
|
// LDAPClient is a cut down version of the ldap.Client interface with just the methods we use.
|
|
|
|
//
|
|
|
|
// Methods added to this interface that have a direct correlation with one from ldap.Client should have the same signature.
|
|
|
|
type LDAPClient interface {
|
2023-05-06 03:02:04 +00:00
|
|
|
Close() (err error)
|
2023-04-14 11:42:31 +00:00
|
|
|
IsClosing() bool
|
|
|
|
SetTimeout(timeout time.Duration)
|
|
|
|
|
|
|
|
TLSConnectionState() (state tls.ConnectionState, ok bool)
|
2022-05-02 01:51:38 +00:00
|
|
|
StartTLS(config *tls.Config) (err error)
|
|
|
|
|
2023-04-14 11:42:31 +00:00
|
|
|
Unbind() (err error)
|
2022-05-10 04:38:36 +00:00
|
|
|
Bind(username, password string) (err error)
|
2023-04-14 11:42:31 +00:00
|
|
|
SimpleBind(request *ldap.SimpleBindRequest) (result *ldap.SimpleBindResult, err error)
|
|
|
|
MD5Bind(host string, username string, password string) (err error)
|
|
|
|
DigestMD5Bind(request *ldap.DigestMD5BindRequest) (result *ldap.DigestMD5BindResult, err error)
|
2022-06-17 11:03:47 +00:00
|
|
|
UnauthenticatedBind(username string) (err error)
|
2023-04-14 11:42:31 +00:00
|
|
|
ExternalBind() (err error)
|
|
|
|
NTLMBind(domain string, username string, password string) (err error)
|
|
|
|
NTLMUnauthenticatedBind(domain string, username string) (err error)
|
|
|
|
NTLMBindWithHash(domain string, username string, hash string) (err error)
|
|
|
|
NTLMChallengeBind(request *ldap.NTLMBindRequest) (result *ldap.NTLMBindResult, err error)
|
|
|
|
|
|
|
|
Modify(request *ldap.ModifyRequest) (err error)
|
|
|
|
ModifyWithResult(request *ldap.ModifyRequest) (result *ldap.ModifyResult, err error)
|
|
|
|
ModifyDN(m *ldap.ModifyDNRequest) (err error)
|
|
|
|
PasswordModify(request *ldap.PasswordModifyRequest) (result *ldap.PasswordModifyResult, err error)
|
|
|
|
|
|
|
|
Add(request *ldap.AddRequest) (err error)
|
|
|
|
Del(request *ldap.DelRequest) (err error)
|
2022-05-02 01:51:38 +00:00
|
|
|
|
2023-04-14 11:42:31 +00:00
|
|
|
Search(request *ldap.SearchRequest) (result *ldap.SearchResult, err error)
|
|
|
|
SearchWithPaging(request *ldap.SearchRequest, pagingSize uint32) (result *ldap.SearchResult, err error)
|
|
|
|
Compare(dn string, attribute string, value string) (same bool, err error)
|
2022-05-10 04:38:36 +00:00
|
|
|
|
2023-04-14 11:42:31 +00:00
|
|
|
WhoAmI(controls []ldap.Control) (result *ldap.WhoAmIResult, err error)
|
2022-05-02 01:51:38 +00:00
|
|
|
}
|
|
|
|
|
2019-04-24 21:52:08 +00:00
|
|
|
// UserDetails represent the details retrieved for a given user.
|
|
|
|
type UserDetails struct {
|
2020-06-19 10:50:21 +00:00
|
|
|
Username string
|
|
|
|
DisplayName string
|
|
|
|
Emails []string
|
|
|
|
Groups []string
|
2019-04-24 21:52:08 +00:00
|
|
|
}
|
2022-05-02 01:51:38 +00:00
|
|
|
|
2022-07-18 00:56:09 +00:00
|
|
|
// Addresses returns the Emails []string as []mail.Address formatted with DisplayName as the Name attribute.
|
|
|
|
func (d UserDetails) Addresses() (addresses []mail.Address) {
|
|
|
|
if len(d.Emails) == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
addresses = make([]mail.Address, len(d.Emails))
|
|
|
|
|
|
|
|
for i, email := range d.Emails {
|
|
|
|
addresses[i] = mail.Address{
|
|
|
|
Name: d.DisplayName,
|
|
|
|
Address: email,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return addresses
|
|
|
|
}
|
|
|
|
|
2022-05-02 01:51:38 +00:00
|
|
|
type ldapUserProfile struct {
|
|
|
|
DN string
|
|
|
|
Emails []string
|
|
|
|
DisplayName string
|
|
|
|
Username string
|
2023-06-18 04:40:38 +00:00
|
|
|
MemberOf []string
|
2022-05-02 01:51:38 +00:00
|
|
|
}
|
|
|
|
|
2022-05-10 04:38:36 +00:00
|
|
|
// LDAPSupportedFeatures represents features which a server may support which are implemented in code.
|
|
|
|
type LDAPSupportedFeatures struct {
|
|
|
|
Extensions LDAPSupportedExtensions
|
|
|
|
ControlTypes LDAPSupportedControlTypes
|
|
|
|
}
|
|
|
|
|
|
|
|
// LDAPSupportedExtensions represents extensions which a server may support which are implemented in code.
|
|
|
|
type LDAPSupportedExtensions struct {
|
|
|
|
TLS bool
|
|
|
|
PwdModifyExOp bool
|
|
|
|
}
|
|
|
|
|
|
|
|
// LDAPSupportedControlTypes represents control types which a server may support which are implemented in code.
|
|
|
|
type LDAPSupportedControlTypes struct {
|
|
|
|
MsftPwdPolHints bool
|
|
|
|
MsftPwdPolHintsDeprecated bool
|
|
|
|
}
|
|
|
|
|
2023-05-25 02:26:19 +00:00
|
|
|
// Level is the type representing a level of authentication.
|
|
|
|
type Level int
|
|
|
|
|
|
|
|
const (
|
|
|
|
// NotAuthenticated if the user is not authenticated yet.
|
|
|
|
NotAuthenticated Level = iota
|
|
|
|
|
|
|
|
// OneFactor if the user has passed first factor only.
|
|
|
|
OneFactor
|
|
|
|
|
|
|
|
// TwoFactor if the user has passed two factors.
|
|
|
|
TwoFactor
|
|
|
|
)
|
|
|
|
|
|
|
|
// String returns a string representation of an authentication.Level.
|
|
|
|
func (l Level) String() string {
|
|
|
|
switch l {
|
|
|
|
case NotAuthenticated:
|
|
|
|
return "not_authenticated"
|
|
|
|
case OneFactor:
|
|
|
|
return "one_factor"
|
|
|
|
case TwoFactor:
|
|
|
|
return "two_factor"
|
|
|
|
default:
|
|
|
|
return "invalid"
|
|
|
|
}
|
|
|
|
}
|