From e05f09bb20a5e1cee9b6138bfab1728e4a83cc9e Mon Sep 17 00:00:00 2001 From: Benjamin Phillippe Date: Fri, 6 Jun 2014 14:34:51 -0500 Subject: [PATCH] Omaha #3255 Registry Security Features (commit 1/5) Change-Id: I3b24ae8696ded86d8157a092eeff81cc45a2f291 Former-commit-id: fb9e936e0e395f7cbed7506b6bd4b36ee003a597 [formerly ec1b81d28c4b418fada53c684e78d397fee9b97d] Former-commit-id: cfe7bb251f552856a4b8a86a251cee93fa428d14 --- edexOsgi/build.edex/esb/bin/setup.env | 5 +- .../esb/conf/security/keystoreUtil.sh | 160 +++++++++++++++ .../META-INF/MANIFEST.MF | 3 +- .../common/registry/ebxml/RegistryUtil.java | 3 +- .../services/RegistryRESTServices.java | 35 ++-- .../services/RegistrySOAPServices.java | 94 +++------ .../RegistryServiceConfiguration.java | 121 +++++++++++ .../META-INF/MANIFEST.MF | 5 +- .../res/spring/ebxml-thrift-client.xml | 2 +- .../res/spring/ebxml-webserver.xml | 54 +---- .../res/spring/ebxml-webservices.xml | 79 ++++++-- .../res/spring/ebxml.xml | 17 +- ...raytheon.uf.edex.registry.ebxml.properties | 26 ++- .../registry/ebxml/web/RegistryWebServer.java | 123 +++++++++++ .../web/security/RegistryIPAccessHandler.java | 59 ++++++ ...lNetworkTrafficSelectChannelConnector.java | 97 +++++++++ .../web/etc/jettyServer.xml | 99 +++++++++ .../web/registry/registryUtil.js | 2 +- .../web/webServiceBeans.xml | 21 +- .../feature.xml | 9 +- .../com.raytheon.uf.edex.security/.classpath | 8 + .../com.raytheon.uf.edex.security/.project | 28 +++ .../.settings/org.eclipse.jdt.core.prefs | 7 + .../META-INF/MANIFEST.MF | 13 ++ .../build.properties | 5 + .../res/spring/edex-security.xml | 9 + .../uf/edex/security/EncryptedProperties.java | 84 ++++++++ .../edex/security/SecurityConfiguration.java | 191 ++++++++++++++++++ 28 files changed, 1175 insertions(+), 184 deletions(-) create mode 100755 edexOsgi/build.edex/esb/conf/security/keystoreUtil.sh create mode 100644 edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistryServiceConfiguration.java create mode 100644 edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/web/RegistryWebServer.java create mode 100644 edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/web/security/RegistryIPAccessHandler.java create mode 100644 edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/web/security/SslNetworkTrafficSelectChannelConnector.java create mode 100644 edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/etc/jettyServer.xml create mode 100644 edexOsgi/com.raytheon.uf.edex.security/.classpath create mode 100644 edexOsgi/com.raytheon.uf.edex.security/.project create mode 100644 edexOsgi/com.raytheon.uf.edex.security/.settings/org.eclipse.jdt.core.prefs create mode 100644 edexOsgi/com.raytheon.uf.edex.security/META-INF/MANIFEST.MF create mode 100644 edexOsgi/com.raytheon.uf.edex.security/build.properties create mode 100644 edexOsgi/com.raytheon.uf.edex.security/res/spring/edex-security.xml create mode 100644 edexOsgi/com.raytheon.uf.edex.security/src/com/raytheon/uf/edex/security/EncryptedProperties.java create mode 100644 edexOsgi/com.raytheon.uf.edex.security/src/com/raytheon/uf/edex/security/SecurityConfiguration.java diff --git a/edexOsgi/build.edex/esb/bin/setup.env b/edexOsgi/build.edex/esb/bin/setup.env index ae28f1c449..d6823a20c3 100644 --- a/edexOsgi/build.edex/esb/bin/setup.env +++ b/edexOsgi/build.edex/esb/bin/setup.env @@ -26,16 +26,17 @@ export BROKER_ADDR=localhost export PYPIES_SERVER=http://localhost:9582 # Registry specific ports +export EBXML_REGISTRY_WEBSERVER_HOME=/awips2/edex/webapps/registryEbxml/ export EBXML_REGISTRY_WEBSERVER_PORT=8082 -export EBXML_REGISTRY_WEBSERVER_CONFIDENTIAL_PORT=8446 export EBXML_THRIFT_SERVICE_PORT=9588 # data delivery specific variables, used below in the localization section export NCF_HOST=165.92.30.69 -export NCF_ADDRESS=http://${NCF_HOST}:${EBXML_REGISTRY_WEBSERVER_PORT} +export NCF_ADDRESS=https://${NCF_HOST}:${EBXML_REGISTRY_WEBSERVER_PORT} export DATADELIVERY_HOST=localhost # Currently the registry is hosted on datadelivery, but this could be changed in the future export EBXML_REGISTRY_HOST=${DATADELIVERY_HOST} export EBXML_REGISTRY_FEDERATION_ENABLED=true +export EBXML_REGISTRY_USER= # moved here from environment.xml # these values are returned to clients that contact the localization service diff --git a/edexOsgi/build.edex/esb/conf/security/keystoreUtil.sh b/edexOsgi/build.edex/esb/conf/security/keystoreUtil.sh new file mode 100755 index 0000000000..bbac75f17a --- /dev/null +++ b/edexOsgi/build.edex/esb/conf/security/keystoreUtil.sh @@ -0,0 +1,160 @@ +#!/bin/bash + +securityDir=/awips2/edex/conf/security +securityProps=$securityDir/security.properties +publicKeyFile=PublicKey.cer +keystore=keystore.jks +truststore=truststore.jks + +keystorePw= +keyAlias=$(hostname -s) +keyPw= + +truststorePw=password + +function usage { + echo "Usage:" + echo -e "\t-h\t\tDisplays usage" + echo -e "\t-g\t\tGenerate keystore, truststore, and security properties file" + echo -e "\t-a [keyFile]\tAdds a public key to the trust store" +} + +function generateKeystores() { + +echo "Generating keystores" + +if [ ! -d "$securityDir" ]; then + mkdir $securityDir +fi + +while [ -z $keystorePw ]; +do + echo -n "Enter password for keystore [$keystore]: " + read keystorePw + if [ -z $keystorePw ]; + then + echo "Keystore password cannot be empty!" + fi +done + +while [ -z $keyAlias ]; +do + echo -n "Enter alias: " + read keyAlias + if [ -z $keyAlias ]; + then + echo "Alias cannot be empty!" + fi +done + +while [ -z $keyPw ]; +do + echo -n "Enter password for key [$keyAlias]: " + read keyPw + if [ -z $keyPw ]; + then + echo "Key password cannot be empty!" + fi +done + +while [ -z $truststorePw ]; +do + echo -n "Enter password for trust store [$truststore]: " + read truststorePw + if [ -z $truststorePw ]; + then + echo "TrustStore password cannot be empty!" + fi +done + +cn=$(hostname) + +echo "Generating keystore..." +keytool -genkeypair -alias $keyAlias -keypass $keyPw -keystore $keystore -storepass $keystorePw -validity 360 -dname "CN=$cn, OU=AWIPS, O=Raytheon, L=Omaha, ST=NE, C=US" -keyalg RSA +echo -n "Exporting public key..." +exportOutput=`keytool -exportcert -alias $keyAlias -keystore $keystore -file $keyAlias$publicKeyFile -storepass $keystorePw 2>&1` +echo "Done!" +obfuscatedKeystorePassword=`java -cp /awips2/edex/lib/dependencies/org.eclipse.jetty/jetty-http-7.6.14.v20131031.jar:/awips2/edex/lib/dependencies/org.eclipse.jetty/jetty-util-7.6.14.v20131031.jar org.eclipse.jetty.util.security.Password $keystorePw 2>&1 | grep OBF` + +echo "Generating trust store..." + +keytool -genkey -alias tmp -keypass tempPass -dname CN=foo -keystore $truststore -storepass $truststorePw +keytool -delete -alias tmp -keystore $truststore -storepass $truststorePw +keytool -import -trustcacerts -file $keyAlias$publicKeyFile -alias $keyAlias -keystore $truststore -storepass $truststorePw + +obfuscatedTruststorePassword=`java -cp /awips2/edex/lib/dependencies/org.eclipse.jetty/jetty-http-7.6.14.v20131031.jar:/awips2/edex/lib/dependencies/org.eclipse.jetty/jetty-util-7.6.14.v20131031.jar org.eclipse.jetty.util.security.Password $truststorePw 2>&1 | grep OBF` + + +echo -n "Generating security properties file..." + +echo "edex.security.keystore.path=$securityDir/$keystore" > $securityProps +echo "edex.security.keystore.alias=$keyAlias" >> $securityProps +echo "edex.security.keystore.password=$obfuscatedKeystorePassword" >> $securityProps +echo "edex.security.keystore.type=JKS" >> $securityProps +echo "edex.security.keystore.algorithm=SunX509" >> $securityProps +echo "edex.security.truststore.path=$securityDir/$truststore" >> $securityProps +echo "edex.security.truststore.password=$obfuscatedTruststorePassword" >> $securityProps +echo "edex.security.truststore.type=JKS" >> $securityProps +echo "edex.security.truststore.algorithm=SunX509" >> $securityProps +echo "edex.security.disableCNCheck=false" >>$securityProps + +echo "#The following configuration items are used with the wss4j in/out interceptors" >> $securityProps +echo "org.apache.ws.security.crypto.merlin.keystore.file=security/$keystore" >> $securityProps +echo "org.apache.ws.security.crypto.merlin.keystore.password=$obfuscatedKeystorePassword" >> $securityProps +echo "org.apache.ws.security.crypto.merlin.keystore.type=JKS" >> $securityProps +echo "org.apache.ws.security.crypto.merlin.keystore.alias=$keyAlias" >> $securityProps + +echo "Done!" + +echo -n "Moving key store and trust store to [$securityDir] ..." +mv $truststore $keystore $securityDir +echo "Done!" + +} + +function addKey() { +echo "Adding $keyfile to trust store..." + +userAlias= +while [ -z $userAlias ]; +do + echo -n "Enter alias for [$keyfile]: " + read userAlias + if [ -z $userAlias ]; + then + echo "Alias cannot be empty!" + fi +done +keytool -import -trustcacerts -file $keyfile -alias $userAlias -keystore $securityDir/$truststore + +} + + +if [ $# -eq 0 ] +then + echo "No arguments supplied" + usage + exit 0 +elif [ "$1" = "-g" ] +then + generateKeystores + exit 0 +elif [ "$1" = "-a" ] +then + if [ $# -lt 2 ] + then + echo "No key file supplied" + usage + elif [ ! -e $securityDir/$truststore ] + then + echo "Trust store [$securityDir/$truststore] does not exist!" + else + keyfile=$2 + addKey + fi + exit 0 +elif [ "$1" = "-usage" ] || [ "$1" = "--help" ] || [ "$1" = "-h" ] +then + usage + exit 0 +fi diff --git a/edexOsgi/com.raytheon.uf.common.registry.ebxml/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.registry.ebxml/META-INF/MANIFEST.MF index eeb2cd17c6..dd6971d1ab 100644 --- a/edexOsgi/com.raytheon.uf.common.registry.ebxml/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.registry.ebxml/META-INF/MANIFEST.MF @@ -31,7 +31,8 @@ Require-Bundle: org.apache.commons.codec;bundle-version="1.4.0", org.springframework;bundle-version="2.5.6", org.apache.commons.lang;bundle-version="2.3.0", org.apache.commons.cxf;bundle-version="1.0.0", - com.raytheon.uf.common.localization;bundle-version="1.12.1174" + com.raytheon.uf.common.localization;bundle-version="1.12.1174", + com.raytheon.uf.edex.security;bundle-version="1.14.0" Import-Package: com.raytheon.uf.common.registry.ebxml.version, com.sun.xml.bind.marshaller, com.vividsolutions.jts.geom diff --git a/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/ebxml/RegistryUtil.java b/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/ebxml/RegistryUtil.java index 8801a167b4..3dd269f15a 100644 --- a/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/ebxml/RegistryUtil.java +++ b/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/ebxml/RegistryUtil.java @@ -82,6 +82,7 @@ import com.raytheon.uf.common.util.ReflectionUtil; * Dec 04, 2013 2584 dhladky Versions for Registry objects * Mar 31, 2014 2889 dhladky Added username for notification center tracking. * Apr 24, 2014 2992 dhladky fixed all objects in ebxml owned by NCF, bad. + * 6/5/2014 1712 bphillip Registry now communicates over https * * * @@ -107,7 +108,7 @@ public final class RegistryUtil { static { if (System.getenv("EBXML_REGISTRY_HOST") != null && System.getenv("EBXML_REGISTRY_WEBSERVER_PORT") != null) { - LOCAL_REGISTRY_ADDRESS = "http://" + LOCAL_REGISTRY_ADDRESS = "https://" + System.getenv("EBXML_REGISTRY_HOST") + ":" + System.getenv("EBXML_REGISTRY_WEBSERVER_PORT"); } diff --git a/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistryRESTServices.java b/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistryRESTServices.java index a04c4019ae..9a5e3f9839 100644 --- a/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistryRESTServices.java +++ b/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistryRESTServices.java @@ -33,16 +33,14 @@ import org.apache.cxf.jaxrs.client.ClientConfiguration; import org.apache.cxf.jaxrs.client.JAXRSClientFactory; import org.apache.cxf.jaxrs.client.WebClient; import org.apache.cxf.transport.http.HTTPConduit; -import org.apache.cxf.transports.http.configuration.ConnectionType; -import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; import com.google.common.io.Resources; -import com.raytheon.uf.common.comm.ProxyConfiguration; import com.raytheon.uf.common.registry.RegistryJaxbManager; import com.raytheon.uf.common.registry.RegistryNamespaceMapper; import com.raytheon.uf.common.registry.ebxml.RegistryUtil; import com.raytheon.uf.common.registry.services.rest.IRegistryObjectsRestService; import com.raytheon.uf.common.registry.services.rest.IRepositoryItemsRestService; +import com.raytheon.uf.edex.security.SecurityConfiguration; /** * @@ -63,6 +61,7 @@ import com.raytheon.uf.common.registry.services.rest.IRepositoryItemsRestService * 12/2/2013 1829 bphillip Removed expectedType argument on getRegistryObject method * 1/15/2014 2613 bphillip Removed Service cache due to unexpected behavior * 2/19/2014 2769 bphillip Added service cache + * 6/5/2014 1712 bphillip Moved configuration out to separate class * * * @author bphillip @@ -76,23 +75,9 @@ public class RegistryRESTServices { /** JAXB Manager */ private RegistryJaxbManager jaxbManager; - /** Policy used for rest connections */ - private static final HTTPClientPolicy restPolicy; + private RegistryServiceConfiguration serviceConfig; - static { - ProxyConfiguration proxyConfig = RegistrySOAPServices - .getProxyConfiguration(); - restPolicy = new HTTPClientPolicy(); - restPolicy.setConnection(ConnectionType.CLOSE); - restPolicy.setConnectionTimeout(2000); - restPolicy.setReceiveTimeout(30000); - restPolicy.setMaxRetransmits(1); - if (proxyConfig != null) { - restPolicy.setProxyServer(proxyConfig.getHost()); - restPolicy.setProxyServerPort(proxyConfig.getPort()); - restPolicy.setNonProxyHosts(proxyConfig.getNonProxyHosts()); - } - } + private SecurityConfiguration securityConfig; public RegistryRESTServices() throws JAXBException { jaxbManager = new RegistryJaxbManager(new RegistryNamespaceMapper()); @@ -192,12 +177,22 @@ public class RegistryRESTServices { T service = JAXRSClientFactory.create(url, serviceClass); Client client = (Client) Proxy.getInvocationHandler((Proxy) service); ClientConfiguration config = WebClient.getConfig(service); + HTTPConduit conduit = config.getHttpConduit(); - conduit.setClient(restPolicy); + conduit.setClient(serviceConfig.getHttpClientPolicy()); + conduit.setTlsClientParameters(securityConfig.getTlsParams()); // Create HTTP header containing the calling registry client.header(RegistryUtil.CALLING_REGISTRY_SOAP_HEADER_NAME, RegistryUtil.LOCAL_REGISTRY_ADDRESS); return service; } + + public void setServiceConfig(RegistryServiceConfiguration serviceConfig) { + this.serviceConfig = serviceConfig; + } + + public void setSecurityConfig(SecurityConfiguration securityConfig) { + this.securityConfig = securityConfig; + } } diff --git a/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistrySOAPServices.java b/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistrySOAPServices.java index 5e9ef91209..4f0cc71be8 100644 --- a/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistrySOAPServices.java +++ b/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistrySOAPServices.java @@ -19,8 +19,6 @@ **/ package com.raytheon.uf.common.registry.services; -import java.io.File; -import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.Arrays; @@ -28,7 +26,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.xml.ws.wsaddressing.W3CEndpointReference; import javax.xml.ws.wsaddressing.W3CEndpointReferenceBuilder; import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.Cataloger; @@ -46,15 +43,12 @@ import org.apache.cxf.endpoint.Client; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.message.Message; import org.apache.cxf.transport.http.HTTPConduit; -import org.apache.cxf.transports.http.configuration.ConnectionType; -import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; +import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; -import com.raytheon.uf.common.comm.ProxyConfiguration; -import com.raytheon.uf.common.comm.ProxyUtil; -import com.raytheon.uf.common.localization.PathManagerFactory; import com.raytheon.uf.common.registry.ebxml.RegistryUtil; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.edex.security.SecurityConfiguration; /** * @@ -74,6 +68,7 @@ import com.raytheon.uf.common.status.UFStatus; * 11/20/2013 2534 bphillip Eliminated service caching * 1/15/2014 2613 bphillip Eliminated service caching...again * 2/19/2014 2769 bphillip Renamed getPort method + * 6/5/2014 1712 bphillip Moved configuration out to separate class. Added outbound interceptor * * * @author bphillip @@ -85,12 +80,6 @@ public class RegistrySOAPServices { protected static final IUFStatusHandler statusHandler = UFStatus .getHandler(RegistrySOAPServices.class); - /** Default timeout for receiving HTTP data */ - protected static final long DEFAULT_RECEIVE_TIMEOUT = 60000; - - /** Default value for establishing an HTTP connection */ - protected static final long DEFAULT_CONNECT_TIMEOUT = 10000; - /** Path separator */ protected static final String PATH_SEPARATOR = "/"; @@ -112,44 +101,11 @@ public class RegistrySOAPServices { /** The name of the validator service */ protected static final String VALIDATOR_SERVICE_NAME = "validator"; - protected static final ProxyConfiguration proxyConfig; + protected WSS4JOutInterceptor securityInterceptor; - protected static final HTTPClientPolicy httpClientPolicy; + protected RegistryServiceConfiguration serviceConfig; - protected static final String HTTP_RECEIVE_TIMEOUT_PROPERTY = "ebxml-http-receive-timeout"; - - protected static final String HTTP_CONNECTION_TIMEOUT_PROPERTY = "ebxml-http-connection-timeout"; - - static { - proxyConfig = getProxyConfiguration(); - httpClientPolicy = new HTTPClientPolicy(); - - try { - httpClientPolicy.setReceiveTimeout(Long.parseLong(System - .getProperty(HTTP_RECEIVE_TIMEOUT_PROPERTY))); - } catch (NumberFormatException e) { - statusHandler - .error("ebxml-http-receive-timeout not specified. Using default value of 1 minute", - e); - httpClientPolicy.setReceiveTimeout(DEFAULT_RECEIVE_TIMEOUT); - } - try { - httpClientPolicy.setConnectionTimeout(Long.parseLong(System - .getProperty(HTTP_CONNECTION_TIMEOUT_PROPERTY))); - } catch (NumberFormatException e) { - statusHandler - .error("ebxml-http-connection-timeout not specified. Using default value of 10 seconds", - e); - httpClientPolicy.setConnectionTimeout(DEFAULT_CONNECT_TIMEOUT); - } - httpClientPolicy.setConnection(ConnectionType.CLOSE); - httpClientPolicy.setMaxRetransmits(5); - if (proxyConfig != null) { - httpClientPolicy.setProxyServer(proxyConfig.getHost()); - httpClientPolicy.setProxyServerPort(proxyConfig.getPort()); - httpClientPolicy.setNonProxyHosts(proxyConfig.getNonProxyHosts()); - } - } + protected SecurityConfiguration securityConfig; /** * Gets the notification listener service URL for the given host @@ -342,11 +298,15 @@ public class RegistrySOAPServices { W3CEndpointReferenceBuilder endpointBuilder = new W3CEndpointReferenceBuilder(); endpointBuilder.wsdlDocumentLocation(serviceUrl.toString() + WSDL); endpointBuilder.address(serviceUrl.toString()); - W3CEndpointReference ref = endpointBuilder.build(); - T port = (T) ref.getPort(serviceInterface); + T port = (T) endpointBuilder.build().getPort(serviceInterface); Client client = ClientProxy.getClient(port); - ((HTTPConduit) client.getConduit()).setClient(httpClientPolicy); + client.getOutInterceptors().add(this.securityInterceptor); + + HTTPConduit conduit = (HTTPConduit) client.getConduit(); + conduit.setClient(serviceConfig.getHttpClientPolicy()); + conduit.setTlsClientParameters(securityConfig.getTlsParams()); + // Create HTTP header containing the calling registry Map> headers = new HashMap>(); headers.put(RegistryUtil.CALLING_REGISTRY_SOAP_HEADER_NAME, @@ -355,23 +315,15 @@ public class RegistrySOAPServices { return port; } - /** - * Gets the proxy configuration - * - * @return The proxy configuration - */ - protected static ProxyConfiguration getProxyConfiguration() { - ProxyConfiguration proxyConfig = null; - File proxyFile = PathManagerFactory.getPathManager().getStaticFile( - "datadelivery" + File.separator + "proxy.properties"); - if (proxyFile != null) { - try { - proxyConfig = ProxyUtil.getProxySettings(proxyFile); - } catch (IOException e) { - throw new RegistryServiceException( - "Error reading proxy properties", e); - } - } - return proxyConfig; + public void setSecurityInterceptor(WSS4JOutInterceptor securityInterceptor) { + this.securityInterceptor = securityInterceptor; + } + + public void setServiceConfig(RegistryServiceConfiguration serviceConfig) { + this.serviceConfig = serviceConfig; + } + + public void setSecurityConfig(SecurityConfiguration securityConfig) { + this.securityConfig = securityConfig; } } diff --git a/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistryServiceConfiguration.java b/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistryServiceConfiguration.java new file mode 100644 index 0000000000..36b1e3c88b --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/services/RegistryServiceConfiguration.java @@ -0,0 +1,121 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.registry.services; + +import java.io.File; +import java.io.IOException; + +import org.apache.cxf.transports.http.configuration.ConnectionType; +import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; + +import com.raytheon.uf.common.comm.ProxyConfiguration; +import com.raytheon.uf.common.comm.ProxyUtil; +import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.time.util.TimeUtil; + +/** + * + * Class containing configuration items for registry soap and rest services + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 6/5/2014     1712        bphillip    Initial coding
+ * 
+ * + * @author bphillip + * @version 1 + */ +public class RegistryServiceConfiguration { + + /** The logger */ + private static final IUFStatusHandler statusHandler = UFStatus + .getHandler(RegistryServiceConfiguration.class); + + /** Default timeout for receiving HTTP data */ + private static final String DEFAULT_RECEIVE_TIMEOUT = "60000"; + + /** Default value for establishing an HTTP connection */ + private static final String DEFAULT_CONNECT_TIMEOUT = "10000"; + + /** The HTTP Communication policy configuration */ + private HTTPClientPolicy httpClientPolicy; + + /** The proxy configuration */ + private ProxyConfiguration proxyConfig; + + /** + * Gets the HTTP communication policy. + * + * @return The HTTP communication policy + */ + public HTTPClientPolicy getHttpClientPolicy() { + if (httpClientPolicy == null) { + initHttpClientPolicy(); + } + return httpClientPolicy; + } + + /** + * Initializes the HTTP communication policy + */ + private void initHttpClientPolicy() { + initProxyConfiguration(); + httpClientPolicy = new HTTPClientPolicy(); + httpClientPolicy.setReceiveTimeout(Long.parseLong(System.getProperty( + "ebxml-http-receive-timeout", DEFAULT_RECEIVE_TIMEOUT))); + httpClientPolicy.setConnectionTimeout(Long.parseLong(System + .getProperty("ebxml-http-connection-timeout", + DEFAULT_CONNECT_TIMEOUT))); + + httpClientPolicy.setConnection(ConnectionType.CLOSE); + httpClientPolicy.setMaxRetransmits(5); + if (proxyConfig != null) { + httpClientPolicy.setProxyServer(proxyConfig.getHost()); + httpClientPolicy.setProxyServerPort(proxyConfig.getPort()); + httpClientPolicy.setNonProxyHosts(proxyConfig.getNonProxyHosts()); + } + } + + /** + * Gets the proxy configuration + * + * @return The proxy configuration + */ + private void initProxyConfiguration() { + if (proxyConfig == null) { + File proxyFile = PathManagerFactory.getPathManager().getStaticFile( + "datadelivery" + File.separator + "proxy.properties"); + if (proxyFile != null) { + try { + proxyConfig = ProxyUtil.getProxySettings(proxyFile); + } catch (IOException e) { + throw new RegistryServiceException( + "Error reading proxy properties", e); + } + } + } + } +} diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/META-INF/MANIFEST.MF index 7231b51b28..bdc2612d43 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/META-INF/MANIFEST.MF @@ -33,7 +33,9 @@ Require-Bundle: com.raytheon.uf.common.registry.schemas.ebxml;bundle-version="1. uk.ltd.getahead;bundle-version="1.0.0", javax.mail;bundle-version="1.0.0", org.apache.commons.validator;bundle-version="1.2.0", - com.sun.xml.bind;bundle-version="1.0.0" + com.sun.xml.bind;bundle-version="1.0.0", + org.eclipse.jetty;bundle-version="7.6.14", + com.raytheon.uf.edex.security;bundle-version="1.14.0" Export-Package: com.raytheon.uf.edex.registry.ebxml.acp, com.raytheon.uf.edex.registry.ebxml.dao, com.raytheon.uf.edex.registry.ebxml.exception, @@ -49,6 +51,7 @@ Export-Package: com.raytheon.uf.edex.registry.ebxml.acp, com.raytheon.uf.edex.registry.ebxml.util, com.raytheon.uf.edex.registry.ebxml.util.xpath, com.raytheon.uf.edex.registry.ebxml.web, + com.raytheon.uf.edex.registry.ebxml.web.security, com.raytheon.uf.edex.registry.events Import-Package: javax.servlet, javax.servlet.http diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-thrift-client.xml b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-thrift-client.xml index 519502ef87..d59c24bf7e 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-thrift-client.xml +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-thrift-client.xml @@ -18,6 +18,6 @@ - + diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-webserver.xml b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-webserver.xml index ec2f01c97d..78c648ddf7 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-webserver.xml +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-webserver.xml @@ -2,52 +2,10 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-webservices.xml b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-webservices.xml index 6a7fbb2afe..39ec5836c9 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-webservices.xml +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-webservices.xml @@ -1,24 +1,77 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - + + + + @@ -28,7 +81,7 @@ - + @@ -40,8 +93,8 @@ - - + + diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml.xml b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml.xml index a062e3713d..13060469d9 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml.xml +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml.xml @@ -5,23 +5,8 @@ - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/resources/com.raytheon.uf.edex.registry.ebxml.properties b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/resources/com.raytheon.uf.edex.registry.ebxml.properties index 99492c50ac..c1fd7bfee6 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/resources/com.raytheon.uf.edex.registry.ebxml.properties +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/resources/com.raytheon.uf.edex.registry.ebxml.properties @@ -13,4 +13,28 @@ ebxml-notification-batch-size=200 # The maximum number of threads that the ebxml registry will use for processing web requests # This number must be >=5. As a general rule, the maximum number of connections should be: # 5+{registries this registry is replicating to/from}=max-threads -ebxml-webserver-max-threads=8 \ No newline at end of file +ebxml-webserver-max-threads=8 + +#### +# Registry Web server IP access control configurations +# This is a ; delimited list of IP access configurations +# +#An empty white list is treated as match all. If there is at least one entry in the white list, +#then a request must match a white list entry. Black list entries are always applied, so that +#even if an entry matches the white list, a black list entry will override it. +# +#Internet address specification is separated from the URI pattern using the "|" (pipe) character. +#URI patterns follow the servlet specification for simple * prefix and suffix wild +#cards (e.g. /, /foo, /foo/bar, /foo/bar/*, *.baz). +# +#Examples of the entry specifications are: +# +# 10.10.1.2 - all requests from IP 10.10.1.2 +# 10.10.1.2|/foo/bar - all requests from IP 10.10.1.2 to URI /foo/bar +# 10.10.1.2|/foo/* - all requests from IP 10.10.1.2 to URIs starting with /foo/ +# 10.10.1.2|*.html - all requests from IP 10.10.1.2 to URIs ending with .html +# 10.10.0-255.0-255 - all requests from IPs within 10.10.0.0/16 subnet +# 10.10.0-.-255|/foo/bar - all requests from IPs within 10.10.0.0/16 subnet to URI /foo/bar +# 10.10.0-3,1,3,7,15|/foo/* - all requests from IPs addresses with last octet equal to 1,3,7,15 in subnet 10.10.0.0/22 to URIs starting with /foo/ +ebxml-webserver-ip-whitelist= +ebxml-webserver-ip-blacklist= \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/web/RegistryWebServer.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/web/RegistryWebServer.java new file mode 100644 index 0000000000..cab4a64b14 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/web/RegistryWebServer.java @@ -0,0 +1,123 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.edex.registry.ebxml.web; + +import java.io.FileInputStream; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.xml.XmlConfiguration; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; +import com.raytheon.uf.edex.registry.ebxml.init.RegistryInitializedListener; +import com.raytheon.uf.edex.security.SecurityConfiguration; + +/** + * + * Wrapper for the Registry web server + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 6/5/2014     1712        bphillip    Initial Creation
+ * 
+ * + * @author bphillip + * @version 1 + **/ +public class RegistryWebServer implements RegistryInitializedListener { + + /** The logger instance */ + protected static final IUFStatusHandler statusHandler = UFStatus + .getHandler(RegistryWebServer.class); + + /** The jetty server instance */ + private final Server jettyServer; + + /** + * Creates a new Jetty Server with the given configuration file + * + * @param jettyConfigFile + * The Jetty configuration file + * @throws Exception + * If errors occur while configuring the Jetty Server + */ + public RegistryWebServer(String jettyConfigFile, SecurityConfiguration securityConfiguration) throws Exception { + try { + statusHandler.info("Configuring registry web server from file [" + + jettyConfigFile + "]"); + FileInputStream fis = null; + try { + // Temporarily add the security properties to the java properties so it can be configured properly + System.getProperties().putAll(securityConfiguration.getSecurityProperties()); + fis = new FileInputStream(jettyConfigFile); + XmlConfiguration configuration = new XmlConfiguration(fis); + jettyServer = (Server) configuration.configure(); + } finally { + // Remove the security properties from the environment + for(Object property: securityConfiguration.getSecurityProperties().keySet()){ + System.getProperties().remove(property); + } + if (fis != null) { + fis.close(); + } + } + statusHandler.info("Registry web server configured!"); + Runtime.getRuntime().addShutdownHook(new Thread() { + public void run() { + statusHandler.info("Stopping Registry web server..."); + try { + if (jettyServer != null && jettyServer.isRunning()) { + jettyServer.stop(); + } + } catch (Exception e) { + statusHandler.error( + "Error shutting down Registry Web Server!", e); + } + statusHandler.info("Registry web server stopped."); + } + }); + } catch (Exception e) { + throw new EbxmlRegistryException( + "Error starting registry web server!", e); + } + } + + @Override + public void executeAfterRegistryInit() throws EbxmlRegistryException { + statusHandler.info("Starting Registry web server..."); + try { + jettyServer.start(); + } catch (Exception e) { + throw new EbxmlRegistryException( + "Error starting Registry web server!", e); + } + statusHandler.info("Registry web server started!"); + } + + public Server getJettyServer() { + return jettyServer; + } + +} diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/web/security/RegistryIPAccessHandler.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/web/security/RegistryIPAccessHandler.java new file mode 100644 index 0000000000..57eea89e41 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/web/security/RegistryIPAccessHandler.java @@ -0,0 +1,59 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.edex.registry.ebxml.web.security; + +import org.eclipse.jetty.server.handler.IPAccessHandler; + +/** + * + * IP Access handler class used by Jetty to control white/black list IPs + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 2/27/2014    1712       bphillip    Initial Creation
+ * 
+ * + * @author bphillip + * @version 1 + **/ +public class RegistryIPAccessHandler extends IPAccessHandler { + + private static final String DELIMITER = ";"; + + private static final String WHITELIST_PROPERTY = "ebxml-webserver-ip-whitelist"; + + private static final String BLACKLIST_PROPERTY = "ebxml-webserver-ip-blacklist"; + + public void setIPAccessControl() { + String whiteList = System.getProperty(WHITELIST_PROPERTY); + if (whiteList != null && !whiteList.trim().isEmpty()) { + setWhite(whiteList.split(DELIMITER)); + } + + String blackList = System.getProperty(BLACKLIST_PROPERTY); + if (blackList != null && !blackList.trim().isEmpty()) { + setBlack(blackList.split(DELIMITER)); + } + } +} diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/web/security/SslNetworkTrafficSelectChannelConnector.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/web/security/SslNetworkTrafficSelectChannelConnector.java new file mode 100644 index 0000000000..5dd13a1620 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/web/security/SslNetworkTrafficSelectChannelConnector.java @@ -0,0 +1,97 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.edex.registry.ebxml.web.security; + +import java.io.IOException; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.eclipse.jetty.io.NetworkTrafficListener; +import org.eclipse.jetty.io.nio.NetworkTrafficSelectChannelEndPoint; +import org.eclipse.jetty.io.nio.SelectChannelEndPoint; +import org.eclipse.jetty.io.nio.SelectorManager; +import org.eclipse.jetty.server.ssl.SslSelectChannelConnector; +import org.eclipse.jetty.util.ssl.SslContextFactory; + +/** + * + * Custom SSL connector for logging traffic. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 3/27/2014    1712       bphillip    Initial Creation
+ * 
+ * + * @author bphillip + * @version 1 + **/ +public class SslNetworkTrafficSelectChannelConnector extends + SslSelectChannelConnector { + private final List listeners = new CopyOnWriteArrayList(); + + public SslNetworkTrafficSelectChannelConnector() { + super(); + } + + public SslNetworkTrafficSelectChannelConnector( + SslContextFactory sslContextFactory) { + super(sslContextFactory); + } + + /** + * @param listener + * the listener to add + */ + public void addNetworkTrafficListener(NetworkTrafficListener listener) { + listeners.add(listener); + } + + /** + * @param listener + * the listener to remove + */ + public void removeNetworkTrafficListener(NetworkTrafficListener listener) { + listeners.remove(listener); + } + + @Override + protected SelectChannelEndPoint newEndPoint(SocketChannel channel, + SelectorManager.SelectSet selectSet, SelectionKey key) + throws IOException { + NetworkTrafficSelectChannelEndPoint endPoint = new NetworkTrafficSelectChannelEndPoint( + channel, selectSet, key, _maxIdleTime, listeners); + endPoint.setConnection(selectSet.getManager().newConnection(channel, + endPoint, key.attachment())); + endPoint.notifyOpened(); + return endPoint; + } + + @Override + protected void endPointClosed(SelectChannelEndPoint endpoint) { + super.endPointClosed(endpoint); + ((NetworkTrafficSelectChannelEndPoint) endpoint).notifyClosed(); + } +} diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/etc/jettyServer.xml b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/etc/jettyServer.xml new file mode 100644 index 0000000000..785fd2a55a --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/etc/jettyServer.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + 500 + + + 5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 30000 + + + + + + + + + + + + + + WEB-INF/web.xml + + + + / + true + + + + + + java. + javax. + org. + com. + gov. + ch. + net. + edu. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/registry/registryUtil.js b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/registry/registryUtil.js index 41ec5d9945..772e578230 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/registry/registryUtil.js +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/registry/registryUtil.js @@ -31,7 +31,7 @@ Date Ticket# Engineer Description */ function callRestService(url,arg){ - var url = "http://"+window.location.host+"/"+url + var url = "https://"+window.location.host+"/"+url if(arg != null){ url+="/"+arg; } diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/webServiceBeans.xml b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/webServiceBeans.xml index 3d2d89fd56..17ff73d454 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/webServiceBeans.xml +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/webServiceBeans.xml @@ -1,7 +1,9 @@ + http://www.springframework.org/schema/context/spring-context-3.1.xsd + http://cxf.apache.org/transports/http/configuration + http://cxf.apache.org/schemas/configuration/http-conf.xsd + http://cxf.apache.org/transports/http-jetty/configuration + http://cxf.apache.org/schemas/configuration/http-jetty.xsd + http://cxf.apache.org/configuration/security + http://cxf.apache.org/schemas/configuration/security.xsd"> - + + @@ -27,9 +36,9 @@ - + - + diff --git a/edexOsgi/com.raytheon.uf.edex.registry.feature/feature.xml b/edexOsgi/com.raytheon.uf.edex.registry.feature/feature.xml index 437e873a82..d255eb30c6 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.feature/feature.xml +++ b/edexOsgi/com.raytheon.uf.edex.registry.feature/feature.xml @@ -17,8 +17,6 @@ [Enter License Description here.] - - + + diff --git a/edexOsgi/com.raytheon.uf.edex.security/.classpath b/edexOsgi/com.raytheon.uf.edex.security/.classpath new file mode 100644 index 0000000000..9eb1185297 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.security/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/edexOsgi/com.raytheon.uf.edex.security/.project b/edexOsgi/com.raytheon.uf.edex.security/.project new file mode 100644 index 0000000000..3813f1c56c --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.security/.project @@ -0,0 +1,28 @@ + + + com.raytheon.uf.edex.security + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/edexOsgi/com.raytheon.uf.edex.security/.settings/org.eclipse.jdt.core.prefs b/edexOsgi/com.raytheon.uf.edex.security/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..f42de363af --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.security/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/edexOsgi/com.raytheon.uf.edex.security/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.edex.security/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..1560df5dd4 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.security/META-INF/MANIFEST.MF @@ -0,0 +1,13 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Security +Bundle-SymbolicName: com.raytheon.uf.edex.security +Bundle-Version: 1.14.0.qualifier +Bundle-Vendor: RAYTHEON +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Require-Bundle: org.eclipse.jetty;bundle-version="7.6.14", + com.raytheon.uf.edex.core;bundle-version="1.14.0", + com.raytheon.uf.common.util;bundle-version="1.14.0", + com.raytheon.uf.common.status;bundle-version="1.12.1174", + org.apache.commons.cxf;bundle-version="2.7.11" +Export-Package: com.raytheon.uf.edex.security diff --git a/edexOsgi/com.raytheon.uf.edex.security/build.properties b/edexOsgi/com.raytheon.uf.edex.security/build.properties new file mode 100644 index 0000000000..5791d48d5f --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.security/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + res/ diff --git a/edexOsgi/com.raytheon.uf.edex.security/res/spring/edex-security.xml b/edexOsgi/com.raytheon.uf.edex.security/res/spring/edex-security.xml new file mode 100644 index 0000000000..0a2c534915 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.security/res/spring/edex-security.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.security/src/com/raytheon/uf/edex/security/EncryptedProperties.java b/edexOsgi/com.raytheon.uf.edex.security/src/com/raytheon/uf/edex/security/EncryptedProperties.java new file mode 100644 index 0000000000..edaed64a5f --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.security/src/com/raytheon/uf/edex/security/EncryptedProperties.java @@ -0,0 +1,84 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.edex.security; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Properties; + +import org.eclipse.jetty.util.security.Password; + +/** + * + * Class used with the WSS4j interceptors. This class extends the java + * Properties class to allow obfuscated properties to be contained in the + * properties file. The properties may be obfuscated using Jetty's obfuscation + * methods. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 6/5/2014     1712        bphillip    Initial Creation
+ * 
+ * + * @author bphillip + * @version 1 + * @see org.eclipse.jetty.util.security.Password.obfuscate(String) + * @see org.eclipse.jetty.util.security.Password.deobfuscate(String) + **/ +public class EncryptedProperties extends Properties { + + private static final long serialVersionUID = -8799654229761166379L; + + /** The prefix prepended to an obfuscated property */ + private static final String OBFUSCATED_PREFIX = "OBF:"; + + /** + * Creates a new EncryptedProperties object + * + * @param filename + * The file containing the properties + * @throws IOException + * If errors occur while reading the properties file + */ + public EncryptedProperties(String filename) throws IOException { + FileInputStream fis = null; + try { + fis = new FileInputStream(filename); + load(fis); + } finally { + if (fis != null) { + fis.close(); + } + } + } + + public String getProperty(String propertyName){ + String property = super.getProperty(propertyName); + if (property != null + && property.startsWith(OBFUSCATED_PREFIX)) { + return Password.deobfuscate(property); + } + return property; + } +} diff --git a/edexOsgi/com.raytheon.uf.edex.security/src/com/raytheon/uf/edex/security/SecurityConfiguration.java b/edexOsgi/com.raytheon.uf.edex.security/src/com/raytheon/uf/edex/security/SecurityConfiguration.java new file mode 100644 index 0000000000..c297441931 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.security/src/com/raytheon/uf/edex/security/SecurityConfiguration.java @@ -0,0 +1,191 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.edex.security; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.security.KeyStore; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.TrustManagerFactory; + +import org.apache.cxf.configuration.jsse.TLSClientParameters; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.edex.core.modes.EDEXModesUtil; + +/** + * + * Object containing the security configuration items. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 6/5/2014     1712        bphillip    Initial Creation
+ * 
+ * + * @author bphillip + * @version 1 + **/ +public class SecurityConfiguration { + + /** The logger instance */ + private static final IUFStatusHandler statusHandler = UFStatus + .getHandler(SecurityConfiguration.class); + + /** The directory containing security related files such as keystores */ + private static final String SECURITY_DIR = EDEXModesUtil.CONF_DIR + + File.separator + "security" + File.separator; + + /** The properties file containing the security configuration items */ + private static final String SECURITY_PROPERTIES_FILE = SECURITY_DIR + + "security.properties"; + + /** Properties object for the security configuration */ + private EncryptedProperties securityProperties; + + /** The https configuration */ + private TLSClientParameters tlsParams; + + /** Keystore factory */ + private KeyManagerFactory kmf; + + /** Trust store factory */ + private TrustManagerFactory tmf; + + /** + * Creates and initializes a new Security configuration object based on the + * security properties specified + * @throws IOException + */ + public SecurityConfiguration() throws IOException { + securityProperties = new EncryptedProperties(SECURITY_PROPERTIES_FILE); + initKeyStore(); + initTrustStore(); + initTLSParams(); + } + + /** + * Initializes the TLS parameters + */ + private void initTLSParams() { + tlsParams = new TLSClientParameters(); + tlsParams.setKeyManagers(kmf.getKeyManagers()); + tlsParams.setTrustManagers(tmf.getTrustManagers()); + tlsParams.setDisableCNCheck(Boolean + .parseBoolean(getProperty("edex.security.disableCNCheck"))); + } + + /** + * Initializes the keystore + */ + private void initKeyStore() { + FileInputStream fis = null; + KeyStore keystore = null; + char[] storepass = getProperty("edex.security.keystore.password").toCharArray(); + + try { + kmf = KeyManagerFactory + .getInstance(getProperty("edex.security.keystore.algorithm")); + fis = new FileInputStream( + getProperty("edex.security.keystore.path")); + keystore = KeyStore + .getInstance(getProperty("edex.security.keystore.type")); + keystore.load(fis, storepass); + kmf.init(keystore, storepass); + } catch (Exception e) { + throw new SecurityException("Error initializing keystore", e); + } finally { + if (fis != null) { + try { + fis.close(); + } catch (IOException e) { + throw new RuntimeException( + "Error closing file input stream!", e); + } + } + } + } + + /** + * Initializes the trust store + */ + private void initTrustStore() { + FileInputStream fis = null; + KeyStore truststore = null; + char[] storepass = getProperty("edex.security.truststore.password").toCharArray(); + + try { + tmf = TrustManagerFactory + .getInstance(getProperty("edex.security.truststore.algorithm")); + fis = new FileInputStream( + getProperty("edex.security.truststore.path")); + truststore = KeyStore + .getInstance(getProperty("edex.security.truststore.type")); + truststore.load(fis, storepass); + tmf.init(truststore); + } catch (Exception e) { + throw new SecurityException("Error initializing truststore", e); + } finally { + if (fis != null) { + try { + fis.close(); + } catch (IOException e) { + throw new RuntimeException( + "Error closing file input stream!", e); + } + } + } + } + + /** + * Gets a security property. + * @param propertyName The name of the property to get + * @return The property value + */ + private String getProperty(String propertyName) { + String prop = securityProperties.getProperty(propertyName); + if (prop == null || prop.trim().isEmpty()) { + throw new SecurityException("Required property not set: " + + propertyName); + } + return prop; + } + + /** + * Gets the TLSClientParameters + * + * @return The TLSClientParameters + */ + public TLSClientParameters getTlsParams() { + return tlsParams; + } + + public EncryptedProperties getSecurityProperties() { + return securityProperties; + } + + +}