forked from mystiq/dex
Merge pull request #908 from ericchiang/start-tls
connector/ldap: support the StartTLS flow for secure connections
This commit is contained in:
commit
e609de5018
8 changed files with 334 additions and 27 deletions
|
@ -30,20 +30,28 @@ connectors:
|
||||||
name: LDAP
|
name: LDAP
|
||||||
config:
|
config:
|
||||||
# Host and optional port of the LDAP server in the form "host:port".
|
# Host and optional port of the LDAP server in the form "host:port".
|
||||||
# If the port is not supplied, it will be guessed based on "insecureNoSSL".
|
# If the port is not supplied, it will be guessed based on "insecureNoSSL",
|
||||||
# 389 for insecure connections, 636 otherwise.
|
# and "startTLS" flags. 389 for insecure or StartTLS connections, 636
|
||||||
|
# otherwise.
|
||||||
host: ldap.example.com:636
|
host: ldap.example.com:636
|
||||||
|
|
||||||
# Following field is required if the LDAP host is not using TLS (port 389).
|
# Following field is required if the LDAP host is not using TLS (port 389).
|
||||||
# Because this option inherently leaks passwords to anyone on the same network
|
# Because this option inherently leaks passwords to anyone on the same network
|
||||||
# as dex, THIS OPTION MAY BE REMOVED WITHOUT WARNING IN A FUTURE RELEASE.
|
# as dex, THIS OPTION MAY BE REMOVED WITHOUT WARNING IN A FUTURE RELEASE.
|
||||||
|
#
|
||||||
# insecureNoSSL: true
|
# insecureNoSSL: true
|
||||||
|
|
||||||
# If a custom certificate isn't provide, this option can be used to turn on
|
# If a custom certificate isn't provide, this option can be used to turn on
|
||||||
# TLS certificate checks. As noted, it is insecure and shouldn't be used outside
|
# TLS certificate checks. As noted, it is insecure and shouldn't be used outside
|
||||||
# of explorative phases.
|
# of explorative phases.
|
||||||
|
#
|
||||||
# insecureSkipVerify: true
|
# insecureSkipVerify: true
|
||||||
|
|
||||||
|
# When connecting to the server, connect using the ldap:// protocol then issue
|
||||||
|
# a StartTLS command. If unspecified, connections will use the ldaps:// protocol
|
||||||
|
#
|
||||||
|
# startTLS: true
|
||||||
|
|
||||||
# Path to a trusted root certificate file. Default: use the host's root CA.
|
# Path to a trusted root certificate file. Default: use the host's root CA.
|
||||||
rootCA: /etc/dex/ldap.ca
|
rootCA: /etc/dex/ldap.ca
|
||||||
|
|
||||||
|
|
49
connector/ldap/gen-certs.sh
Executable file
49
connector/ldap/gen-certs.sh
Executable file
|
@ -0,0 +1,49 @@
|
||||||
|
#!/bin/bash -e
|
||||||
|
|
||||||
|
# Stolen from the coreos/matchbox repo.
|
||||||
|
|
||||||
|
echo "
|
||||||
|
[req]
|
||||||
|
req_extensions = v3_req
|
||||||
|
distinguished_name = req_distinguished_name
|
||||||
|
|
||||||
|
[req_distinguished_name]
|
||||||
|
|
||||||
|
[ v3_req ]
|
||||||
|
basicConstraints = CA:FALSE
|
||||||
|
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||||
|
subjectAltName = @alt_names
|
||||||
|
|
||||||
|
[alt_names]
|
||||||
|
DNS.101 = localhost
|
||||||
|
" > openssl.config
|
||||||
|
|
||||||
|
openssl genrsa -out testdata/ca.key 2048
|
||||||
|
openssl genrsa -out testdata/server.key 2048
|
||||||
|
|
||||||
|
openssl req \
|
||||||
|
-x509 -new -nodes \
|
||||||
|
-key testdata/ca.key \
|
||||||
|
-days 10000 -out testdata/ca.crt \
|
||||||
|
-subj "/CN=ldap-tests"
|
||||||
|
|
||||||
|
openssl req \
|
||||||
|
-new \
|
||||||
|
-key testdata/server.key \
|
||||||
|
-out testdata/server.csr \
|
||||||
|
-subj "/CN=localhost" \
|
||||||
|
-config openssl.config
|
||||||
|
|
||||||
|
openssl x509 -req \
|
||||||
|
-in testdata/server.csr \
|
||||||
|
-CA testdata/ca.crt \
|
||||||
|
-CAkey testdata/ca.key \
|
||||||
|
-CAcreateserial \
|
||||||
|
-out testdata/server.crt \
|
||||||
|
-days 10000 \
|
||||||
|
-extensions v3_req \
|
||||||
|
-extfile openssl.config
|
||||||
|
|
||||||
|
rm testdata/server.csr
|
||||||
|
rm testdata/ca.srl
|
||||||
|
rm openssl.config
|
|
@ -61,6 +61,11 @@ type Config struct {
|
||||||
// Don't verify the CA.
|
// Don't verify the CA.
|
||||||
InsecureSkipVerify bool `json:"insecureSkipVerify"`
|
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.
|
// Path to a trusted root certificate file.
|
||||||
RootCA string `json:"rootCA"`
|
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
|
conn *ldap.Conn
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
if c.InsecureNoSSL {
|
switch {
|
||||||
|
case c.InsecureNoSSL:
|
||||||
conn, err = ldap.Dial("tcp", c.Host)
|
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)
|
conn, err = ldap.DialTLS("tcp", c.Host, c.tlsConfig)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -21,6 +21,15 @@ import (
|
||||||
|
|
||||||
const envVar = "DEX_LDAP_TESTS"
|
const envVar = "DEX_LDAP_TESTS"
|
||||||
|
|
||||||
|
// connectionMethod indicates how the test should connect to the LDAP server.
|
||||||
|
type connectionMethod int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
connectStartTLS connectionMethod = iota
|
||||||
|
connectLDAPS
|
||||||
|
connectLDAP
|
||||||
|
)
|
||||||
|
|
||||||
// subtest is a login test against a given schema.
|
// subtest is a login test against a given schema.
|
||||||
type subtest struct {
|
type subtest struct {
|
||||||
// Name of the sub-test.
|
// Name of the sub-test.
|
||||||
|
@ -110,7 +119,7 @@ userpassword: bar
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
runTests(t, schema, c, tests)
|
runTests(t, schema, connectLDAP, c, tests)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGroupQuery(t *testing.T) {
|
func TestGroupQuery(t *testing.T) {
|
||||||
|
@ -198,7 +207,7 @@ member: cn=jane,ou=People,dc=example,dc=org
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
runTests(t, schema, c, tests)
|
runTests(t, schema, connectLDAP, c, tests)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGroupsOnUserEntity(t *testing.T) {
|
func TestGroupsOnUserEntity(t *testing.T) {
|
||||||
|
@ -295,7 +304,93 @@ gidNumber: 1002
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
runTests(t, schema, c, tests)
|
runTests(t, schema, connectLDAP, c, tests)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStartTLS(t *testing.T) {
|
||||||
|
schema := `
|
||||||
|
dn: dc=example,dc=org
|
||||||
|
objectClass: dcObject
|
||||||
|
objectClass: organization
|
||||||
|
o: Example Company
|
||||||
|
dc: example
|
||||||
|
|
||||||
|
dn: ou=People,dc=example,dc=org
|
||||||
|
objectClass: organizationalUnit
|
||||||
|
ou: People
|
||||||
|
|
||||||
|
dn: cn=jane,ou=People,dc=example,dc=org
|
||||||
|
objectClass: person
|
||||||
|
objectClass: inetOrgPerson
|
||||||
|
sn: doe
|
||||||
|
cn: jane
|
||||||
|
mail: janedoe@example.com
|
||||||
|
userpassword: foo
|
||||||
|
`
|
||||||
|
c := &Config{}
|
||||||
|
c.UserSearch.BaseDN = "ou=People,dc=example,dc=org"
|
||||||
|
c.UserSearch.NameAttr = "cn"
|
||||||
|
c.UserSearch.EmailAttr = "mail"
|
||||||
|
c.UserSearch.IDAttr = "DN"
|
||||||
|
c.UserSearch.Username = "cn"
|
||||||
|
|
||||||
|
tests := []subtest{
|
||||||
|
{
|
||||||
|
name: "validpassword",
|
||||||
|
username: "jane",
|
||||||
|
password: "foo",
|
||||||
|
want: connector.Identity{
|
||||||
|
UserID: "cn=jane,ou=People,dc=example,dc=org",
|
||||||
|
Username: "jane",
|
||||||
|
Email: "janedoe@example.com",
|
||||||
|
EmailVerified: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
runTests(t, schema, connectStartTLS, c, tests)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLDAPS(t *testing.T) {
|
||||||
|
schema := `
|
||||||
|
dn: dc=example,dc=org
|
||||||
|
objectClass: dcObject
|
||||||
|
objectClass: organization
|
||||||
|
o: Example Company
|
||||||
|
dc: example
|
||||||
|
|
||||||
|
dn: ou=People,dc=example,dc=org
|
||||||
|
objectClass: organizationalUnit
|
||||||
|
ou: People
|
||||||
|
|
||||||
|
dn: cn=jane,ou=People,dc=example,dc=org
|
||||||
|
objectClass: person
|
||||||
|
objectClass: inetOrgPerson
|
||||||
|
sn: doe
|
||||||
|
cn: jane
|
||||||
|
mail: janedoe@example.com
|
||||||
|
userpassword: foo
|
||||||
|
`
|
||||||
|
c := &Config{}
|
||||||
|
c.UserSearch.BaseDN = "ou=People,dc=example,dc=org"
|
||||||
|
c.UserSearch.NameAttr = "cn"
|
||||||
|
c.UserSearch.EmailAttr = "mail"
|
||||||
|
c.UserSearch.IDAttr = "DN"
|
||||||
|
c.UserSearch.Username = "cn"
|
||||||
|
|
||||||
|
tests := []subtest{
|
||||||
|
{
|
||||||
|
name: "validpassword",
|
||||||
|
username: "jane",
|
||||||
|
password: "foo",
|
||||||
|
want: connector.Identity{
|
||||||
|
UserID: "cn=jane,ou=People,dc=example,dc=org",
|
||||||
|
Username: "jane",
|
||||||
|
Email: "janedoe@example.com",
|
||||||
|
EmailVerified: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
runTests(t, schema, connectLDAPS, c, tests)
|
||||||
}
|
}
|
||||||
|
|
||||||
// runTests runs a set of tests against an LDAP schema. It does this by
|
// runTests runs a set of tests against an LDAP schema. It does this by
|
||||||
|
@ -305,7 +400,7 @@ gidNumber: 1002
|
||||||
// machine's PATH.
|
// machine's PATH.
|
||||||
//
|
//
|
||||||
// The DEX_LDAP_TESTS must be set to "1"
|
// The DEX_LDAP_TESTS must be set to "1"
|
||||||
func runTests(t *testing.T, schema string, config *Config, tests []subtest) {
|
func runTests(t *testing.T, schema string, connMethod connectionMethod, config *Config, tests []subtest) {
|
||||||
if os.Getenv(envVar) != "1" {
|
if os.Getenv(envVar) != "1" {
|
||||||
t.Skipf("%s not set. Skipping test (run 'export %s=1' to run tests)", envVar, envVar)
|
t.Skipf("%s not set. Skipping test (run 'export %s=1' to run tests)", envVar, envVar)
|
||||||
}
|
}
|
||||||
|
@ -316,6 +411,11 @@ func runTests(t *testing.T, schema string, config *Config, tests []subtest) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
tempDir, err := ioutil.TempDir("", "")
|
tempDir, err := ioutil.TempDir("", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -324,7 +424,13 @@ func runTests(t *testing.T, schema string, config *Config, tests []subtest) {
|
||||||
|
|
||||||
configBytes := new(bytes.Buffer)
|
configBytes := new(bytes.Buffer)
|
||||||
|
|
||||||
if err := slapdConfigTmpl.Execute(configBytes, tmplData{tempDir, includes(t)}); err != nil {
|
data := tmplData{
|
||||||
|
TempDir: tempDir,
|
||||||
|
Includes: includes(t, wd),
|
||||||
|
}
|
||||||
|
data.TLSCertPath, data.TLSKeyPath = tlsAssets(t, wd)
|
||||||
|
|
||||||
|
if err := slapdConfigTmpl.Execute(configBytes, data); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,7 +450,7 @@ func runTests(t *testing.T, schema string, config *Config, tests []subtest) {
|
||||||
cmd := exec.Command(
|
cmd := exec.Command(
|
||||||
"slapd",
|
"slapd",
|
||||||
"-d", "any",
|
"-d", "any",
|
||||||
"-h", "ldap://localhost:10363/ ldaps://localhost:10636/ ldapi://"+socketPath,
|
"-h", "ldap://localhost:10389/ ldaps://localhost:10636/ ldapi://"+socketPath,
|
||||||
"-f", configPath,
|
"-f", configPath,
|
||||||
)
|
)
|
||||||
cmd.Stdout = slapdOut
|
cmd.Stdout = slapdOut
|
||||||
|
@ -385,18 +491,30 @@ func runTests(t *testing.T, schema string, config *Config, tests []subtest) {
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Wait for slapd to come up.
|
// Try a few times to connect to the LDAP server. On slower machines
|
||||||
time.Sleep(100 * time.Millisecond)
|
// it can take a while for it to come up.
|
||||||
|
connected := false
|
||||||
|
wait := 100 * time.Millisecond
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
|
time.Sleep(wait)
|
||||||
|
|
||||||
ldapadd := exec.Command(
|
ldapadd := exec.Command(
|
||||||
"ldapadd", "-x",
|
"ldapadd", "-x",
|
||||||
"-D", "cn=admin,dc=example,dc=org",
|
"-D", "cn=admin,dc=example,dc=org",
|
||||||
"-w", "admin",
|
"-w", "admin",
|
||||||
"-f", schemaPath,
|
"-f", schemaPath,
|
||||||
"-H", "ldap://localhost:10363/",
|
"-H", "ldap://localhost:10389/",
|
||||||
)
|
)
|
||||||
if out, err := ldapadd.CombinedOutput(); err != nil {
|
if out, err := ldapadd.CombinedOutput(); err != nil {
|
||||||
t.Errorf("ldapadd: %s", out)
|
t.Logf("ldapadd: %s", out)
|
||||||
|
wait = wait * 2 // backoff
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
connected = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if !connected {
|
||||||
|
t.Errorf("ldapadd command failed")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,8 +523,19 @@ func runTests(t *testing.T, schema string, config *Config, tests []subtest) {
|
||||||
|
|
||||||
// We need to configure host parameters but don't want to overwrite user or
|
// We need to configure host parameters but don't want to overwrite user or
|
||||||
// group search configuration.
|
// group search configuration.
|
||||||
c.Host = "localhost:10363"
|
switch connMethod {
|
||||||
|
case connectStartTLS:
|
||||||
|
c.Host = "localhost:10389"
|
||||||
|
c.RootCA = "testdata/ca.crt"
|
||||||
|
c.StartTLS = true
|
||||||
|
case connectLDAPS:
|
||||||
|
c.Host = "localhost:10636"
|
||||||
|
c.RootCA = "testdata/ca.crt"
|
||||||
|
case connectLDAP:
|
||||||
|
c.Host = "localhost:10389"
|
||||||
c.InsecureNoSSL = true
|
c.InsecureNoSSL = true
|
||||||
|
}
|
||||||
|
|
||||||
c.BindDN = "cn=admin,dc=example,dc=org"
|
c.BindDN = "cn=admin,dc=example,dc=org"
|
||||||
c.BindPW = "admin"
|
c.BindPW = "admin"
|
||||||
|
|
||||||
|
@ -488,10 +617,16 @@ type tmplData struct {
|
||||||
TempDir string
|
TempDir string
|
||||||
// List of schema files to include.
|
// List of schema files to include.
|
||||||
Includes []string
|
Includes []string
|
||||||
|
// TLS assets for LDAPS.
|
||||||
|
TLSKeyPath string
|
||||||
|
TLSCertPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config template copied from:
|
// Config template copied from:
|
||||||
// http://www.zytrax.com/books/ldap/ch5/index.html#step1-slapd
|
// http://www.zytrax.com/books/ldap/ch5/index.html#step1-slapd
|
||||||
|
//
|
||||||
|
// TLS instructions found here:
|
||||||
|
// http://www.openldap.org/doc/admin24/tls.html
|
||||||
var slapdConfigTmpl = template.Must(template.New("").Parse(`
|
var slapdConfigTmpl = template.Must(template.New("").Parse(`
|
||||||
{{ range $i, $include := .Includes }}
|
{{ range $i, $include := .Includes }}
|
||||||
include {{ $include }}
|
include {{ $include }}
|
||||||
|
@ -511,6 +646,9 @@ rootpw admin
|
||||||
# change path as necessary
|
# change path as necessary
|
||||||
directory {{ .TempDir }}
|
directory {{ .TempDir }}
|
||||||
|
|
||||||
|
TLSCertificateFile {{ .TLSCertPath }}
|
||||||
|
TLSCertificateKeyFile {{ .TLSKeyPath }}
|
||||||
|
|
||||||
# Indices to maintain for this directory
|
# Indices to maintain for this directory
|
||||||
# unique id so equality match only
|
# unique id so equality match only
|
||||||
index uid eq
|
index uid eq
|
||||||
|
@ -534,11 +672,18 @@ cachesize 10000
|
||||||
checkpoint 128 15
|
checkpoint 128 15
|
||||||
`))
|
`))
|
||||||
|
|
||||||
func includes(t *testing.T) (paths []string) {
|
func tlsAssets(t *testing.T, wd string) (certPath, keyPath string) {
|
||||||
wd, err := os.Getwd()
|
certPath = filepath.Join(wd, "testdata", "server.crt")
|
||||||
if err != nil {
|
keyPath = filepath.Join(wd, "testdata", "server.key")
|
||||||
t.Fatalf("getting working directory: %v", err)
|
for _, p := range []string{certPath, keyPath} {
|
||||||
|
if _, err := os.Stat(p); err != nil {
|
||||||
|
t.Fatalf("failed to find TLS asset file: %s %v", p, err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func includes(t *testing.T, wd string) (paths []string) {
|
||||||
for _, f := range includeFiles {
|
for _, f := range includeFiles {
|
||||||
p := filepath.Join(wd, "testdata", f)
|
p := filepath.Join(wd, "testdata", f)
|
||||||
if _, err := os.Stat(p); err != nil {
|
if _, err := os.Stat(p); err != nil {
|
||||||
|
|
19
connector/ldap/testdata/ca.crt
vendored
Normal file
19
connector/ldap/testdata/ca.crt
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIC/TCCAeWgAwIBAgIJAIrt+AlVUsXKMA0GCSqGSIb3DQEBCwUAMBUxEzARBgNV
|
||||||
|
BAMMCmxkYXAtdGVzdHMwHhcNMTcwNDEyMjAxNzI5WhcNNDQwODI4MjAxNzI5WjAV
|
||||||
|
MRMwEQYDVQQDDApsZGFwLXRlc3RzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||||
|
CgKCAQEAzKJkt2WsALUDA3tQsedx7UJKIxis05+dU5FbBxf/BMSch8gCNh/cWErH
|
||||||
|
IDljWGwLKbc9UefIz3BzbcNBPLgLGMp7t9Pf9HCBNf7lShLZB2BEGpgpCpd0urox
|
||||||
|
xTqMEfchssJj75HOZRweHfBDDHk8LMHQYUBn5qTiuMYvBUbPVq69argE/kt5yAEW
|
||||||
|
COZzzx38a11iY0gtPjY4Tc9vICsLHhTssNn/1wf+GFNzSTHqijC7NKW0txUneFQJ
|
||||||
|
h6LAmKV/uZC84W1tqMDZKKpABiTpB+JbDvwsb9eXJ6YG6TgbKcrXjLy4ogbIrIRA
|
||||||
|
s2DqMih792mxusIl6lRf3hTtCdyodwIDAQABo1AwTjAdBgNVHQ4EFgQUnfj9sAq4
|
||||||
|
2xBbV4rf5FNvYaE2Bg0wHwYDVR0jBBgwFoAUnfj9sAq42xBbV4rf5FNvYaE2Bg0w
|
||||||
|
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAFGnBH1qpLJLvrLWKNI5w
|
||||||
|
u8pFYO3RGqmfJ3BGf60MQxdUaTIUNQxPfPATbth7t8GRJwpWESRDlaXWq9fM9rkt
|
||||||
|
fbmuqjAMGTFloNd9ra6e2F0CKjwZWcn/3eG/mVw/5d1Ku9Ow8luKrZuzNzVJd13r
|
||||||
|
hoNc1wYXN0pHWkNiRUuR/E4fE/sn+tYOpJ4XYQvKAcSrNrq8m5O9VG5gLvlTeNno
|
||||||
|
6q9hBy+5XKYUdHlzbAGm9QL0e1R45Mu4qxcFluKEmzS1rXlLsLs4/pqHgreXlYgL
|
||||||
|
f7K0cFvaJGnFRKaxa6Bpf1EPNtqSc/pQZh01Ww8CUu1xh2+5KufgJQjAHVG3a1ow
|
||||||
|
dQ==
|
||||||
|
-----END CERTIFICATE-----
|
27
connector/ldap/testdata/ca.key
vendored
Normal file
27
connector/ldap/testdata/ca.key
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEowIBAAKCAQEAzKJkt2WsALUDA3tQsedx7UJKIxis05+dU5FbBxf/BMSch8gC
|
||||||
|
Nh/cWErHIDljWGwLKbc9UefIz3BzbcNBPLgLGMp7t9Pf9HCBNf7lShLZB2BEGpgp
|
||||||
|
Cpd0uroxxTqMEfchssJj75HOZRweHfBDDHk8LMHQYUBn5qTiuMYvBUbPVq69argE
|
||||||
|
/kt5yAEWCOZzzx38a11iY0gtPjY4Tc9vICsLHhTssNn/1wf+GFNzSTHqijC7NKW0
|
||||||
|
txUneFQJh6LAmKV/uZC84W1tqMDZKKpABiTpB+JbDvwsb9eXJ6YG6TgbKcrXjLy4
|
||||||
|
ogbIrIRAs2DqMih792mxusIl6lRf3hTtCdyodwIDAQABAoIBAHQpEucQbe0Q058c
|
||||||
|
VxhF+2PlJ1R441JV3ubbMkL6mibIvNpO7QJwX5I3EIX4Ta6Z1lRd0g82dcVbXgrG
|
||||||
|
tbeT+aie+E/Hk++cFZzjDqFXxZ7sRHycN1/tzbNZknsU2wIvuQ9STYxmxjSbG3V/
|
||||||
|
N3BTOZdmhbVO7Cv/GTwuM+7Y3UWkc74HaXfAgo1UIO9MtqgqP3H1Tv6ZIeKzl+mP
|
||||||
|
wrvei0eQe6jI4W6+vUOX3SlrlrMxMTLK/Ce2MP1pJx++m8Ga23+vtna+lkOWnwcD
|
||||||
|
NmhYl4dL31sDcE6Hz/T6Wwfdlfyugw8vi3a3GEYGMIwy27CFf/ccYnWPOI3oIHDe
|
||||||
|
RwlXLCECgYEA595xJmfUpwqgYY80pT3JG3+64NWJ7f/gH0Ey9fivZfnTegjkI2Kc
|
||||||
|
Uf7+odCq9I1TFtx10M72N4pXT1uLzJtINYty4ZIfOLG7jSraVbOuf9AvMNCYw+cT
|
||||||
|
Fcf/HGUJEE95TKYDrGfklOYFNs3ZCcKOCYJOWCuwki8Vm2vtJpV6gnkCgYEA4e5b
|
||||||
|
DI+YworLjokY8eP4aOF5BMuiFdGkYDjVQZG45RwjJdLwBjaf+HA4pAuJAr2LWiLX
|
||||||
|
cdKpk+3AlJ8UMLIM+hBP4hBqnrPaRTkEhTXpbUA1lvL9o0mVDFgNh90guu5TeJza
|
||||||
|
sW7JLaStmAyCxYGxbW4LTjR8GX9DPOPmLs5ZRm8CgYAyFW5DaXIZksYJzLEGcE4c
|
||||||
|
Tn7DSdy9N+PlXGPxlYHteQUg+wKsUgSKAZZmxXfn0w77hSs9qzar0IoDbjbIP1Jd
|
||||||
|
nn12E+YCjQGCAJugn2s12HYZCTW2Oxd4QPbt3zUR/NiqocFxYA+TygueRuB2pzue
|
||||||
|
+jKKAQXmzZzRMYLMLsWDoQKBgAnrCcoyX5VivG7ka9jqlhQcmdBxFAt7KYkj1ZDM
|
||||||
|
Ud6U7qIRcYIEUd95JbNl4jzhj0WEtAqGIfWhgUvE9ADzQAiWQLt+1v9ii9lwGFe0
|
||||||
|
tyuZnwCiaCoL5+Qj1Ww6c95g6f8oe51AbMp5KTm8it0axWw1YX+sZCpGYPBCXO9/
|
||||||
|
FYI3AoGBAMacjjbPjjfOXxBRhRz1rEDTrIStDj5KM4fgslKVGysqpH/mw7gSC8SK
|
||||||
|
qn0anL2s3SAe9PQpOzM3pFFRZx4XMOk4ojYRZtp3FjPFDRnYuYzkfkbU7eV04awO
|
||||||
|
6nrua8KNLNK+ir9iCi46tP6Zr3F81zWGUoVArVUgCRDbA9e0swB0
|
||||||
|
-----END RSA PRIVATE KEY-----
|
18
connector/ldap/testdata/server.crt
vendored
Normal file
18
connector/ldap/testdata/server.crt
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIC3DCCAcSgAwIBAgIJANsmsx7hUWnHMA0GCSqGSIb3DQEBCwUAMBUxEzARBgNV
|
||||||
|
BAMMCmxkYXAtdGVzdHMwHhcNMTcwNDEyMjAxNzI5WhcNNDQwODI4MjAxNzI5WjAU
|
||||||
|
MRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
|
||||||
|
AoIBAQDlWGC5X/TWgysEimM7n0hSkXRCITwAFxKG0C4EeppmL42DBcjQa0xrElRF
|
||||||
|
h57EBZltbSfvTMDBZAyhx5oZKoETDfwy5jFzf4L4PazSkvfn4qWmCnrq4HNO5Vl7
|
||||||
|
GBsW93bljsh2nfvoKDX2vBpEUe0qrZzJtRHq0ytfd6zXZ9+WFMsmhD9poADrH4hB
|
||||||
|
/UOV3uCJPybOoy/WsANQpSgJPD886zakmF+54XQ3tExKzFA1rR4HJbU26h99U5kH
|
||||||
|
346sV7/xKJLENQVIH1qsqyA1UPDZRWusABjdIPc9Racy0/MxTVE0k5lQbBvz9QSe
|
||||||
|
HZvW+ct/aZX5tjxr9JlSY7tK2I9FAgMBAAGjMDAuMAkGA1UdEwQCMAAwCwYDVR0P
|
||||||
|
BAQDAgXgMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEA
|
||||||
|
RZp/fNjoQNaO6KW0Ay0aaPW6jPrcqGjzFgeIXaw/0UaWm5jhptWtjOAILV+afIrd
|
||||||
|
4cKDg65o4xRdQYYbqmutFMAO/DeyDyMi3IL60qk0osipPDIORx5Ai2ZBQvUsGtwV
|
||||||
|
np9UwQGNO5AGeR9N5kndyldbpxaIJFhsKOV8uRSi+4PRbMH3G0kJIX6wwZU4Ri/k
|
||||||
|
3lWJQfqULH0vtMQCWSJuaYHxWYFq4AM+H/zpLwg1WG2eKVgSMWotxMRi5LOFSBbG
|
||||||
|
XuOxAb0SNBcXl6kjRYbQyHBxIJMsB1lk64g7dTJqXuYFUwmIGL/vTr6PL6EKYk65
|
||||||
|
/aWO8cvwXOrYaf9umgcqvg==
|
||||||
|
-----END CERTIFICATE-----
|
27
connector/ldap/testdata/server.key
vendored
Normal file
27
connector/ldap/testdata/server.key
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpAIBAAKCAQEA5VhguV/01oMrBIpjO59IUpF0QiE8ABcShtAuBHqaZi+NgwXI
|
||||||
|
0GtMaxJURYeexAWZbW0n70zAwWQMoceaGSqBEw38MuYxc3+C+D2s0pL35+Klpgp6
|
||||||
|
6uBzTuVZexgbFvd25Y7Idp376Cg19rwaRFHtKq2cybUR6tMrX3es12fflhTLJoQ/
|
||||||
|
aaAA6x+IQf1Dld7giT8mzqMv1rADUKUoCTw/POs2pJhfueF0N7RMSsxQNa0eByW1
|
||||||
|
NuoffVOZB9+OrFe/8SiSxDUFSB9arKsgNVDw2UVrrAAY3SD3PUWnMtPzMU1RNJOZ
|
||||||
|
UGwb8/UEnh2b1vnLf2mV+bY8a/SZUmO7StiPRQIDAQABAoIBAQDHBbKqK4MkxB8I
|
||||||
|
ia8jhk4UmPTyjjSrP1pscyv75wkltA5xrQtfEj32jKlkzRQRt2o1c4w8NbbwHAp6
|
||||||
|
OeSYAjKQfoplAS3YtMbK9XqMIc3QBPcK5/1S5gQqaw0DrR+VBpq/CvEbPm3kQUDT
|
||||||
|
JNkGgLH3X0G4KNGrniT9a7UqGJIGgdBAr7bPESiDi9wuOwfhm/9TB8LOG8wB9cn4
|
||||||
|
NcUipvjOcRxMFkyYtq056ZfGeoK2ooFe0lHi4j8sWXfII789OqN0plecAg8NGZsl
|
||||||
|
klSncpTObE6eTXo9Jncio3pftvszEctKssK7vuL6opajtppT6C5FnKLb6NIAOo7j
|
||||||
|
CPk1BRPhAoGBAPf8TMTr+l8MHRuVXEx52E1dBH46ZB8bMfvwb7cZ31Fn0EEmygCj
|
||||||
|
wP9eKZ8MKmHVBbU6CbxYQMICTTwRrw9H0tNoaZBwzWMz/JDHcACfsPKtfrX8T4UQ
|
||||||
|
wmVwbLctdC1Cbaxn1jYeSLoLfSe8IGPDnLpsMCzpRcQIgPS+gO69zr8vAoGBAOzB
|
||||||
|
254TKd2OQPnvUvmAVYGRYyTu/+ShH9fZyDJYtjhQbuxt6eqh3poneWJOW+KPlqDd
|
||||||
|
J0a8yv1pDXmCy5k1Oo8Nubt7cPI0y2z0nm5LvAaqPaFdUJs9nq9umH3svJh6du6Z
|
||||||
|
+TZ6MDU/eyJRq7Mc5SQrssziJidS3cU21b560xvLAoGBAPYpZY9Ia7Uz0iUSY5eq
|
||||||
|
j7Nj9VTT45UZKsnbRxnrvckSEyDJP1XZN3iG4Sv3KI8KpWrbHNTwif/Lxx0stKin
|
||||||
|
dDjU+Y0e3FJwRXL19lE4M68B17kQp2MAWufU7KX8oclXmoS8YmBAOZMsWmU6ErDV
|
||||||
|
eVt4j23VdaJ9inzoKhZTJcqTAoGAH9znJZsGo16lt/1ReWqgF1Ptt+bCYY6drnsM
|
||||||
|
ylnODD4m74LLXFx0jOKLH4PUMeWJLBUXWBnIZ9pfid7kb7YOL3p1aJnwVWhtiDhT
|
||||||
|
qhxfLbZznOfmFT5xwMJtm2Tk7NBueSYXuBExs7jbZX8AUJau7/NBmPlGkTxBxGzg
|
||||||
|
z0XQa4kCgYBxYBXwFpLLjBO+bMMkoVOlMDj7feCOWP9CsnKQSHYqPbmmb+8mA7pN
|
||||||
|
mIWfjSVynVe+Ncn0I5Uijbs9QDYqcfApJQ+iXeb+VGrg4QkLHHGd/5kIY28Evc6A
|
||||||
|
KVyRIuiYNmgOXGpaFpMXSw718N4U7jWW7lqUxK2rvEupFhaL52oJFQ==
|
||||||
|
-----END RSA PRIVATE KEY-----
|
Loading…
Reference in a new issue