/** * 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.cxf.transport.http_jetty.osgi; import java.io.IOException; import java.security.GeneralSecurityException; import java.util.Dictionary; import java.util.Enumeration; import java.util.List; import java.util.StringTokenizer; import javax.management.MBeanServer; import org.apache.cxf.bus.blueprint.BlueprintNameSpaceHandlerFactory; import org.apache.cxf.bus.blueprint.NamespaceHandlerRegisterer; import org.apache.cxf.common.util.CollectionUtils; import org.apache.cxf.configuration.jsse.TLSParameterJaxBUtils; import org.apache.cxf.configuration.jsse.TLSServerParameters; import org.apache.cxf.configuration.security.CertStoreType; import org.apache.cxf.configuration.security.CertificateConstraintsType; import org.apache.cxf.configuration.security.ClientAuthentication; import org.apache.cxf.configuration.security.CombinatorType; import org.apache.cxf.configuration.security.DNConstraintsType; import org.apache.cxf.configuration.security.FiltersType; import org.apache.cxf.configuration.security.KeyManagersType; import org.apache.cxf.configuration.security.KeyStoreType; import org.apache.cxf.configuration.security.SecureRandomParameters; import org.apache.cxf.configuration.security.TrustManagersType; import org.apache.cxf.transport.http_jetty.JettyHTTPServerEngine; import org.apache.cxf.transport.http_jetty.JettyHTTPServerEngineFactory; import org.apache.cxf.transport.http_jetty.ThreadingParameters; import org.apache.cxf.transport.http_jetty.blueprint.HTTPJettyTransportNamespaceHandler; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceRegistration; import org.osgi.service.cm.ConfigurationException; import org.osgi.service.cm.ManagedServiceFactory; import org.osgi.util.tracker.ServiceTracker; public class HTTPJettyTransportActivator implements BundleActivator, ManagedServiceFactory { public static final String FACTORY_PID = "org.apache.cxf.http.jetty"; BundleContext context; MBeanServer mbeans; ServiceTracker<MBeanServer, ?> mbeanServerTracker; ServiceRegistration<ManagedServiceFactory> reg; JettyHTTPServerEngineFactory factory = new JettyHTTPServerEngineFactory() { public MBeanServer getMBeanServer() { return (MBeanServer)mbeanServerTracker.getService(); } }; public void start(BundleContext ctx) throws Exception { this.context = ctx; reg = context.registerService(ManagedServiceFactory.class, this, CollectionUtils.singletonDictionary(Constants.SERVICE_PID, FACTORY_PID)); mbeanServerTracker = new ServiceTracker<>(ctx, MBeanServer.class, null); try { BlueprintNameSpaceHandlerFactory nsHandlerFactory = new BlueprintNameSpaceHandlerFactory() { @Override public Object createNamespaceHandler() { return new HTTPJettyTransportNamespaceHandler(); } }; NamespaceHandlerRegisterer.register(context, nsHandlerFactory, "http://cxf.apache.org/transports/http-jetty/configuration"); } catch (NoClassDefFoundError e) { // Blueprint not available, ignore } } public void stop(BundleContext ctx) throws Exception { mbeanServerTracker.close(); reg.unregister(); } public String getName() { return FACTORY_PID; } public void updated(String pid, Dictionary<String, ?> properties) throws ConfigurationException { if (pid == null) { return; } int port = Integer.parseInt((String)properties.get("port")); String host = (String)properties.get("host"); try { TLSServerParameters tls = createTlsServerParameters(properties); if (tls != null) { factory.setTLSServerParametersForPort(host, port, tls); } else { factory.createJettyHTTPServerEngine(host, port, "http"); } JettyHTTPServerEngine e = factory.retrieveJettyHTTPServerEngine(port); configure(e, properties); } catch (GeneralSecurityException e) { throw new ConfigurationException(null, null, e); } catch (IOException e) { throw new ConfigurationException(null, null, e); } } private void configure(JettyHTTPServerEngine e, Dictionary<String, ?> properties) { ThreadingParameters threading = createThreadingParameters(properties); if (threading != null) { e.setThreadingParameters(threading); } Enumeration<String> keys = properties.keys(); while (keys.hasMoreElements()) { String k = keys.nextElement(); if ("sessionSupport".equals(k)) { e.setSessionSupport(Boolean.parseBoolean((String)properties.get(k))); } else if ("continuationsEnabled".equals(k)) { e.setContinuationsEnabled(Boolean.parseBoolean((String)properties.get(k))); } else if ("reuseAddress".equals(k)) { e.setReuseAddress(Boolean.parseBoolean((String)properties.get(k))); } else if ("maxIdleTime".equals(k)) { e.setMaxIdleTime(Integer.parseInt((String)properties.get(k))); } } } public void deleted(String pid) { } private ThreadingParameters createThreadingParameters(Dictionary<String, ?> d) { Enumeration<String> keys = d.keys(); ThreadingParameters p = null; while (keys.hasMoreElements()) { String k = keys.nextElement(); if (k.startsWith("threadingParameters.")) { if (p == null) { p = new ThreadingParameters(); } String v = (String)d.get(k); k = k.substring("threadingParameters.".length()); if ("minThreads".equals(k)) { p.setMinThreads(Integer.parseInt(v)); } else if ("maxThreads".equals(k)) { p.setMaxThreads(Integer.parseInt(v)); } else if ("threadNamePrefix".equals(k)) { p.setThreadNamePrefix(k); } } } return p; } private TLSServerParameters createTlsServerParameters(Dictionary<String, ?> d) { Enumeration<String> keys = d.keys(); TLSServerParameters p = null; SecureRandomParameters srp = null; KeyManagersType kmt = null; TrustManagersType tmt = null; boolean enableRevocation = false; while (keys.hasMoreElements()) { String k = keys.nextElement(); if (k.startsWith("tlsServerParameters.")) { if (p == null) { p = new TLSServerParameters(); } String v = (String)d.get(k); k = k.substring("tlsServerParameters.".length()); if ("secureSocketProtocol".equals(k)) { p.setSecureSocketProtocol(v); } else if ("jsseProvider".equals(k)) { p.setJsseProvider(v); } else if ("certAlias".equals(k)) { p.setCertAlias(v); } else if ("clientAuthentication.want".equals(k)) { if (p.getClientAuthentication() == null) { p.setClientAuthentication(new ClientAuthentication()); } p.getClientAuthentication().setWant(Boolean.parseBoolean(v)); } else if ("clientAuthentication.required".equals(k)) { if (p.getClientAuthentication() == null) { p.setClientAuthentication(new ClientAuthentication()); } p.getClientAuthentication().setRequired(Boolean.parseBoolean(v)); } else if ("enableRevocation".equals(k)) { enableRevocation = Boolean.parseBoolean(v); } else if (k.startsWith("certConstraints.")) { configureCertConstraints(p, k, v); } else if (k.startsWith("secureRandomParameters.")) { srp = configureSecureRandom(srp, k, v); } else if (k.startsWith("cipherSuitesFilter.")) { configureCipherSuitesFilter(p, k, v); } else if (k.startsWith("cipherSuites")) { StringTokenizer st = new StringTokenizer(v, ","); while (st.hasMoreTokens()) { p.getCipherSuites().add(st.nextToken()); } } else if (k.startsWith("excludeProtocols")) { StringTokenizer st = new StringTokenizer(v, ","); while (st.hasMoreTokens()) { p.getExcludeProtocols().add(st.nextToken()); } } else if (k.startsWith("trustManagers.")) { tmt = getTrustManagers(tmt, k.substring("trustManagers.".length()), v); } else if (k.startsWith("keyManagers.")) { kmt = getKeyManagers(kmt, k.substring("keyManagers.".length()), v); } } } try { if (srp != null) { p.setSecureRandom(TLSParameterJaxBUtils.getSecureRandom(srp)); } if (kmt != null) { p.setKeyManagers(TLSParameterJaxBUtils.getKeyManagers(kmt)); } if (tmt != null) { p.setTrustManagers(TLSParameterJaxBUtils.getTrustManagers(tmt, enableRevocation)); } } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException(e); } return p; } private void configureCipherSuitesFilter(TLSServerParameters p, String k, String v) { k = k.substring("cipherSuitesFilter.".length()); StringTokenizer st = new StringTokenizer(v, ","); FiltersType ft = p.getCipherSuitesFilter(); if (ft == null) { ft = new FiltersType(); p.setCipherSuitesFilter(ft); } List<String> lst = "include".equals(k) ? ft.getInclude() : ft.getExclude(); while (st.hasMoreTokens()) { lst.add(st.nextToken()); } } private SecureRandomParameters configureSecureRandom(SecureRandomParameters srp, String k, String v) { k = k.substring("secureRandomParameters.".length()); if (srp == null) { srp = new SecureRandomParameters(); } if ("algorithm".equals(k)) { srp.setAlgorithm(v); } else if ("provider".equals(k)) { srp.setProvider(v); } return srp; } private void configureCertConstraints(TLSServerParameters p, String k, String v) { k = k.substring("certConstraints.".length()); CertificateConstraintsType cct = p.getCertConstraints(); if (cct == null) { cct = new CertificateConstraintsType(); p.setCertConstraints(cct); } DNConstraintsType dnct = null; if (k.startsWith("SubjectDNConstraints.")) { dnct = cct.getSubjectDNConstraints(); if (dnct == null) { dnct = new DNConstraintsType(); cct.setSubjectDNConstraints(dnct); } k = k.substring("SubjectDNConstraints.".length()); } else if (k.startsWith("IssuerDNConstraints.")) { dnct = cct.getIssuerDNConstraints(); if (dnct == null) { dnct = new DNConstraintsType(); cct.setIssuerDNConstraints(dnct); } k = k.substring("IssuerDNConstraints.".length()); } if (dnct != null) { if ("combinator".equals(k)) { dnct.setCombinator(CombinatorType.fromValue(v)); } else if ("RegularExpression".equals(k)) { dnct.getRegularExpression().add(k); } } } private KeyManagersType getKeyManagers(KeyManagersType keyManagers, String k, String v) { if (keyManagers == null) { keyManagers = new KeyManagersType(); } if ("factoryAlgorithm".equals(k)) { keyManagers.setFactoryAlgorithm(v); } else if ("provider".equals(k)) { keyManagers.setProvider(v); } else if ("keyPassword".equals(k)) { keyManagers.setKeyPassword(v); } else if (k.startsWith("keyStore.")) { keyManagers.setKeyStore(getKeyStore(keyManagers.getKeyStore(), k.substring("keyStore.".length()), v)); } return keyManagers; } private KeyStoreType getKeyStore(KeyStoreType ks, String k, String v) { if (ks == null) { ks = new KeyStoreType(); } if ("type".equals(k)) { ks.setType(v); } else if ("password".equals(k)) { ks.setPassword(v); } else if ("provider".equals(k)) { ks.setProvider(v); } else if ("url".equals(k)) { ks.setUrl(v); } else if ("file".equals(k)) { ks.setFile(v); } else if ("resource".equals(k)) { ks.setResource(v); } return ks; } private TrustManagersType getTrustManagers(TrustManagersType tmt, String k, String v) { if (tmt == null) { tmt = new TrustManagersType(); } if ("provider".equals(k)) { tmt.setProvider(v); } else if ("factoryAlgorithm".equals(k)) { tmt.setFactoryAlgorithm(v); } else if (k.startsWith("keyStore.")) { tmt.setKeyStore(getKeyStore(tmt.getKeyStore(), k.substring("keyStore.".length()), v)); } else if (k.startsWith("certStore")) { tmt.setCertStore(getCertStore(tmt.getCertStore(), k.substring("certStore.".length()), v)); } return tmt; } private CertStoreType getCertStore(CertStoreType cs, String k, String v) { if (cs == null) { cs = new CertStoreType(); } if ("file".equals(k)) { cs.setFile(v); } else if ("url".equals(k)) { cs.setUrl(v); } else if ("resource".equals(k)) { cs.setResource(v); } return cs; } }