Пример #1
0
 private void configureSSL(HTTPConnectionHandlerCfg config) throws DirectoryException {
   protocol = config.isUseSSL() ? "HTTPS" : "HTTP";
   if (config.isUseSSL()) {
     sslEngineConfigurator = createSSLEngineConfigurator(config);
   } else {
     sslEngineConfigurator = null;
   }
 }
Пример #2
0
  private ConnectionHandlerDescriptor getConnectionHandler(
      ConnectionHandlerCfg connHandler, String name) throws OpenDsException {
    SortedSet<InetAddress> addresses = new TreeSet<InetAddress>(getInetAddressComparator());
    int port;

    ConnectionHandlerDescriptor.Protocol protocol;

    ConnectionHandlerDescriptor.State state =
        connHandler.isEnabled()
            ? ConnectionHandlerDescriptor.State.ENABLED
            : ConnectionHandlerDescriptor.State.DISABLED;

    if (connHandler instanceof LDAPConnectionHandlerCfg) {
      LDAPConnectionHandlerCfg ldap = (LDAPConnectionHandlerCfg) connHandler;
      if (ldap.isUseSSL()) {
        protocol = ConnectionHandlerDescriptor.Protocol.LDAPS;
      } else if (ldap.isAllowStartTLS()) {
        protocol = ConnectionHandlerDescriptor.Protocol.LDAP_STARTTLS;
      } else {
        protocol = ConnectionHandlerDescriptor.Protocol.LDAP;
      }
      addAll(addresses, ldap.getListenAddress());
      port = ldap.getListenPort();
    } else if (connHandler instanceof HTTPConnectionHandlerCfg) {
      HTTPConnectionHandlerCfg http = (HTTPConnectionHandlerCfg) connHandler;
      if (http.isUseSSL()) {
        protocol = ConnectionHandlerDescriptor.Protocol.HTTPS;
      } else {
        protocol = ConnectionHandlerDescriptor.Protocol.HTTP;
      }
      addAll(addresses, http.getListenAddress());
      port = http.getListenPort();
    } else if (connHandler instanceof JMXConnectionHandlerCfg) {
      JMXConnectionHandlerCfg jmx = (JMXConnectionHandlerCfg) connHandler;
      if (jmx.isUseSSL()) {
        protocol = ConnectionHandlerDescriptor.Protocol.JMXS;
      } else {
        protocol = ConnectionHandlerDescriptor.Protocol.JMX;
      }
      addAll(addresses, jmx.getListenAddress());
      port = jmx.getListenPort();
    } else if (connHandler instanceof LDIFConnectionHandlerCfg) {
      protocol = ConnectionHandlerDescriptor.Protocol.LDIF;
      port = -1;
    } else if (connHandler instanceof SNMPConnectionHandlerCfg) {
      protocol = ConnectionHandlerDescriptor.Protocol.SNMP;
      SNMPConnectionHandlerCfg snmp = (SNMPConnectionHandlerCfg) connHandler;
      addAll(addresses, snmp.getListenAddress());
      port = snmp.getListenPort();
    } else {
      protocol = ConnectionHandlerDescriptor.Protocol.OTHER;
      port = -1;
    }
    Set<CustomSearchResult> emptySet = Collections.emptySet();
    return new ConnectionHandlerDescriptor(addresses, port, protocol, state, name, emptySet);
  }
Пример #3
0
 private String getHandlerName(HTTPConnectionHandlerCfg config) {
   StringBuilder nameBuffer = new StringBuilder();
   nameBuffer.append(friendlyName);
   for (InetAddress a : config.getListenAddress()) {
     nameBuffer.append(" ");
     nameBuffer.append(a.getHostAddress());
   }
   nameBuffer.append(" port ");
   nameBuffer.append(config.getListenPort());
   return nameBuffer.toString();
 }
