@@ -79,6 +79,11 @@ public class KnoxLDAPServerManager {
7979 private int port ;
8080 private String baseDn ;
8181 private String bindUser ;
82+ // Secure (LDAPS) transport configuration
83+ private boolean sslEnabled ;
84+ private String sslKeystorePath ;
85+ private String sslKeystorePasswordAlias ;
86+ private List <String > sslEnabledCipherSuites ;
8287 // Collection of DNs for the proxied backend LDAP servers
8388 private Set <String > baseDns ;
8489
@@ -108,6 +113,17 @@ public void initialize(GatewayConfig config) throws Exception {
108113 this .baseDn = config .getLDAPBaseDN ();
109114 this .bindUser = config .getLDAPBindUser ();
110115
116+ // Secure (LDAPS) transport configuration. When enabled but no dedicated keystore is
117+ // configured, fall back to the gateway identity keystore so the embedded server can
118+ // reuse the gateway's own TLS material out of the box.
119+ this .sslEnabled = config .isLDAPSSLEnabled ();
120+ if (sslEnabled ) {
121+ final String configuredKeystore = config .getLDAPSSLKeystorePath ();
122+ this .sslKeystorePath = StringUtils .isNotBlank (configuredKeystore ) ? configuredKeystore : config .getIdentityKeystorePath ();
123+ this .sslKeystorePasswordAlias = config .getLDAPSSLKeystorePasswordAlias ();
124+ this .sslEnabledCipherSuites = config .getLDAPSSLEnabledCipherSuites ();
125+ }
126+
111127 createInterceptors (config );
112128
113129 // Clean up previous run if it didn't shut down cleanly
@@ -215,7 +231,11 @@ public void start() throws Exception {
215231
216232 // Create LDAP server on configured port
217233 ldapServer = new LdapServer ();
218- ldapServer .setTransports (new TcpTransport (port ));
234+ final TcpTransport transport = new TcpTransport (port );
235+ if (sslEnabled ) {
236+ configureSsl (transport );
237+ }
238+ ldapServer .setTransports (transport );
219239 ldapServer .setDirectoryService (directoryService );
220240
221241 ldapServer .start ();
@@ -280,6 +300,56 @@ private int fetchAuthenticationInterceptorIndex(final List<Interceptor> dsInterc
280300 .orElse (-1 );
281301 }
282302
303+ /**
304+ * Enable the secure (LDAPS) transport on the embedded server. The keystore holding the
305+ * server certificate and its password are resolved from the gateway configuration and
306+ * credential store; the password defaults to the gateway identity keystore password when
307+ * no dedicated alias is configured. The keystore must be in the JVM default format
308+ * (see {@code java.security.KeyStore#getDefaultType()}), which is what ApacheDS uses to
309+ * load it.
310+ */
311+ private void configureSsl (final TcpTransport transport ) throws Exception {
312+ if (StringUtils .isBlank (sslKeystorePath )) {
313+ final String reason = "no keystore configured; set " + GatewayConfig .LDAP_SSL_KEYSTORE_PATH
314+ + " or configure the gateway identity keystore" ;
315+ LOG .ldapSslConfigInvalid (reason );
316+ throw new IllegalStateException ("Cannot enable LDAPS: " + reason );
317+ }
318+
319+ final File keystore = new File (sslKeystorePath );
320+ if (!keystore .exists ()) {
321+ final String reason = "keystore file not found: " + keystore .getAbsolutePath ();
322+ LOG .ldapSslConfigInvalid (reason );
323+ throw new IllegalStateException ("Cannot enable LDAPS: " + reason );
324+ }
325+
326+ transport .setEnableSSL (true );
327+ ldapServer .setKeystoreFile (keystore .getAbsolutePath ());
328+
329+ final char [] passwordChars = resolveSslKeystorePassword ();
330+ if (passwordChars != null ) {
331+ ldapServer .setCertificatePassword (new String (passwordChars ));
332+ }
333+
334+ if (sslEnabledCipherSuites != null && !sslEnabledCipherSuites .isEmpty ()) {
335+ ldapServer .setEnabledCipherSuites (new ArrayList <>(sslEnabledCipherSuites ));
336+ }
337+
338+ LOG .ldapSslEnabled (keystore .getAbsolutePath ());
339+ }
340+
341+ /**
342+ * Resolve the password protecting the LDAPS keystore from the gateway credential store.
343+ * Uses the configured alias when set, otherwise falls back to the gateway identity
344+ * keystore password (matching the keystore-path fallback in {@link #initialize(GatewayConfig)}).
345+ */
346+ private char [] resolveSslKeystorePassword () throws Exception {
347+ if (StringUtils .isNotBlank (sslKeystorePasswordAlias )) {
348+ return aliasService .getPasswordFromAliasForGateway (sslKeystorePasswordAlias );
349+ }
350+ return aliasService .getGatewayIdentityKeystorePassword ();
351+ }
352+
283353 /**
284354 * Stop the LDAP server
285355 */
0 commit comments