diff --git a/internal/auth/ldap/repository_authenticate.go b/internal/auth/ldap/repository_authenticate.go index f417adcf77..a146926e1a 100644 --- a/internal/auth/ldap/repository_authenticate.go +++ b/internal/auth/ldap/repository_authenticate.go @@ -6,6 +6,7 @@ package ldap import ( "context" "encoding/json" + "encoding/pem" "fmt" "strings" @@ -54,6 +55,11 @@ func (r *Repository) Authenticate(ctx context.Context, authMethodId, loginName, return nil, errors.New(ctx, errors.RecordNotFound, op, fmt.Sprintf("auth method id %q not found", authMethodId)) } + var clientTLSKeyPem string + if am.ClientCertificateKey != nil { + clientTLSKeyPem = string(pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: am.ClientCertificateKey})) + } + // config cap ldap provider client, err := ldap.NewClient(ctx, &ldap.ClientConfig{ IncludeUserAttributes: true, @@ -72,7 +78,7 @@ func (r *Repository) Authenticate(ctx context.Context, authMethodId, loginName, GroupAttr: am.GroupAttr, GroupFilter: am.GroupFilter, Certificates: am.Certificates, - ClientTLSKey: string(am.ClientCertificateKey), + ClientTLSKey: clientTLSKeyPem, ClientTLSCert: am.ClientCertificate, BindDN: am.BindDn, BindPassword: am.BindPassword, diff --git a/internal/auth/ldap/repository_authenticate_test.go b/internal/auth/ldap/repository_authenticate_test.go index 665634fb69..ac1bb210c6 100644 --- a/internal/auth/ldap/repository_authenticate_test.go +++ b/internal/auth/ldap/repository_authenticate_test.go @@ -5,6 +5,7 @@ package ldap import ( "context" + "encoding/pem" "fmt" "testing" @@ -282,6 +283,44 @@ func TestRepository_authenticate(t *testing.T) { assert.Contains(err.Error(), "failed to connect") assert.Nil(got) }) + t.Run("mTLS-client-success", func(t *testing.T) { + // test for client key/cert issue reported: + // https://github.com/hashicorp/boundary/issues/3927 + tdWithMtls := testdirectory.Start(t, + testdirectory.WithMTLS(t), + testdirectory.WithDefaults(t, &testdirectory.Defaults{AllowAnonymousBind: true}), + testdirectory.WithLogger(t, logger), + ) + tdWithMtlsCerts, err := ParseCertificates(testCtx, tdWithMtls.Cert()) + require.NoError(t, err) + + testClientCert, err := ParseCertificates(testCtx, tdWithMtls.ClientCert()) + require.NoError(t, err) + testClientKeyPem := tdWithMtls.ClientKey() + block, _ := pem.Decode([]byte(testClientKeyPem)) + require.NotEmpty(t, block) + // block.Bytes + + testAmWithMtls := TestAuthMethod(t, testConn, orgDbWrapper, org.PublicId, + []string{fmt.Sprintf("ldaps://%s:%d", tdWithMtls.Host(), tdWithMtls.Port())}, + WithCertificates(testCtx, tdWithMtlsCerts...), + WithClientCertificate(testCtx, block.Bytes, testClientCert[0]), + WithDiscoverDn(testCtx), + WithEnableGroups(testCtx), + WithUserDn(testCtx, testdirectory.DefaultUserDN), + WithGroupDn(testCtx, testdirectory.DefaultGroupDN), + ) + + testAccountUsingMtls := TestAccount(t, testConn, testAmWithMtls, testLoginName) + + tdWithMtls.SetUsers(users...) + tdWithMtls.SetGroups(groups...) + tdWithMtls.SetTokenGroups(tokenGroups) + + got, err := testRepo.Authenticate(testCtx, testAmWithMtls.PublicId, testAccountUsingMtls.LoginName, testPassword) + require.NoError(t, err) + require.NotEmpty(t, got) + }) } func Test_caseInsensitiveAttributeSearch(t *testing.T) {