| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.activemq.artemis.core.server.management; |
| |
| import org.apache.activemq.artemis.core.remoting.impl.ssl.SSLSupport; |
| |
| import javax.management.JMException; |
| import javax.management.MBeanServer; |
| import javax.management.ObjectName; |
| import javax.management.remote.JMXConnectorServer; |
| import javax.management.remote.JMXConnectorServerFactory; |
| import javax.management.remote.JMXServiceURL; |
| import javax.management.remote.rmi.RMIConnectorServer; |
| import javax.net.ServerSocketFactory; |
| import javax.net.ssl.SSLContext; |
| import javax.net.ssl.SSLServerSocket; |
| import javax.net.ssl.SSLServerSocketFactory; |
| import javax.rmi.ssl.SslRMIClientSocketFactory; |
| import java.io.IOException; |
| import java.net.InetAddress; |
| import java.net.ServerSocket; |
| import java.rmi.server.RMIClientSocketFactory; |
| import java.rmi.server.RMIServerSocketFactory; |
| import java.util.Map; |
| |
| public class ConnectorServerFactory { |
| |
| public void setkeyStoreProvider(String keyStoreProvider) { |
| this.keyStoreProvider = keyStoreProvider; |
| } |
| |
| public void setKeyStorePassword(String keyStorePassword) { |
| this.keyStorePassword = keyStorePassword; |
| } |
| |
| public void setTrustStorePath(String trustStorePath) { |
| this.trustStorePath = trustStorePath; |
| } |
| |
| public void setTrustStoreProvider(String trustStoreProvider) { |
| this.trustStoreProvider = trustStoreProvider; |
| } |
| |
| public void setTrustStorePassword(String trustStorePassword) { |
| this.trustStorePassword = trustStorePassword; |
| } |
| |
| private enum AuthenticatorType { NONE, PASSWORD, CERTIFICATE }; |
| |
| private MBeanServer server; |
| private String serviceUrl; |
| private String rmiServerHost; |
| private Map environment; |
| private ObjectName objectName; |
| private JMXConnectorServer connectorServer; |
| |
| private AuthenticatorType authenticatorType = AuthenticatorType.PASSWORD; |
| |
| private boolean secured; |
| |
| private String keyStoreProvider; |
| |
| private String keyStorePath; |
| |
| private String keyStorePassword; |
| |
| private String trustStoreProvider; |
| |
| private String trustStorePath; |
| |
| private String trustStorePassword; |
| |
| |
| public String getKeyStoreProvider() { |
| return keyStoreProvider; |
| } |
| |
| public String getKeyStorePath() { |
| return keyStorePath; |
| } |
| |
| public void setKeyStorePath(String keyStorePath) { |
| this.keyStorePath = keyStorePath; |
| } |
| |
| public String getKeyStorePassword() { |
| return keyStorePassword; |
| } |
| |
| public String getTrustStoreProvider() { |
| return trustStoreProvider; |
| } |
| |
| public String getTrustStorePath() { |
| return trustStorePath; |
| } |
| |
| public String getTrustStorePassword() { |
| return trustStorePassword; |
| } |
| |
| public MBeanServer getServer() { |
| return server; |
| } |
| |
| public void setServer(MBeanServer server) { |
| this.server = server; |
| } |
| |
| public String getServiceUrl() { |
| return serviceUrl; |
| } |
| |
| public void setServiceUrl(String serviceUrl) { |
| this.serviceUrl = serviceUrl; |
| } |
| |
| public String getRmiServerHost() { |
| return this.rmiServerHost; |
| } |
| |
| public void setRmiServerHost(String rmiServerHost) { |
| this.rmiServerHost = rmiServerHost; |
| } |
| |
| public Map getEnvironment() { |
| return environment; |
| } |
| |
| public void setEnvironment(Map environment) { |
| this.environment = environment; |
| } |
| |
| public ObjectName getObjectName() { |
| return objectName; |
| } |
| |
| public void setObjectName(ObjectName objectName) { |
| this.objectName = objectName; |
| } |
| |
| public String getAuthenticatorType() { |
| return this.authenticatorType.name().toLowerCase(); |
| } |
| |
| /** |
| * Authenticator type to use. Acceptable values are "none", "password", and "certificate" |
| * |
| * @param value |
| */ |
| public void setAuthenticatorType(String value) { |
| this.authenticatorType = AuthenticatorType.valueOf(value.toUpperCase()); |
| } |
| |
| public boolean isSecured() { |
| return this.secured; |
| } |
| |
| public void setSecured(boolean secured) { |
| this.secured = secured; |
| } |
| |
| private boolean isClientAuth() { |
| return this.authenticatorType.equals(AuthenticatorType.CERTIFICATE); |
| } |
| |
| public void init() throws Exception { |
| |
| if (this.server == null) { |
| throw new IllegalArgumentException("server must be set"); |
| } |
| JMXServiceURL url = new JMXServiceURL(this.serviceUrl); |
| setupArtemisRMIServerSocketFactory(); |
| if (isClientAuth()) { |
| this.secured = true; |
| } |
| |
| if (this.secured) { |
| this.setupSsl(); |
| } |
| |
| if (!AuthenticatorType.PASSWORD.equals(this.authenticatorType)) { |
| this.environment.remove("jmx.remote.authenticator"); |
| } |
| |
| this.connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, this.environment, this.server); |
| if (this.objectName != null) { |
| this.server.registerMBean(this.connectorServer, this.objectName); |
| } |
| |
| try { |
| this.connectorServer.start(); |
| } catch (Exception ex) { |
| doUnregister(this.objectName); |
| throw ex; |
| } |
| } |
| |
| public void destroy() throws Exception { |
| try { |
| if (this.connectorServer != null) { |
| this.connectorServer.stop(); |
| } |
| } finally { |
| doUnregister(this.objectName); |
| } |
| } |
| |
| protected void doUnregister(ObjectName objectName) { |
| try { |
| if (this.objectName != null && this.server.isRegistered(objectName)) { |
| this.server.unregisterMBean(objectName); |
| } |
| } catch (JMException ex) { |
| // Ignore |
| } |
| } |
| |
| //todo fix |
| private void setupSsl() throws Exception { |
| SSLContext context = new SSLSupport() |
| .setKeystoreProvider(keyStoreProvider) |
| .setKeystorePath(keyStorePath) |
| .setKeystorePassword(keyStorePassword) |
| .setTruststoreProvider(trustStoreProvider) |
| .setTruststorePath(trustStorePath) |
| .setTruststorePassword(trustStorePassword) |
| .createContext(); |
| SSLServerSocketFactory sssf = context.getServerSocketFactory(); |
| RMIServerSocketFactory rssf = new ArtemisSslRMIServerSocketFactory(sssf, this.isClientAuth(), rmiServerHost); |
| RMIClientSocketFactory rcsf = new SslRMIClientSocketFactory(); |
| environment.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, rssf); |
| environment.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, rcsf); |
| } |
| |
| private void setupArtemisRMIServerSocketFactory() { |
| RMIServerSocketFactory rmiServerSocketFactory = new ArtemisRMIServerSocketFactory(getRmiServerHost()); |
| environment.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, rmiServerSocketFactory); |
| } |
| |
| private static class ArtemisSslRMIServerSocketFactory implements RMIServerSocketFactory { |
| private SSLServerSocketFactory sssf; |
| private boolean clientAuth; |
| private String rmiServerHost; |
| |
| ArtemisSslRMIServerSocketFactory(SSLServerSocketFactory sssf, boolean clientAuth, String rmiServerHost) { |
| this.sssf = sssf; |
| this.clientAuth = clientAuth; |
| this.rmiServerHost = rmiServerHost; |
| } |
| |
| @Override |
| public ServerSocket createServerSocket(int port) throws IOException { |
| SSLServerSocket ss = (SSLServerSocket) sssf.createServerSocket(port, 50, InetAddress.getByName(rmiServerHost)); |
| ss.setNeedClientAuth(clientAuth); |
| return ss; |
| } |
| } |
| |
| private static class ArtemisRMIServerSocketFactory implements RMIServerSocketFactory { |
| private String rmiServerHost; |
| |
| ArtemisRMIServerSocketFactory(String rmiServerHost) { |
| this.rmiServerHost = rmiServerHost; |
| } |
| |
| @Override |
| public ServerSocket createServerSocket(int port) throws IOException { |
| ServerSocket serverSocket = (ServerSocket) ServerSocketFactory.getDefault().createServerSocket(port, 50, InetAddress.getByName(rmiServerHost)); |
| return serverSocket; |
| } |
| } |
| |
| |
| } |