connector/ldap: support the StartTLS flow for secure connections

When connecting to an LDAP server, there are three ways to connect:

1. Insecurely through port 389 (LDAP).
2. Securely through port 696 (LDAPS).
3. Insecurely through port 389 then negotiate TLS (StartTLS).

This PR adds support for the 3rd flow, letting dex connect to the
standard LDAP port then negotiating TLS through the LDAP protocol
itself.

See a writeup here:

http://www.openldap.org/faq/data/cache/185.html
This commit is contained in:
Eric Chiang
2017-04-12 14:13:34 -07:00
parent 9b0af83604
commit 74f5eaf47e
8 changed files with 334 additions and 27 deletions

View File

@@ -61,6 +61,11 @@ type Config struct {
// Don't verify the CA.
InsecureSkipVerify bool `json:"insecureSkipVerify"`
// Connect to the insecure port then issue a StartTLS command to negotiate a
// secure connection. If unsupplied secure connections will use the LDAPS
// protocol.
StartTLS bool `json:"startTLS"`
// Path to a trusted root certificate file.
RootCA string `json:"rootCA"`
@@ -238,9 +243,18 @@ func (c *ldapConnector) do(ctx context.Context, f func(c *ldap.Conn) error) erro
conn *ldap.Conn
err error
)
if c.InsecureNoSSL {
switch {
case c.InsecureNoSSL:
conn, err = ldap.Dial("tcp", c.Host)
} else {
case c.StartTLS:
conn, err = ldap.Dial("tcp", c.Host)
if err != nil {
return fmt.Errorf("failed to connect: %v", err)
}
if err := conn.StartTLS(c.tlsConfig); err != nil {
return fmt.Errorf("start TLS failed: %v", err)
}
default:
conn, err = ldap.DialTLS("tcp", c.Host, c.tlsConfig)
}
if err != nil {