public void start() { final Xnio xnio; try { // Do what org.jboss.as.remoting.XnioUtil does xnio = Xnio.getInstance( null, Module.getModuleFromCallerModuleLoader( ModuleIdentifier.fromString("org.jboss.xnio.nio")) .getClassLoader()); } catch (Exception e) { throw new IllegalStateException(e.getLocalizedMessage()); } try { // TODO make this configurable worker = xnio.createWorker( OptionMap.builder() .set(Options.WORKER_IO_THREADS, 4) .set(Options.CONNECTION_HIGH_WATER, 1000000) .set(Options.CONNECTION_LOW_WATER, 1000000) .set(Options.WORKER_TASK_CORE_THREADS, 10) .set(Options.WORKER_TASK_MAX_THREADS, 12) .set(Options.TCP_NODELAY, true) .set(Options.CORK, true) .getMap()); Builder serverOptionsBuilder = OptionMap.builder().set(Options.TCP_NODELAY, true).set(Options.REUSE_ADDRESSES, true); ChannelListener acceptListener = ChannelListeners.openListenerAdapter(openListener); if (httpAddress != null) { normalServer = worker.createStreamConnectionServer( httpAddress, acceptListener, serverOptionsBuilder.getMap()); normalServer.resumeAccepts(); } if (secureAddress != null) { SSLContext sslContext = securityRealm.getSSLContext(); Set<AuthMechanism> supportedMechanisms = securityRealm.getSupportedAuthenticationMechanisms(); if (supportedMechanisms.contains(AuthMechanism.CLIENT_CERT)) { if (supportedMechanisms.contains(AuthMechanism.DIGEST) || supportedMechanisms.contains(AuthMechanism.PLAIN)) { // Username / Password auth is possible so don't mandate a client certificate. serverOptionsBuilder.set(SSL_CLIENT_AUTH_MODE, REQUESTED); } else { serverOptionsBuilder.set(SSL_CLIENT_AUTH_MODE, REQUIRED); } } OptionMap secureOptions = serverOptionsBuilder.getMap(); XnioSsl xnioSsl = new JsseXnioSsl(worker.getXnio(), secureOptions, sslContext); secureServer = xnioSsl.createSslConnectionServer(worker, secureAddress, acceptListener, secureOptions); secureServer.resumeAccepts(); } } catch (IOException e) { throw new RuntimeException(e); } }
private static HttpHandler secureDomainAccess( final HttpHandler domainHandler, final SecurityRealm securityRealm) { RealmIdentityManager rim = new RealmIdentityManager(securityRealm); List<AuthenticationMechanism> undertowMechanisms; if (securityRealm != null) { Set<AuthMechanism> mechanisms = securityRealm.getSupportedAuthenticationMechanisms(); undertowMechanisms = new ArrayList<AuthenticationMechanism>(mechanisms.size()); undertowMechanisms.add(wrap(new CachedAuthenticatedSessionMechanism(), null)); for (AuthMechanism current : mechanisms) { switch (current) { case KERBEROS: undertowMechanisms.add( wrap( new GSSAPIAuthenticationMechanism(new ServerSubjectFactory(securityRealm, rim)), current)); break; case CLIENT_CERT: undertowMechanisms.add(wrap(new ClientCertAuthenticationMechanism(), current)); break; case DIGEST: List<DigestAlgorithm> digestAlgorithms = Collections.singletonList(DigestAlgorithm.MD5); List<DigestQop> digestQops = Collections.singletonList(DigestQop.AUTH); undertowMechanisms.add( wrap( new DigestAuthenticationMechanism( digestAlgorithms, digestQops, securityRealm.getName(), "/management", new SimpleNonceManager()), current)); break; case PLAIN: undertowMechanisms.add( wrap(new BasicAuthenticationMechanism(securityRealm.getName()), current)); break; case LOCAL: break; } } } else { undertowMechanisms = Collections.singletonList(wrap(new AnonymousMechanism(), null)); } // If the only mechanism is the cached mechanism then no need to add these. HttpHandler current = domainHandler; current = new AuthenticationCallHandler(current); // Currently the security handlers are being added after a PATH handler so we know // authentication is required by // this point. current = new AuthenticationConstraintHandler(current); current = new AuthenticationMechanismsHandler(current, undertowMechanisms); return new SecurityInitialHandler(AuthenticationMode.PRO_ACTIVE, rim, current); }
private static HttpHandler secureDomainAccess( final HttpHandler domainHandler, final SecurityRealm securityRealm) { if (securityRealm != null) { Set<AuthMechanism> mechanisms = securityRealm.getSupportedAuthenticationMechanisms(); List<AuthenticationMechanism> undertowMechanisms = new ArrayList<AuthenticationMechanism>(mechanisms.size()); undertowMechanisms.add(wrap(new CachedAuthenticatedSessionMechanism(), null)); for (AuthMechanism current : mechanisms) { switch (current) { case CLIENT_CERT: undertowMechanisms.add(wrap(new ClientCertAuthenticationMechanism(), current)); break; case DIGEST: List<DigestAlgorithm> digestAlgorithms = Collections.singletonList(DigestAlgorithm.MD5); List<DigestQop> digestQops = Collections.emptyList(); undertowMechanisms.add( wrap( new DigestAuthenticationMechanism( digestAlgorithms, digestQops, securityRealm.getName(), "/management", new SimpleNonceManager()), current)); break; case PLAIN: undertowMechanisms.add( wrap(new BasicAuthenticationMechanism(securityRealm.getName()), current)); break; } } if (undertowMechanisms.size() > 1) { // If the only mechanism is the cached mechanism then no need to add these. HttpHandler current = domainHandler; current = new AuthenticationCallHandler(current); // Currently the security handlers are being added after a PATH handler so we know // authentication is required by // this point. current = new AuthenticationConstraintHandler(current); current = new AuthenticationMechanismsHandler(current, undertowMechanisms); current = new ConnectionAuthenticationCacheHandler(current); return new SecurityInitialHandler( AuthenticationMode.PRO_ACTIVE, new RealmIdentityManager(securityRealm), current); } // TODO - If there were no mechanisms to begin with requests should be represented as an // anonymous user. // If there were mechanisms but none suitable for HTTP reject all requests. } return domainHandler; }
private AuthorizingCallbackHandler getAuthorizingCallbackHandler(final String realmName) { SecurityRealm realm; if (TEST_REALM.equals(realmName)) { realm = securityRealm; } else { ServiceContainer container = getContainer(); ServiceController<?> service = container.getRequiredService(SecurityRealm.ServiceUtil.createServiceName(realmName)); realm = (SecurityRealm) service.getValue(); } return realm.getAuthorizingCallbackHandler(AuthMechanism.PLAIN); }
public void start(HttpServer httpServer, SecurityRealm securityRealm) { HttpContext context = httpServer.createContext(DOMAIN_API_CONTEXT, this); if (securityRealm != null) { DomainCallbackHandler callbackHandler = securityRealm.getCallbackHandler(); Class[] supportedCallbacks = callbackHandler.getSupportedCallbacks(); if (DigestAuthenticator.requiredCallbacksSupported(supportedCallbacks)) { context.setAuthenticator( new DigestAuthenticator( callbackHandler, securityRealm.getName(), contains(DigestHashCallback.class, supportedCallbacks))); } else if (BasicAuthenticator.requiredCallbacksSupported(supportedCallbacks)) { context.setAuthenticator(new BasicAuthenticator(callbackHandler, securityRealm.getName())); } } }
/** * Connect and register at the remote domain controller. * * @return connection the established connection * @throws IOException */ protected Connection openConnection() throws IOException { // Perhaps this can just be done once? CallbackHandler callbackHandler = null; SSLContext sslContext = null; if (realm != null) { sslContext = realm.getSSLContext(); CallbackHandlerFactory handlerFactory = realm.getSecretCallbackHandlerFactory(); if (handlerFactory != null) { String username = this.username != null ? this.username : localHostName; callbackHandler = handlerFactory.getCallbackHandler(username); } } final ProtocolConnectionConfiguration config = ProtocolConnectionConfiguration.copy(configuration); config.setCallbackHandler(callbackHandler); config.setSslContext(sslContext); config.setUri(uri); // Connect return ProtocolConnectionUtils.connectSync(config); }
private static void setupOpenListener( HttpOpenListener listener, ModelController modelController, ConsoleMode consoleMode, String consoleSlot, ControlledProcessStateService controlledProcessStateService, int securePort, SecurityRealm securityRealm, final ChannelUpgradeHandler upgradeHandler) { CanonicalPathHandler canonicalPathHandler = new CanonicalPathHandler(); listener.setRootHandler(canonicalPathHandler); PathHandler pathHandler = new PathHandler(); HttpHandler current = pathHandler; if (upgradeHandler != null) { upgradeHandler.setNonUpgradeHandler(current); current = upgradeHandler; } if (securePort > 0) { current = new SinglePortConfidentialityHandler(current, securePort); } // caching handler, used for static resources current = new CacheHandler( new DirectBufferCache( 1024, 1024 * 10, 1024 * 1000, BufferAllocator.BYTE_BUFFER_ALLOCATOR), current); current = new SimpleErrorPageHandler(current); canonicalPathHandler.setNext(current); ResourceHandlerDefinition consoleHandler = null; try { consoleHandler = consoleMode.createConsoleHandler(consoleSlot); } catch (ModuleLoadException e) { ROOT_LOGGER.consoleModuleNotFound(consoleSlot == null ? "main" : consoleSlot); } try { pathHandler.addPrefixPath( ErrorContextHandler.ERROR_CONTEXT, ErrorContextHandler.createErrorContext(consoleSlot)); } catch (ModuleLoadException e) { ROOT_LOGGER.errorContextModuleNotFound(consoleSlot == null ? "main" : consoleSlot); } ManagementRootConsoleRedirectHandler rootConsoleRedirectHandler = new ManagementRootConsoleRedirectHandler(consoleHandler); DomainApiCheckHandler domainApiHandler = new DomainApiCheckHandler(modelController, controlledProcessStateService); pathHandler.addPrefixPath("/", rootConsoleRedirectHandler); if (consoleHandler != null) { HttpHandler readinessHandler = new RedirectReadinessHandler( securityRealm, consoleHandler.getHandler(), ErrorContextHandler.ERROR_CONTEXT); pathHandler.addPrefixPath(consoleHandler.getContext(), readinessHandler); } HttpHandler readinessHandler = new DmrFailureReadinessHandler( securityRealm, secureDomainAccess(domainApiHandler, securityRealm), ErrorContextHandler.ERROR_CONTEXT); pathHandler.addPrefixPath(DomainApiCheckHandler.PATH, readinessHandler); pathHandler.addExactPath("management-upload", readinessHandler); if (securityRealm != null) { pathHandler.addPrefixPath(LogoutHandler.PATH, new LogoutHandler(securityRealm.getName())); } }
public static ManagementHttpServer create( InetSocketAddress bindAddress, InetSocketAddress secureBindAddress, int backlog, ModelController modelController, SecurityRealm securityRealm, ControlledProcessStateService controlledProcessStateService, ConsoleMode consoleMode, String consoleSlot, final ChannelUpgradeHandler upgradeHandler, ManagementHttpRequestProcessor managementHttpRequestProcessor, Collection<String> allowedOrigins) throws IOException, StartException { SSLContext sslContext = null; SslClientAuthMode sslClientAuthMode = null; if (secureBindAddress != null) { sslContext = securityRealm.getSSLContext(); if (sslContext == null) { throw ROOT_LOGGER.sslRequestedNoSslContext(); } Set<AuthMechanism> supportedMechanisms = securityRealm.getSupportedAuthenticationMechanisms(); if (supportedMechanisms.contains(AuthMechanism.CLIENT_CERT)) { if (supportedMechanisms.contains(AuthMechanism.DIGEST) || supportedMechanisms.contains(AuthMechanism.PLAIN)) { // Username / Password auth is possible so don't mandate a client certificate. sslClientAuthMode = REQUESTED; } else { sslClientAuthMode = REQUIRED; } } } HttpOpenListener openListener = new HttpOpenListener( new ByteBufferSlicePool(BufferAllocator.DIRECT_BYTE_BUFFER_ALLOCATOR, 4096, 10 * 4096)); int secureRedirectPort = secureBindAddress != null ? secureBindAddress.getPort() : -1; // WFLY-2870 -- redirect not supported if bindAddress and secureBindAddress are using different // InetAddress boolean redirectSupported = (bindAddress == null || secureBindAddress == null || bindAddress.getAddress().equals(secureBindAddress.getAddress())); if (!redirectSupported && secureRedirectPort > 0) { HttpServerLogger.ROOT_LOGGER.httpsRedirectNotSupported( bindAddress.getAddress(), secureBindAddress.getAddress()); secureRedirectPort = -1; } setupOpenListener( openListener, modelController, consoleMode, consoleSlot, controlledProcessStateService, secureRedirectPort, securityRealm, upgradeHandler, managementHttpRequestProcessor, allowedOrigins); return new ManagementHttpServer( openListener, bindAddress, secureBindAddress, sslContext, sslClientAuthMode); }
@Override public synchronized void start(StartContext context) throws StartException { super.start(context); SecurityRealm realm = securityRealm.getOptionalValue(); // TODO: SSL support for the client // TODO: wire up idle timeout when new version of undertow arrives final ModCluster.Builder modClusterBuilder; final XnioWorker worker = workerInjectedValue.getValue(); if (realm == null) { modClusterBuilder = ModCluster.builder(worker); } else { SSLContext sslContext = realm.getSSLContext(); OptionMap.Builder builder = OptionMap.builder(); builder.set(Options.USE_DIRECT_BUFFERS, true); OptionMap combined = builder.getMap(); XnioSsl xnioSsl = new UndertowXnioSsl(worker.getXnio(), combined, sslContext); modClusterBuilder = ModCluster.builder(worker, UndertowClient.getInstance(), xnioSsl); } modClusterBuilder .setHealthCheckInterval(healthCheckInterval) .setMaxRequestTime(maxRequestTime) .setCacheConnections(cachedConnections) .setQueueNewRequests(requestQueueSize > 0) .setRequestQueueSize(requestQueueSize) .setRemoveBrokenNodes(removeBrokenNodes) .setTtl(connectionIdleTimeout) .setMaxConnections(connectionsPerThread) .setUseAlias(useAlias); modCluster = modClusterBuilder.build(); MCMPConfig.Builder builder = MCMPConfig.builder(); InetAddress multicastAddress = advertiseSocketBinding.getValue().getMulticastAddress(); if (multicastAddress == null) { throw UndertowLogger.ROOT_LOGGER.advertiseSocketBindingRequiresMulticastAddress(); } if (advertiseFrequency > 0) { builder .enableAdvertise() .setAdvertiseAddress( advertiseSocketBinding.getValue().getSocketAddress().getAddress().getHostAddress()) .setAdvertiseGroup(multicastAddress.getHostAddress()) .setAdvertisePort(advertiseSocketBinding.getValue().getPort()) .setAdvertiseFrequency(advertiseFrequency) .setPath(advertisePath) .setProtocol(advertiseProtocol) .setSecurityKey(securityKey); } builder.setManagementHost(managementSocketBinding.getValue().getSocketAddress().getHostName()); builder.setManagementPort(managementSocketBinding.getValue().getSocketAddress().getPort()); config = builder.build(); if (advertiseFrequency > 0) { try { modCluster.advertise(config); } catch (IOException e) { throw new RuntimeException(e); } } modCluster.start(); }