diff options
Diffstat (limited to 'modules/auth/ldap/ldap.go')
-rw-r--r-- | modules/auth/ldap/ldap.go | 73 |
1 files changed, 48 insertions, 25 deletions
diff --git a/modules/auth/ldap/ldap.go b/modules/auth/ldap/ldap.go index 0875ec3dae..598929d9e5 100644 --- a/modules/auth/ldap/ldap.go +++ b/modules/auth/ldap/ldap.go @@ -16,12 +16,21 @@ import ( "github.com/gogits/gogs/modules/log" ) +type SecurityProtocol int + +// Note: new type must be added at the end of list to maintain compatibility. +const ( + SECURITY_PROTOCOL_UNENCRYPTED SecurityProtocol = iota + SECURITY_PROTOCOL_LDAPS + SECURITY_PROTOCOL_START_TLS +) + // Basic LDAP authentication service type Source struct { Name string // canonical name (ie. corporate.ad) Host string // LDAP host Port int // port number - UseSSL bool // Use SSL + SecurityProtocol SecurityProtocol SkipVerify bool BindDN string // DN to bind with BindPassword string // Bind DN password @@ -102,9 +111,46 @@ func (ls *Source) findUserDN(l *ldap.Conn, name string) (string, bool) { return userDN, true } +func dial(ls *Source) (*ldap.Conn, error) { + log.Trace("Dialing LDAP with security protocol (%v) without verifying: %v", ls.SecurityProtocol, ls.SkipVerify) + + tlsCfg := &tls.Config{ + ServerName: ls.Host, + InsecureSkipVerify: ls.SkipVerify, + } + if ls.SecurityProtocol == SECURITY_PROTOCOL_LDAPS { + return ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port), tlsCfg) + } + + conn, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port)) + if err != nil { + return nil, fmt.Errorf("Dial: %v", err) + } + + if ls.SecurityProtocol == SECURITY_PROTOCOL_START_TLS { + if err = conn.StartTLS(tlsCfg); err != nil { + conn.Close() + return nil, fmt.Errorf("StartTLS: %v", err) + } + } + + return conn, nil +} + +func bindUser(l *ldap.Conn, userDN, passwd string) error { + log.Trace("Binding with userDN: %s", userDN) + err := l.Bind(userDN, passwd) + if err != nil { + log.Debug("LDAP auth. failed for %s, reason: %v", userDN, err) + return err + } + log.Trace("Bound successfully with userDN: %s", userDN) + return err +} + // searchEntry : search an LDAP source if an entry (name, passwd) is valid and in the specific filter func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, string, string, string, bool, bool) { - l, err := ldapDial(ls) + l, err := dial(ls) if err != nil { log.Error(4, "LDAP Connect error, %s:%v", ls.Host, err) ls.Enabled = false @@ -197,26 +243,3 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str return username_attr, name_attr, sn_attr, mail_attr, admin_attr, true } - -func bindUser(l *ldap.Conn, userDN, passwd string) error { - log.Trace("Binding with userDN: %s", userDN) - err := l.Bind(userDN, passwd) - if err != nil { - log.Debug("LDAP auth. failed for %s, reason: %v", userDN, err) - return err - } - log.Trace("Bound successfully with userDN: %s", userDN) - return err -} - -func ldapDial(ls *Source) (*ldap.Conn, error) { - if ls.UseSSL { - log.Debug("Using TLS for LDAP without verifying: %v", ls.SkipVerify) - return ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port), &tls.Config{ - ServerName: ls.Host, - InsecureSkipVerify: ls.SkipVerify, - }) - } else { - return ldap.Dial("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port)) - } -} |