| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | * Portions Copyright 2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.api; |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | |
| | | throws ConfigException, InitializationException; |
| | | |
| | | |
| | | /** |
| | | * |
| | | * Verifies that an alias is defined in the scope of this Key Manager. |
| | | * |
| | | * @param alias |
| | | * The alias to check. |
| | | * @return true if the alias exists, false otherwise |
| | | */ |
| | | public boolean containsKeyWithAlias(String alias) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * |
| | | * Verifies that the keystore has at least one usable key. |
| | | * |
| | | * @return true if the keystore has at least one usable key, false otherwise |
| | | */ |
| | | public boolean containsAtLeastOneKey() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * Indicates whether the provided configuration is acceptable for |
| | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a set of <CODE>KeyManager</CODE> objects that may be used for |
| | | * interactions requiring access to a key manager. |
| | | * |
| | | * @return A set of <CODE>KeyManager</CODE> objects that may be used for |
| | | * interactions requiring access to a key manager. |
| | | * |
| | | * @throws DirectoryException If a problem occurs while attempting to obtain |
| | | * the set of key managers. |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public KeyManager[] getKeyManagers() throws DirectoryException |
| | | { |
| | | public boolean containsKeyWithAlias(String alias) { |
| | | KeyStore keyStore; |
| | | |
| | | try { |
| | | keyStore = getKeystore(); |
| | | } catch (DirectoryException e) { |
| | | return false; |
| | | } |
| | | |
| | | try { |
| | | Enumeration<String> aliases = keyStore.aliases(); |
| | | while (aliases.hasMoreElements()) { |
| | | String theAlias = aliases.nextElement(); |
| | | if (alias.equals(theAlias) && keyStore.entryInstanceOf(alias, KeyStore.PrivateKeyEntry.class)) { |
| | | return true; |
| | | } |
| | | } |
| | | } catch (KeyStoreException e) { |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | private KeyStore getKeystore() |
| | | throws DirectoryException { |
| | | KeyStore keyStore; |
| | | try |
| | | { |
| | |
| | | throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), |
| | | message, e); |
| | | } |
| | | return keyStore; |
| | | } |
| | | |
| | | try { |
| | | // Troubleshooting aid; Analyse the keystore for the presence of at least one private entry. |
| | | if (!findOneKeyEntry(keyStore)) |
| | | /** |
| | | * Retrieves a set of <CODE>KeyManager</CODE> objects that may be used for |
| | | * interactions requiring access to a key manager. |
| | | * |
| | | * @return A set of <CODE>KeyManager</CODE> objects that may be used for |
| | | * interactions requiring access to a key manager. |
| | | * |
| | | * @throws DirectoryException If a problem occurs while attempting to obtain |
| | | * the set of key managers. |
| | | */ |
| | | @Override |
| | | public KeyManager[] getKeyManagers() throws DirectoryException |
| | | { |
| | | logger.warn(INFO_NO_KEY_ENTRY_IN_KEYSTORE, keyStoreFile); |
| | | } |
| | | } |
| | | catch (Exception e) { |
| | | logger.traceException(e); |
| | | } |
| | | KeyStore keyStore = getKeystore(); |
| | | |
| | | try |
| | | { |
| | | if (! findOneKeyEntry(keyStore)) |
| | | { |
| | | // Troubleshooting message to let now of possible config error |
| | | logger.error(ERR_NO_KEY_ENTRY_IN_KEYSTORE, keyStoreFile); |
| | | } |
| | | |
| | | String keyManagerAlgorithm = KeyManagerFactory.getDefaultAlgorithm(); |
| | | KeyManagerFactory keyManagerFactory = |
| | | KeyManagerFactory.getInstance(keyManagerAlgorithm); |
| | |
| | | } |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean containsAtLeastOneKey() |
| | | { |
| | | try |
| | | { |
| | | return findOneKeyEntry(getKeystore()); |
| | | } |
| | | catch (Exception e) { |
| | | logger.traceException(e); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | private boolean findOneKeyEntry(KeyStore keyStore) throws KeyStoreException |
| | | { |
| | | Enumeration<String> aliases = keyStore.aliases(); |
| | |
| | | public void initializeConnectionHandler(HTTPConnectionHandlerCfg config) |
| | | throws ConfigException, InitializationException |
| | | { |
| | | this.enabled = config.isEnabled(); |
| | | |
| | | if (friendlyName == null) |
| | | { |
| | | friendlyName = config.dn().rdn().getAttributeValue(0).toString(); |
| | |
| | | // Configure SSL if needed. |
| | | try |
| | | { |
| | | // This call may disable the connector if wrong SSL settings |
| | | configureSSL(config); |
| | | } |
| | | catch (DirectoryException e) |
| | |
| | | |
| | | this.initConfig = config; |
| | | this.currentConfig = config; |
| | | this.enabled = this.currentConfig.isEnabled(); |
| | | } |
| | | |
| | | private String getHandlerName(HTTPConnectionHandlerCfg config) |
| | |
| | | setName(handlerName); |
| | | |
| | | boolean lastIterationFailed = false; |
| | | boolean starting = true; |
| | | |
| | | while (!shutdownRequested) |
| | | { |
| | | // If this connection handler is not enabled, then just sleep |
| | |
| | | stopHttpServer(); |
| | | } |
| | | |
| | | if (starting) |
| | | { |
| | | // This may happen if there was an initialisation error |
| | | // which led to disable the connector. |
| | | // The main thread is waiting for the connector to listen |
| | | // on its port, which will not occur yet, |
| | | // so notify here to allow the server startup to complete. |
| | | synchronized (waitListen) |
| | | { |
| | | starting = false; |
| | | waitListen.notify(); |
| | | } |
| | | } |
| | | |
| | | StaticUtils.sleep(1000); |
| | | continue; |
| | | } |
| | |
| | | DN keyMgrDN = config.getKeyManagerProviderDN(); |
| | | KeyManagerProvider<?> keyManagerProvider = |
| | | DirectoryServer.getKeyManagerProvider(keyMgrDN); |
| | | if (keyManagerProvider == null) |
| | | { |
| | | if (keyManagerProvider == null) { |
| | | logger.error(ERR_NULL_KEY_PROVIDER_MANAGER, keyMgrDN, friendlyName); |
| | | logger.warn(INFO_DISABLE_CONNECTION, friendlyName); |
| | | keyManagerProvider = new NullKeyManagerProvider(); |
| | | enabled = false; |
| | | } |
| | | else if (! keyManagerProvider.containsAtLeastOneKey()) |
| | | { |
| | | logger.error(ERR_INVALID_KEYSTORE, friendlyName); |
| | | logger.warn(INFO_DISABLE_CONNECTION, friendlyName); |
| | | enabled = false; |
| | | } |
| | | |
| | | String alias = config.getSSLCertNickname(); |
| | |
| | | } |
| | | else |
| | | { |
| | | if (! keyManagerProvider.containsKeyWithAlias(alias)) { |
| | | logger.error(ERR_KEYSTORE_DOES_NOT_CONTAIN_ALIAS, alias, friendlyName); |
| | | logger.warn(INFO_DISABLE_CONNECTION, friendlyName); |
| | | enabled = false; |
| | | } |
| | | keyManagers = |
| | | SelectableCertificateKeyManager.wrap(keyManagerProvider |
| | | .getKeyManagers(), alias); |
| | |
| | | // Configure SSL if needed. |
| | | try |
| | | { |
| | | // This call may disable the connector if wrong SSL settings |
| | | configureSSL(config); |
| | | } |
| | | catch (DirectoryException e) |
| | |
| | | { |
| | | setName(handlerName); |
| | | boolean listening = false; |
| | | boolean starting = true; |
| | | |
| | | while (!shutdownRequested) |
| | | { |
| | |
| | | logger.info(NOTE_CONNHANDLER_STOPPED_LISTENING, handlerName); |
| | | } |
| | | |
| | | if (starting) |
| | | { |
| | | // This may happen if there was an initialisation error |
| | | // which led to disable the connector. |
| | | // The main thread is waiting for the connector to listen |
| | | // on its port, which will not occur yet, |
| | | // so notify here to allow the server startup to complete. |
| | | synchronized (waitListen) |
| | | { |
| | | starting = false; |
| | | waitListen.notify(); |
| | | } |
| | | } |
| | | |
| | | StaticUtils.sleep(1000); |
| | | continue; |
| | | } |
| | |
| | | |
| | | |
| | | |
| | | private void disableAndWarnIfUseSSL(LDAPConnectionHandlerCfg config) |
| | | { |
| | | if (config.isUseSSL()) |
| | | { |
| | | logger.warn(INFO_DISABLE_CONNECTION, friendlyName); |
| | | enabled = false; |
| | | } |
| | | } |
| | | |
| | | private SSLContext createSSLContext(LDAPConnectionHandlerCfg config) |
| | | throws DirectoryException |
| | | { |
| | |
| | | .getKeyManagerProvider(keyMgrDN); |
| | | if (keyManagerProvider == null) |
| | | { |
| | | if (config.isUseSSL()) { |
| | | logger.warn(INFO_NULL_KEY_PROVIDER_MANAGER, keyMgrDN, friendlyName); |
| | | } |
| | | logger.error(ERR_NULL_KEY_PROVIDER_MANAGER, keyMgrDN, friendlyName); |
| | | disableAndWarnIfUseSSL(config); |
| | | keyManagerProvider = new NullKeyManagerProvider(); |
| | | // The SSL connection is unusable without a key manager provider |
| | | } |
| | | else if (! keyManagerProvider.containsAtLeastOneKey()) |
| | | { |
| | | logger.error(ERR_INVALID_KEYSTORE, friendlyName); |
| | | disableAndWarnIfUseSSL(config); |
| | | } |
| | | |
| | | String alias = config.getSSLCertNickname(); |
| | |
| | | } |
| | | else |
| | | { |
| | | if (!keyManagerProvider.containsKeyWithAlias(alias)) |
| | | { |
| | | logger.error(ERR_KEYSTORE_DOES_NOT_CONTAIN_ALIAS, alias, friendlyName); |
| | | disableAndWarnIfUseSSL(config); |
| | | } |
| | | keyManagers = SelectableCertificateKeyManager.wrap( |
| | | keyManagerProvider.getKeyManagers(), alias, friendlyName); |
| | | } |
| | |
| | | } |
| | | } |
| | | } |
| | | logger.warn(INFO_KEYSTORE_DOES_NOT_CONTAIN_ALIAS, keyType, alias, componentName); |
| | | logger.warn(INFO_KEYSTORE_DOES_NOT_CONTAIN_ALIAS, componentName, keyType, alias); |
| | | return null; |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | logger.warn(INFO_KEYSTORE_DOES_NOT_CONTAIN_ALIAS, keyType, alias, componentName); |
| | | logger.warn(INFO_KEYSTORE_DOES_NOT_CONTAIN_ALIAS, componentName, keyType, alias); |
| | | return null; |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | logger.warn(INFO_KEYSTORE_DOES_NOT_CONTAIN_ALIAS, keyType, alias, componentName); |
| | | logger.warn(INFO_KEYSTORE_DOES_NOT_CONTAIN_ALIAS, componentName, keyType, alias); |
| | | return null; |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | logger.warn(INFO_KEYSTORE_DOES_NOT_CONTAIN_ALIAS, keyType, alias, componentName); |
| | | logger.warn(INFO_KEYSTORE_DOES_NOT_CONTAIN_ALIAS, componentName, keyType, alias); |
| | | return null; |
| | | } |
| | | |
| | |
| | | definition '%s' is invalid because the range '%s' is missing the minus |
| | | ERR_CHARSET_VALIDATOR_SHORT_RANGE_635=The provided character range \ |
| | | definition '%s' is invalid because the range '%s' is too short |
| | | INFO_KEYSTORE_DOES_NOT_CONTAIN_ALIAS_636=The %s key with alias '%s' was not found for '%s' |
| | | INFO_NO_KEY_ENTRY_IN_KEYSTORE_637=There is no key entry in keystore %s |
| | | ERR_NO_KEY_ENTRY_IN_KEYSTORE_636=There is no private key entry in keystore %s |
| | | INFO_KEYSTORE_DOES_NOT_CONTAIN_ALIAS_637=handshake for '%s': cipher is expecting key %s to be of type %s |
| | |
| | | whitespace character at the current position: %s |
| | | ERR_GSER_NO_VALID_IDENTIFIEDCHOICE_1523=The GSER value does not \ |
| | | contain a valid IdentifiedChoiceValue at the current position: %s |
| | | INFO_NULL_KEY_PROVIDER_MANAGER_1524=The keystore %s seems to be missing, \ |
| | | this may render the secure port inoperative for '%s' |
| | | ERR_NULL_KEY_PROVIDER_MANAGER_1524=The keystore %s seems to be missing, \ |
| | | this may render the secure port inoperative for '%s'. \ |
| | | Verify the keystore setting in the configuration. |
| | | ERR_PROXYAUTH_AUTHZ_NOT_PERMITTED_1525=Authorization as '%s' specified in \ |
| | | the proxied authorization control is not permitted |
| | | ERR_KEYSTORE_DOES_NOT_CONTAIN_ALIAS_1526=The key with alias '%s' was not found for '%s'. \ |
| | | Verify that the keystore is properly configured |
| | | ERR_INVALID_KEYSTORE_1527=No usable key was found for '%s'. Verify the keystore content |
| | | INFO_DISABLE_CONNECTION_1528=Disabling %s |