Пример #4
0
  private SSLEngineConfigurator createSSLEngineConfigurator(HTTPConnectionHandlerCfg config)
      throws DirectoryException {
    if (!config.isUseSSL()) {
      return null;
    }

    try {
      SSLContext sslContext = createSSLContext(config);
      SSLEngineConfigurator configurator = new SSLEngineConfigurator(sslContext);
      configurator.setClientMode(false);

      // configure with defaults from the JVM
      final SSLEngine defaults = sslContext.createSSLEngine();
      configurator.setEnabledProtocols(defaults.getEnabledProtocols());
      configurator.setEnabledCipherSuites(defaults.getEnabledCipherSuites());

      final Set<String> protocols = config.getSSLProtocol();
      if (!protocols.isEmpty()) {
        configurator.setEnabledProtocols(protocols.toArray(new String[protocols.size()]));
      }

      final Set<String> ciphers = config.getSSLCipherSuite();
      if (!ciphers.isEmpty()) {
        configurator.setEnabledCipherSuites(ciphers.toArray(new String[ciphers.size()]));
      }

      switch (config.getSSLClientAuthPolicy()) {
        case DISABLED:
          configurator.setNeedClientAuth(false);
          configurator.setWantClientAuth(false);
          break;
        case REQUIRED:
          configurator.setNeedClientAuth(true);
          configurator.setWantClientAuth(true);
          break;
        case OPTIONAL:
        default:
          configurator.setNeedClientAuth(false);
          configurator.setWantClientAuth(true);
          break;
      }

      return configurator;
    } catch (Exception e) {
      logger.traceException(e);
      ResultCode resCode = DirectoryServer.getServerErrorResultCode();
      throw new DirectoryException(
          resCode, ERR_CONNHANDLER_SSL_CANNOT_INITIALIZE.get(getExceptionMessage(e)), e);
    }
  }
Пример #5
0
  @Override
  public boolean isConfigurationAcceptable(
      ConnectionHandlerCfg configuration, List<LocalizableMessage> unacceptableReasons) {
    HTTPConnectionHandlerCfg config = (HTTPConnectionHandlerCfg) configuration;

    if (currentConfig == null || (!this.enabled && config.isEnabled())) {
      // Attempt to bind to the listen port on all configured addresses to
      // verify whether the connection handler will be able to start.
      LocalizableMessage errorMessage =
          checkAnyListenAddressInUse(
              config.getListenAddress(),
              config.getListenPort(),
              config.isAllowTCPReuseAddress(),
              config.dn());
      if (errorMessage != null) {
        unacceptableReasons.add(errorMessage);
        return false;
      }
    }

    if (config.isEnabled() && config.isUseSSL()) {
      try {
        createSSLEngineConfigurator(config);
      } catch (DirectoryException e) {
        logger.traceException(e);
        unacceptableReasons.add(e.getMessageObject());
        return false;
      }
    }

    return true;
  }
Пример #6
0
  private SSLContext createSSLContext(HTTPConnectionHandlerCfg config) throws Exception {
    if (!config.isUseSSL()) {
      return null;
    }

    DN keyMgrDN = config.getKeyManagerProviderDN();
    KeyManagerProvider<?> keyManagerProvider = DirectoryServer.getKeyManagerProvider(keyMgrDN);
    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;
    }

    final SortedSet<String> aliases = new TreeSet<>(config.getSSLCertNickname());
    final KeyManager[] keyManagers;
    if (aliases.isEmpty()) {
      keyManagers = keyManagerProvider.getKeyManagers();
    } else {
      final Iterator<String> it = aliases.iterator();
      while (it.hasNext()) {
        if (!keyManagerProvider.containsKeyWithAlias(it.next())) {
          logger.error(ERR_KEYSTORE_DOES_NOT_CONTAIN_ALIAS, aliases, friendlyName);
          it.remove();
        }
      }
      if (aliases.isEmpty()) {
        logger.warn(INFO_DISABLE_CONNECTION, friendlyName);
        enabled = false;
      }
      keyManagers =
          SelectableCertificateKeyManager.wrap(keyManagerProvider.getKeyManagers(), aliases);
    }

    DN trustMgrDN = config.getTrustManagerProviderDN();
    TrustManagerProvider<?> trustManagerProvider =
        DirectoryServer.getTrustManagerProvider(trustMgrDN);
    if (trustManagerProvider == null) {
      trustManagerProvider = new NullTrustManagerProvider();
    }

    SSLContext sslContext = SSLContext.getInstance(SSL_CONTEXT_INSTANCE_NAME);
    sslContext.init(keyManagers, trustManagerProvider.getTrustManagers(), null);
    return sslContext;
  }
