001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.activemq.transport;
018
019import javax.net.ssl.SSLContext;
020
021import org.apache.activemq.broker.SslContext;
022import org.apache.activemq.transport.https.Krb5AndCertsSslSocketConnector;
023import org.apache.activemq.util.IntrospectionSupport;
024import org.eclipse.jetty.server.Connector;
025import org.eclipse.jetty.server.Server;
026import org.eclipse.jetty.util.ssl.SslContextFactory;
027
028public class SecureSocketConnectorFactory extends SocketConnectorFactory {
029
030    private String keyPassword = System.getProperty("javax.net.ssl.keyPassword");
031    private String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword");
032    private String keyStore = System.getProperty("javax.net.ssl.keyStore");
033    private String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword");
034    private String trustStore = System.getProperty("javax.net.ssl.trustStore");
035    private boolean needClientAuth;
036    private boolean wantClientAuth;
037    private String keyStoreType;
038    private String secureRandomCertficateAlgorithm;
039    private String trustCertificateAlgorithm;
040    private String keyCertificateAlgorithm;
041    private String protocol;
042    private String auth;
043
044    private SslContext context;
045    private SslContextFactory contextFactory;
046    
047    public SecureSocketConnectorFactory() {
048        
049    }
050    public SecureSocketConnectorFactory(SslContext context) {
051        this.context = context;
052    }
053
054    public SecureSocketConnectorFactory(SslContextFactory contextFactory) {
055        this.contextFactory = contextFactory;
056    }
057
058    @Override
059    public Connector createConnector(Server server) throws Exception {
060        if (getTransportOptions() != null) {
061            IntrospectionSupport.setProperties(this, getTransportOptions());
062        }
063
064        SSLContext sslContext = context == null ? null : context.getSSLContext();
065
066        // Get a reference to the current ssl context factory...
067
068        SslContextFactory factory;
069        if (contextFactory == null) {
070            factory = new SslContextFactory();
071            if (context != null) {
072                // Should not be using this method since it does not use all of the values
073                // from the passed SslContext instance.....
074                factory.setSslContext(sslContext);
075
076            } else {
077                if (keyStore != null) {
078                    factory.setKeyStorePath(keyStore);
079                }
080                if (keyStorePassword != null) {
081                    factory.setKeyStorePassword(keyStorePassword);
082                }
083                // if the keyPassword hasn't been set, default it to the
084                // key store password
085                if (keyPassword == null && keyStorePassword != null) {
086                    factory.setKeyStorePassword(keyStorePassword);
087                }
088                if (keyStoreType != null) {
089                    factory.setKeyStoreType(keyStoreType);
090                }
091                if (secureRandomCertficateAlgorithm != null) {
092                    factory.setSecureRandomAlgorithm(secureRandomCertficateAlgorithm);
093                }
094                if (keyCertificateAlgorithm != null) {
095                    factory.setSslKeyManagerFactoryAlgorithm(keyCertificateAlgorithm);
096                }
097                if (trustCertificateAlgorithm != null) {
098                    factory.setTrustManagerFactoryAlgorithm(trustCertificateAlgorithm);
099                }
100                if (protocol != null) {
101                    factory.setProtocol(protocol);
102                }
103                if (trustStore != null) {
104                    setTrustStore(factory, trustStore);
105                }
106                if (trustStorePassword != null) {
107                    factory.setTrustStorePassword(trustStorePassword);
108                }
109            }
110            factory.setNeedClientAuth(needClientAuth);
111            factory.setWantClientAuth(wantClientAuth);
112        } else {
113            factory = contextFactory;
114        }
115
116        
117        if ("KRB".equals(auth) || "BOTH".equals(auth)
118            && Server.getVersion().startsWith("8")) {
119            return new Krb5AndCertsSslSocketConnector(factory, auth);
120        } else {
121            try {
122                Class<?> cls = Class.forName("org.eclipse.jetty.server.ssl.SslSelectChannelConnector", true, Server.class.getClassLoader());
123                return (Connector)cls.getConstructor(SslContextFactory.class).newInstance(factory);
124            } catch (Throwable t) {
125                Class<?> c = Class.forName("org.eclipse.jetty.server.ServerConnector", true, Server.class.getClassLoader());
126                Connector connector = (Connector)c.getConstructor(Server.class, SslContextFactory.class).newInstance(server, factory);
127                Server.class.getMethod("setStopTimeout", Long.TYPE).invoke(server, 500);
128                connector.getClass().getMethod("setStopTimeout", Long.TYPE).invoke(connector, 500);
129                return connector;
130            }
131        }
132    }
133    private void setTrustStore(SslContextFactory factory, String trustStore2) throws Exception {
134        String mname = Server.getVersion().startsWith("8") ? "setTrustStore" : "setTrustStorePath";
135        factory.getClass().getMethod(mname, String.class).invoke(factory, trustStore2);
136    }
137
138
139    
140    // Properties
141    // --------------------------------------------------------------------------------
142
143    public String getKeyStore() {
144        return keyStore;
145    }
146
147    public void setKeyStore(String keyStore) {
148        this.keyStore = keyStore;
149    }
150
151    public String getKeyPassword() {
152        return keyPassword;
153    }
154
155    public void setKeyPassword(String keyPassword) {
156        this.keyPassword = keyPassword;
157    }
158
159    public String getKeyStoreType() {
160        return keyStoreType;
161    }
162
163    public void setKeyStoreType(String keyStoreType) {
164        this.keyStoreType = keyStoreType;
165    }
166
167    public String getKeyStorePassword() {
168        return keyStorePassword;
169    }
170
171    public void setKeyStorePassword(String keyStorePassword) {
172        this.keyStorePassword = keyStorePassword;
173    }
174
175    public String getProtocol() {
176        return protocol;
177    }
178
179    public void setProtocol(String protocol) {
180        this.protocol = protocol;
181    }
182
183    public String getSecureRandomCertficateAlgorithm() {
184        return secureRandomCertficateAlgorithm;
185    }
186
187    public void setSecureRandomCertficateAlgorithm(String secureRandomCertficateAlgorithm) {
188        this.secureRandomCertficateAlgorithm = secureRandomCertficateAlgorithm;
189    }
190
191    public String getKeyCertificateAlgorithm() {
192        return keyCertificateAlgorithm;
193    }
194
195    public void setKeyCertificateAlgorithm(String keyCertificateAlgorithm) {
196        this.keyCertificateAlgorithm = keyCertificateAlgorithm;
197    }
198
199    public String getTrustCertificateAlgorithm() {
200        return trustCertificateAlgorithm;
201    }
202
203    public void setTrustCertificateAlgorithm(String trustCertificateAlgorithm) {
204        this.trustCertificateAlgorithm = trustCertificateAlgorithm;
205    }
206
207    /**
208     * @return the auth
209     */
210    public String getAuth() {
211        return auth;
212    }
213
214    /**
215     * @param auth the auth to set
216     */
217    public void setAuth(String auth) {
218        this.auth = auth;
219    }
220
221    public boolean isWantClientAuth() {
222        return wantClientAuth;
223    }
224
225    public void setWantClientAuth(boolean wantClientAuth) {
226        this.wantClientAuth = wantClientAuth;
227    }
228
229    public boolean isNeedClientAuth() {
230        return needClientAuth;
231    }
232
233    public void setNeedClientAuth(boolean needClientAuth) {
234        this.needClientAuth = needClientAuth;
235    }
236
237    public String getTrustStore() {
238        return trustStore;
239    }
240
241    public void setTrustStore(String trustStore) {
242        this.trustStore = trustStore;
243    }
244
245    public String getTrustStorePassword() {
246        return trustStorePassword;
247    }
248
249    public void setTrustStorePassword(String trustStorePassword) {
250        this.trustStorePassword = trustStorePassword;
251    }
252}