Пример #7
0
  @Override
  public ConfigChangeResult applyConfigurationChange(HTTPConnectionHandlerCfg config) {
    final ConfigChangeResult ccr = new ConfigChangeResult();

    if (anyChangeRequiresRestart(config)) {
      ccr.setAdminActionRequired(true);
      ccr.addMessage(ERR_CONNHANDLER_CONFIG_CHANGES_REQUIRE_RESTART.get("HTTP"));
    }

    // Reconfigure SSL if needed.
    try {
      configureSSL(config);
    } catch (DirectoryException e) {
      logger.traceException(e);
      ccr.setResultCode(e.getResultCode());
      ccr.addMessage(e.getMessageObject());
      return ccr;
    }

    if (config.isEnabled() && this.currentConfig.isEnabled() && isListening()) {
      // Server was running and will still be running if the "enabled" was flipped,
      // leave it to the stop / start server to handle it.
      if (!this.currentConfig.isKeepStats() && config.isKeepStats()) {
        // It must now keep stats while it was not previously.
        setHttpStatsProbe(this.httpServer);
      } else if (this.currentConfig.isKeepStats()
          && !config.isKeepStats()
          && this.httpProbe != null) {
        // It must NOT keep stats anymore.
        getHttpConfig(this.httpServer).removeProbes(this.httpProbe);
        this.httpProbe = null;
      }
    }

    this.initConfig = config;
    this.currentConfig = config;
    this.enabled = this.currentConfig.isEnabled();

    return ccr;
  }
Пример #8
0
  private HttpServer createHttpServer() {
    final HttpServer server = new HttpServer();

    final int requestSize = (int) currentConfig.getMaxRequestSize();
    final ServerConfiguration serverConfig = server.getServerConfiguration();
    serverConfig.setMaxBufferedPostSize(requestSize);
    serverConfig.setMaxFormPostSize(requestSize);
    serverConfig.setDefaultQueryEncoding(Charsets.UTF8_CHARSET);

    if (keepStats()) {
      setHttpStatsProbe(server);
    }

    // Configure the network listener
    final NetworkListener listener =
        new NetworkListener(
            "Rest2LDAP", NetworkListener.DEFAULT_NETWORK_HOST, initConfig.getListenPort());
    server.addListener(listener);

    // Configure the network transport
    final TCPNIOTransport transport = listener.getTransport();
    transport.setReuseAddress(currentConfig.isAllowTCPReuseAddress());
    transport.setKeepAlive(currentConfig.isUseTCPKeepAlive());
    transport.setTcpNoDelay(currentConfig.isUseTCPNoDelay());
    transport.setWriteTimeout(currentConfig.getMaxBlockedWriteTimeLimit(), TimeUnit.MILLISECONDS);

    final int bufferSize = (int) currentConfig.getBufferSize();
    transport.setReadBufferSize(bufferSize);
    transport.setWriteBufferSize(bufferSize);
    transport.setIOStrategy(SameThreadIOStrategy.getInstance());

    final int numRequestHandlers =
        getNumRequestHandlers(currentConfig.getNumRequestHandlers(), friendlyName);
    transport.setSelectorRunnersCount(numRequestHandlers);
    transport.setServerConnectionBackLog(currentConfig.getAcceptBacklog());

    // Configure SSL
    if (sslEngineConfigurator != null) {
      listener.setSecure(true);
      listener.setSSLEngineConfig(sslEngineConfigurator);
    }

    return server;
  }
Пример #9
0
  @Override
  public void initializeConnectionHandler(HTTPConnectionHandlerCfg config)
      throws ConfigException, InitializationException {
    this.enabled = config.isEnabled();

    if (friendlyName == null) {
      friendlyName = config.dn().rdn().getAttributeValue(0).toString();
    }

    int listenPort = config.getListenPort();
    for (InetAddress a : config.getListenAddress()) {
      listeners.add(new HostPort(a.getHostAddress(), listenPort));
    }

    handlerName = getHandlerName(config);

    // Configure SSL if needed.
    try {
      // This call may disable the connector if wrong SSL settings
      configureSSL(config);
    } catch (DirectoryException e) {
      logger.traceException(e);
      throw new InitializationException(e.getMessageObject());
    }

    // Create and register monitors.
    statTracker = new HTTPStatistics(handlerName + " Statistics");
    DirectoryServer.registerMonitorProvider(statTracker);

    connMonitor = new ClientConnectionMonitorProvider(this);
    DirectoryServer.registerMonitorProvider(connMonitor);

    // Register this as a change listener.
    config.addHTTPChangeListener(this);

    this.initConfig = config;
    this.currentConfig = config;
  }
Пример #10
0
  @Override
  public void finalizeConnectionHandler(LocalizableMessage finalizeReason) {
    shutdownRequested = true;
    // Unregister this as a change listener.
    currentConfig.removeHTTPChangeListener(this);

    if (connMonitor != null) {
      DirectoryServer.deregisterMonitorProvider(connMonitor);
    }

    if (statTracker != null) {
      DirectoryServer.deregisterMonitorProvider(statTracker);
    }
  }
Пример #11
0
  @Override
  public void run() {
    setName(handlerName);

    boolean lastIterationFailed = false;
    boolean starting = true;

    while (!shutdownRequested) {
      // If this connection handler is not enabled, then just sleep for a bit and check again.
      if (!this.enabled) {
        if (isListening()) {
          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;
      }

      if (isListening()) {
        // If already listening, then sleep for a bit and check again.
        StaticUtils.sleep(1000);
        continue;
      }

      try {
        // At this point, the connection Handler either started correctly or failed
        // to start but the start process should be notified and resume its work in any cases.
        synchronized (waitListen) {
          waitListen.notify();
        }

        // If we have gotten here, then we are about to start listening
        // for the first time since startup or since we were previously disabled.
        // Start the embedded HTTP server
        startHttpServer();
        lastIterationFailed = false;
      } catch (Exception e) {
        // Clean up the messed up HTTP server
        cleanUpHttpServer();

        // Error + alert about the horked config
        logger.traceException(e);
        logger.error(
            ERR_CONNHANDLER_CANNOT_ACCEPT_CONNECTION,
            friendlyName,
            currentConfig.dn(),
            getExceptionMessage(e));

        if (lastIterationFailed) {
          // The last time through the accept loop we also encountered a failure.
          // Rather than enter a potential infinite loop of failures,
          // disable this acceptor and log an error.
          LocalizableMessage message =
              ERR_CONNHANDLER_CONSECUTIVE_ACCEPT_FAILURES.get(
                  friendlyName, currentConfig.dn(), stackTraceToSingleLineString(e));
          logger.error(message);

          DirectoryServer.sendAlertNotification(
              this, ALERT_TYPE_HTTP_CONNECTION_HANDLER_CONSECUTIVE_FAILURES, message);
          this.enabled = false;
        } else {
          lastIterationFailed = true;
        }
      }
    }

    // Initiate shutdown
    stopHttpServer();
  }
Пример #12
0
 /**
  * Indicates whether this connection handler should maintain usage statistics.
  *
  * @return <CODE>true</CODE> if this connection handler should maintain usage statistics, or
  *     <CODE>false</CODE> if not.
  */
 public boolean keepStats() {
   return currentConfig.isKeepStats();
 }
Пример #13
0
 @Override
 public DN getComponentEntryDN() {
   return currentConfig.dn();
 }
Пример #14
0
 private boolean anyChangeRequiresRestart(HTTPConnectionHandlerCfg newCfg) {
   return !equals(newCfg.getListenPort(), initConfig.getListenPort())
       || !Objects.equals(newCfg.getListenAddress(), initConfig.getListenAddress())
       || !equals(newCfg.getMaxRequestSize(), currentConfig.getMaxRequestSize())
       || !equals(newCfg.isAllowTCPReuseAddress(), currentConfig.isAllowTCPReuseAddress())
       || !equals(newCfg.isUseTCPKeepAlive(), currentConfig.isUseTCPKeepAlive())
       || !equals(newCfg.isUseTCPNoDelay(), currentConfig.isUseTCPNoDelay())
       || !equals(
           newCfg.getMaxBlockedWriteTimeLimit(), currentConfig.getMaxBlockedWriteTimeLimit())
       || !equals(newCfg.getBufferSize(), currentConfig.getBufferSize())
       || !equals(newCfg.getAcceptBacklog(), currentConfig.getAcceptBacklog())
       || !equals(newCfg.isUseSSL(), currentConfig.isUseSSL())
       || !Objects.equals(
           newCfg.getKeyManagerProviderDN(), currentConfig.getKeyManagerProviderDN())
       || !Objects.equals(newCfg.getSSLCertNickname(), currentConfig.getSSLCertNickname())
       || !Objects.equals(
           newCfg.getTrustManagerProviderDN(), currentConfig.getTrustManagerProviderDN())
       || !Objects.equals(newCfg.getSSLProtocol(), currentConfig.getSSLProtocol())
       || !Objects.equals(newCfg.getSSLCipherSuite(), currentConfig.getSSLCipherSuite())
       || !Objects.equals(newCfg.getSSLClientAuthPolicy(), currentConfig.getSSLClientAuthPolicy());
 }