summaryrefslogtreecommitdiffstats
path: root/base/server/tomcat7
diff options
context:
space:
mode:
Diffstat (limited to 'base/server/tomcat7')
-rw-r--r--base/server/tomcat7/CMakeLists.txt10
-rw-r--r--base/server/tomcat7/conf/Catalina/localhost/ROOT.xml30
-rw-r--r--base/server/tomcat7/conf/Catalina/localhost/pki.xml30
-rw-r--r--base/server/tomcat7/conf/server.xml310
-rw-r--r--base/server/tomcat7/src/CMakeLists.txt158
-rw-r--r--base/server/tomcat7/src/com/netscape/cms/tomcat/ProxyRealm.java139
-rw-r--r--base/server/tomcat7/src/com/netscape/cms/tomcat/SSLAuthenticatorWithFallback.java172
-rw-r--r--base/server/tomcat7/src/pki-tomcat.mf3
8 files changed, 852 insertions, 0 deletions
diff --git a/base/server/tomcat7/CMakeLists.txt b/base/server/tomcat7/CMakeLists.txt
new file mode 100644
index 000000000..ba02af18d
--- /dev/null
+++ b/base/server/tomcat7/CMakeLists.txt
@@ -0,0 +1,10 @@
+project(server-tomcat7)
+
+add_subdirectory(src)
+
+install(
+ DIRECTORY
+ conf/
+ DESTINATION
+ ${DATA_INSTALL_DIR}/server/conf/
+)
diff --git a/base/server/tomcat7/conf/Catalina/localhost/ROOT.xml b/base/server/tomcat7/conf/Catalina/localhost/ROOT.xml
new file mode 100644
index 000000000..ce98bfa4e
--- /dev/null
+++ b/base/server/tomcat7/conf/Catalina/localhost/ROOT.xml
@@ -0,0 +1,30 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2012 Red Hat, Inc.
+ All rights reserved.
+ Modifications: configuration parameters
+ END COPYRIGHT BLOCK
+-->
+
+<!--
+ 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.
+-->
+<Context crossContext="true" allowLinking="true">
+
+ <Manager
+ secureRandomProvider="Mozilla-JSS" secureRandomAlgorithm="pkcs11prng"/>
+
+</Context>
diff --git a/base/server/tomcat7/conf/Catalina/localhost/pki.xml b/base/server/tomcat7/conf/Catalina/localhost/pki.xml
new file mode 100644
index 000000000..ce98bfa4e
--- /dev/null
+++ b/base/server/tomcat7/conf/Catalina/localhost/pki.xml
@@ -0,0 +1,30 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2012 Red Hat, Inc.
+ All rights reserved.
+ Modifications: configuration parameters
+ END COPYRIGHT BLOCK
+-->
+
+<!--
+ 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.
+-->
+<Context crossContext="true" allowLinking="true">
+
+ <Manager
+ secureRandomProvider="Mozilla-JSS" secureRandomAlgorithm="pkcs11prng"/>
+
+</Context>
diff --git a/base/server/tomcat7/conf/server.xml b/base/server/tomcat7/conf/server.xml
new file mode 100644
index 000000000..b9e8860b2
--- /dev/null
+++ b/base/server/tomcat7/conf/server.xml
@@ -0,0 +1,310 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2012 Red Hat, Inc.
+ All rights reserved.
+ Modifications: configuration parameters
+ END COPYRIGHT BLOCK -->
+<!--
+ 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.
+-->
+<!-- Note: A "Server" is not itself a "Container", so you may not
+ define subcomponents such as "Valves" at this level.
+ Documentation at /docs/config/server.html
+-->
+
+<!-- DO NOT REMOVE - Begin PKI Status Definitions -->
+<!-- CA Status Definitions -->
+<!--
+Unsecure URL = http://[PKI_HOSTNAME]:[PKI_UNSECURE_PORT]/ca/ee/ca
+Secure Agent URL = https://[PKI_HOSTNAME]:[PKI_AGENT_SECURE_PORT]/ca/agent/ca
+Secure EE URL = https://[PKI_HOSTNAME]:[PKI_EE_SECURE_PORT]/ca/ee/ca
+Secure Admin URL = https://[PKI_HOSTNAME]:[PKI_ADMIN_SECURE_PORT]/ca/services
+EE Client Auth URL = https://[PKI_HOSTNAME]:[PKI_EE_SECURE_CLIENT_AUTH_PORT]/ca/eeca/ca
+PKI Console Command = pkiconsole https://[PKI_HOSTNAME]:[PKI_ADMIN_SECURE_PORT]/ca
+Tomcat Port = [TOMCAT_SERVER_PORT] (for shutdown)
+-->
+<!-- KRA Status Definitions -->
+<!--
+Unsecure URL = http://[PKI_HOSTNAME]:[PKI_UNSECURE_PORT]/kra/ee/kra
+Secure Agent URL = https://[PKI_HOSTNAME]:[PKI_AGENT_SECURE_PORT]/kra/agent/kra
+Secure EE URL = https://[PKI_HOSTNAME]:[PKI_EE_SECURE_PORT]/kra/ee/kra
+Secure Admin URL = https://[PKI_HOSTNAME]:[PKI_ADMIN_SECURE_PORT]/kra/services
+PKI Console Command = pkiconsole https://[PKI_HOSTNAME]:[PKI_ADMIN_SECURE_PORT]/kra
+Tomcat Port = [TOMCAT_SERVER_PORT] (for shutdown)
+-->
+<!-- OCSP Status Definitions -->
+<!--
+Unsecure URL = http://[PKI_HOSTNAME]:[PKI_UNSECURE_PORT]/ocsp/ee/ocsp
+Secure Agent URL = https://[PKI_HOSTNAME]:[PKI_AGENT_SECURE_PORT]/ocsp/agent/ocsp
+Secure EE URL = https://[PKI_HOSTNAME]:[PKI_EE_SECURE_PORT]/ocsp/ee/ocsp
+Secure Admin URL = https://[PKI_HOSTNAME]:[PKI_ADMIN_SECURE_PORT]/ocsp/services
+PKI Console Command = pkiconsole https://[PKI_HOSTNAME]:[PKI_ADMIN_SECURE_PORT]/ocsp
+Tomcat Port = [TOMCAT_SERVER_PORT] (for shutdown)
+-->
+<!-- TKS Status Definitions -->
+<!--
+Unsecure URL = http://[PKI_HOSTNAME]:[PKI_UNSECURE_PORT]/tks/ee/tks
+Secure Agent URL = https://[PKI_HOSTNAME]:[PKI_AGENT_SECURE_PORT]/tks/agent/tks
+Secure EE URL = https://[PKI_HOSTNAME]:[PKI_EE_SECURE_PORT]/tks/ee/tks
+Secure Admin URL = https://[PKI_HOSTNAME]:[PKI_ADMIN_SECURE_PORT]/tks/services
+PKI Console Command = pkiconsole https://[PKI_HOSTNAME]:[PKI_ADMIN_SECURE_PORT]/tks
+Tomcat Port = [TOMCAT_SERVER_PORT] (for shutdown)
+-->
+<!-- DO NOT REMOVE - End PKI Status Definitions -->
+
+<Server port="[TOMCAT_SERVER_PORT]" shutdown="SHUTDOWN">
+
+ <!--APR library loader. Documentation at /docs/apr.html -->
+ <!-- The following Listener class has been commented out because this -->
+ <!-- implementation depends upon the 'tomcatjss' JSSE module, 'JSS', -->
+ <!-- and 'NSS' rather than the 'tomcat-native' module! -->
+ <!-- Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" -->
+ <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
+ <Listener className="org.apache.catalina.core.JasperListener" />
+ <!-- JMX Support for the Tomcat server. Documentation at /docs/non-existent.html -->
+ <!-- The following class has been commented out because it -->
+ <!-- has been EXCLUDED from the Tomcat 7 'tomcat-lib' RPM! -->
+ <!-- Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" -->
+ <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
+
+ <!-- Global JNDI resources
+ Documentation at /docs/jndi-resources-howto.html
+ -->
+ <GlobalNamingResources>
+ <!-- Editable user database that can also be used by
+ UserDatabaseRealm to authenticate users
+ -->
+ <Resource name="UserDatabase" auth="Container"
+ type="org.apache.catalina.UserDatabase"
+ description="User database that can be updated and saved"
+ factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
+ pathname="conf/tomcat-users.xml" />
+ </GlobalNamingResources>
+
+ <!-- A "Service" is a collection of one or more "Connectors" that share
+ a single "Container" Note: A "Service" is not itself a "Container",
+ so you may not define subcomponents such as "Valves" at this level.
+ Documentation at /docs/config/service.html
+ -->
+ <Service name="Catalina">
+
+ <!--The connectors can use a shared executor, you can define one or more named thread pools-->
+ <!--
+ <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
+ maxThreads="150" minSpareThreads="4"/>
+ -->
+
+
+ <!-- A "Connector" represents an endpoint by which requests are received
+ and responses are returned. Documentation at :
+ Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
+ Java AJP Connector: /docs/config/ajp.html
+ APR (HTTP/AJP) Connector: /docs/apr.html
+ Define a non-SSL HTTP/1.1 Connector on port 8080
+ -->
+
+ [PKI_UNSECURE_PORT_SERVER_COMMENT]
+ <Connector name="[PKI_UNSECURE_PORT_CONNECTOR_NAME]" port="[PKI_UNSECURE_PORT]" protocol="HTTP/1.1" redirectPort="[PKI_SECURE_PORT]"
+ maxHttpHeaderSize="8192"
+ acceptCount="100" maxThreads="150" minSpareThreads="25"
+ enableLookups="false" connectionTimeout="20000" disableUploadTimeout="true"
+ />
+
+ <!-- Define a SSL HTTP/1.1 Connector on port 8443 -->
+ [PKI_SECURE_PORT_SERVER_COMMENT]
+ <!-- DO NOT REMOVE - Begin define PKI secure port
+ NOTE: The following 'keys' (and their assigned values) are exclusive to
+ the 'tomcatjss' JSSE module:
+
+ 'enableOCSP'
+ 'ocspResponderURL'
+ 'ocspResponderCertNickname'
+ 'ocspCacheSize'
+ 'ocspMinCacheEntryDuration'
+ 'ocspMaxCacheEntryDuration'
+ 'ocspTimeout'
+ 'strictCiphers'
+ 'clientauth' (ALL lowercase)
+ 'sslOptions'
+ 'ssl2Ciphers'
+ 'ssl3Ciphers'
+ 'tlsCiphers'
+ 'sslVersionRangeStream'
+ 'sslVersionRangeDatagram'
+ 'sslRangeCiphers'
+ 'serverCertNickFile'
+ 'passwordFile'
+ 'passwordClass'
+ 'certdbDir'
+
+ and are referenced via the value of the 'sslImplementationName' key.
+ NOTE: The OCSP settings take effect globally, so it should only be set once.
+
+ In setup where SSL clientauth="true", OCSP can be turned on by
+ setting enableOCSP to true like the following:
+ enableOCSP="true"
+ along with changes to related settings, especially:
+ ocspResponderURL=<see example in connector definition below>
+ ocspResponderCertNickname=<see example in connector definition below>
+ Here are the definition to all the OCSP-related settings:
+ enableOCSP - turns on/off the ocsp check
+ ocspResponderURL - sets the url where the ocsp requests are sent
+ ocspResponderCertNickname - sets the nickname of the cert that is
+ either CA's signing certificate or the OCSP server's signing
+ certificate.
+ The CA's signing certificate should already be in the db, in
+ case of the same security domain.
+ In case of an ocsp signing certificate, one must import the cert
+ into the subsystem's nss db and set trust. e.g.:
+ certutil -d . -A -n "ocspSigningCert cert-pki-ca" -t "C,," -a -i ocspCert.b64
+ ocspCacheSize - sets max cache entries
+ ocspMinCacheEntryDuration - sets minimum seconds to next fetch attempt
+ ocspMaxCacheEntryDuration - sets maximum seconds to next fetch attempt
+ ocspTimeout -sets OCSP timeout in seconds
+ -->
+ <Connector name="[PKI_SECURE_PORT_CONNECTOR_NAME]" port="[PKI_SECURE_PORT]" protocol="HTTP/1.1" SSLEnabled="true" sslProtocol="SSL" scheme="https" secure="true"
+ maxHttpHeaderSize="8192"
+ acceptCount="100" maxThreads="150" minSpareThreads="25"
+ enableLookups="false" disableUploadTimeout="true"
+ sslImplementationName="org.apache.tomcat.util.net.jss.JSSImplementation"
+ enableOCSP="false"
+ ocspResponderURL="http://[PKI_HOSTNAME]:9080/ca/ocsp"
+ ocspResponderCertNickname="ocspSigningCert cert-pki-ca"
+ ocspCacheSize="1000"
+ ocspMinCacheEntryDuration="60"
+ ocspMaxCacheEntryDuration="120"
+ ocspTimeout="10"
+ strictCiphers="true"
+ clientAuth="[PKI_AGENT_CLIENTAUTH]"
+ sslOptions="[TOMCAT_SSL_OPTIONS]"
+ ssl2Ciphers="[TOMCAT_SSL2_CIPHERS]"
+ ssl3Ciphers="[TOMCAT_SSL3_CIPHERS]"
+ tlsCiphers="[TOMCAT_TLS_CIPHERS]"
+ sslVersionRangeStream="[TOMCAT_SSL_VERSION_RANGE_STREAM]"
+ sslVersionRangeDatagram="[TOMCAT_SSL_VERSION_RANGE_DATAGRAM]"
+ sslRangeCiphers="[TOMCAT_SSL_RANGE_CIPHERS]"
+ serverCertNickFile="[PKI_INSTANCE_PATH]/conf/serverCertNick.conf"
+ passwordFile="[PKI_INSTANCE_PATH]/conf/password.conf"
+ passwordClass="org.apache.tomcat.util.net.jss.PlainPasswordFile"
+ certdbDir="[PKI_INSTANCE_PATH]/alias"
+ />
+ <!-- DO NOT REMOVE - End define PKI secure port -->
+
+ <!-- Define an AJP 1.3 Connector on port [PKI_AJP_PORT] -->
+[PKI_OPEN_AJP_PORT_COMMENT]
+ <Connector port="[PKI_AJP_PORT]" protocol="AJP/1.3" redirectPort="[PKI_AJP_REDIRECT_PORT]" address="127.0.0.1" />
+[PKI_CLOSE_AJP_PORT_COMMENT]
+
+
+ <!-- An Engine represents the entry point (within Catalina) that processes
+ every request. The Engine implementation for Tomcat stand alone
+ analyzes the HTTP headers included with the request, and passes them
+ on to the appropriate Host (virtual host).
+ Documentation at /docs/config/engine.html -->
+
+ <!-- You should set jvmRoute to support load-balancing via AJP ie :
+ <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
+ -->
+ <Engine name="Catalina" defaultHost="localhost">
+
+ <!--For clustering, please take a look at documentation at:
+ /docs/cluster-howto.html (simple how to)
+ /docs/config/cluster.html (reference documentation) -->
+ <!--
+ <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
+ -->
+
+ <!-- The request dumper valve dumps useful debugging information about
+ the request and response data received and sent by Tomcat.
+ Documentation at: /docs/config/valve.html -->
+ <!--
+ <Valve className="org.apache.catalina.valves.RequestDumperValve"/>
+ -->
+
+ <!-- This Realm uses the UserDatabase configured in the global JNDI
+ resources under the key "UserDatabase". Any edits
+ that are performed against this UserDatabase are immediately
+ available for use by the Realm. -->
+
+ <!--
+ <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+ resourceName="UserDatabase"/>
+ -->
+
+ <!--
+ <Realm className="com.netscape.cmscore.realm.PKIRealm" />
+ -->
+
+ <!-- Define the default virtual host
+ Note: XML Schema validation will not work with Xerces 2.2.
+ -->
+ <Host name="localhost"
+ appBase="[PKI_INSTANCE_PATH]/webapps"
+ unpackWARs="true" autoDeploy="true"
+ xmlValidation="false" xmlNamespaceAware="false">
+
+ <!--
+ <Context path="/ca"
+ docBase="ca"
+ allowLinking="true">
+ <Loader className="org.apache.catalina.loader.VirtualWebappLoader"
+ virtualClasspath="[PKI_INSTANCE_PATH]/ca/webapps/ca/WEB-INF/classes;[PKI_INSTANCE_PATH]/ca/webapps/ca/WEB-INF/lib" />" />
+ <JarScanner scanAllDirectories="true" />
+ </Context>
+
+ <Context path="/kra"
+ docBase="kra"
+ allowLinking="true">
+ <Loader className="org.apache.catalina.loader.VirtualWebappLoader"
+ virtualClasspath="[PKI_INSTANCE_PATH]/kra/webapps/kra/WEB-INF/classes;[PKI_INSTANCE_PATH]/kra/webapps/kra/WEB-INF/lib" />
+ <JarScanner scanAllDirectories="true" />
+ </Context>
+
+ <Context path="/ocsp"
+ docBase="ocsp"
+ allowLinking="true">
+ <Loader className="org.apache.catalina.loader.VirtualWebappLoader"
+ virtualClasspath="[PKI_INSTANCE_PATH]/ocsp/webapps/ocsp/WEB-INF/classes;[PKI_INSTANCE_PATH]/ocsp/webapps/ocsp/WEB-INF/lib" />
+ <JarScanner scanAllDirectories="true" />
+ </Context>
+
+ <Context path="/tks"
+ docBase="tks"
+ allowLinking="true">
+ <Loader className="org.apache.catalina.loader.VirtualWebappLoader"
+ virtualClasspath="[PKI_INSTANCE_PATH]/tks/webapps/tks/WEB-INF/classes;[PKI_INSTANCE_PATH]/tks/webapps/tks/WEB-INF/lib" />
+ <JarScanner scanAllDirectories="true" />
+ </Context>
+ -->
+
+ <!-- SingleSignOn valve, share authentication between web applications
+ Documentation at: /docs/config/valve.html -->
+ <!--
+ <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
+ -->
+
+ <!-- Access log processes all example.
+ Documentation at: /docs/config/valve.html -->
+ [PKI_OPEN_TOMCAT_ACCESS_LOG_COMMENT]
+ <Valve className="org.apache.catalina.valves.AccessLogValve"
+ directory="logs" prefix="localhost_access_log." suffix=".txt"
+ pattern="common" resolveHosts="false"/>
+ [PKI_CLOSE_TOMCAT_ACCESS_LOG_COMMENT]
+
+ </Host>
+ </Engine>
+ </Service>
+</Server>
diff --git a/base/server/tomcat7/src/CMakeLists.txt b/base/server/tomcat7/src/CMakeLists.txt
new file mode 100644
index 000000000..102dec782
--- /dev/null
+++ b/base/server/tomcat7/src/CMakeLists.txt
@@ -0,0 +1,158 @@
+project(pki-tomcat)
+
+find_file(JSS_JAR
+ NAMES
+ jss4.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(LDAPJDK_JAR
+ NAMES
+ ldapjdk.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(COMMONS_CODEC_JAR
+ NAMES
+ commons-codec.jar
+ PATHS
+ /usr/share/java
+)
+
+find_file(COMMONS_HTTPCLIENT_JAR
+ NAMES
+ commons-httpclient.jar
+ PATHS
+ /usr/share/java
+)
+
+find_file(APACHE_COMMONS_LANG_JAR
+ NAMES
+ apache-commons-lang.jar
+ PATHS
+ /usr/share/java
+)
+
+find_file(TOMCAT_CATALINA_JAR
+ NAMES
+ catalina.jar
+ PATHS
+ /usr/share/java/tomcat
+)
+
+find_file(TOMCAT_UTIL_SCAN_JAR
+ NAMES
+ tomcat-util-scan.jar
+ PATHS
+ /usr/share/java/tomcat
+)
+
+find_file(SERVLET_JAR
+ NAMES
+ servlet.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(VELOCITY_JAR
+ NAMES
+ velocity.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(XALAN_JAR
+ NAMES
+ xalan-j2.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(XERCES_JAR
+ NAMES
+ xerces-j2.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(JAXRS_API_JAR
+ NAMES
+ jaxrs-api.jar
+ PATHS
+ ${RESTEASY_LIB}
+)
+
+find_file(RESTEASY_JAXRS_JAR
+ NAMES
+ resteasy-jaxrs.jar
+ PATHS
+ ${RESTEASY_LIB}
+)
+
+find_file(RESTEASY_ATOM_PROVIDER_JAR
+ NAMES
+ resteasy-atom-provider.jar
+ PATHS
+ ${RESTEASY_LIB}
+)
+
+find_file(HTTPCLIENT_JAR
+ NAMES
+ httpclient.jar
+ PATHS
+ /usr/share/java/httpcomponents
+)
+
+find_file(HTTPCORE_JAR
+ NAMES
+ httpcore.jar
+ PATHS
+ /usr/share/java/httpcomponents
+)
+
+# build pki-tomcat
+javac(pki-tomcat-classes
+ SOURCES
+ com/netscape/cms/tomcat/*.java
+ CLASSPATH
+ ${SERVLET_JAR} ${TOMCAT_CATALINA_JAR} ${TOMCAT_UTIL_SCAN_JAR}
+ OUTPUT_DIR
+ ${CMAKE_BINARY_DIR}/classes
+)
+
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/pki-tomcat.mf
+ ${CMAKE_CURRENT_BINARY_DIR}/pki-tomcat.mf
+)
+
+jar(pki-tomcat-jar
+ CREATE
+ ${CMAKE_BINARY_DIR}/dist/pki-tomcat.jar
+ OPTIONS
+ m
+ PARAMS
+ ${CMAKE_CURRENT_BINARY_DIR}/pki-tomcat.mf
+ INPUT_DIR
+ ${CMAKE_BINARY_DIR}/classes
+ FILES
+ com/netscape/cms/tomcat/*.class
+ DEPENDS
+ pki-tomcat-classes
+)
+
+install(
+ FILES
+ ${CMAKE_BINARY_DIR}/dist/pki-tomcat.jar
+ DESTINATION
+ ${JAVA_JAR_INSTALL_DIR}/pki
+)
+
+set(PKI_TOMCAT_JAR ${CMAKE_BINARY_DIR}/dist/pki-tomcat.jar CACHE INTERNAL "pki-tomcat jar file")
diff --git a/base/server/tomcat7/src/com/netscape/cms/tomcat/ProxyRealm.java b/base/server/tomcat7/src/com/netscape/cms/tomcat/ProxyRealm.java
new file mode 100644
index 000000000..094c0561f
--- /dev/null
+++ b/base/server/tomcat7/src/com/netscape/cms/tomcat/ProxyRealm.java
@@ -0,0 +1,139 @@
+package com.netscape.cms.tomcat;
+
+import java.beans.PropertyChangeListener;
+import java.io.IOException;
+import java.security.Principal;
+import java.security.cert.X509Certificate;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.catalina.Container;
+import org.apache.catalina.Context;
+import org.apache.catalina.Realm;
+import org.apache.catalina.Wrapper;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.deploy.SecurityConstraint;
+import org.ietf.jgss.GSSContext;
+
+/**
+ * @author Endi S. Dewata
+ */
+public class ProxyRealm implements Realm {
+
+ public static Map<String, ProxyRealm> proxies = new HashMap<String, ProxyRealm>();
+
+ public Container container;
+ public Realm realm;
+
+ public ProxyRealm() {
+ }
+
+ @Override
+ public Container getContainer() {
+ return container;
+ }
+
+ @Override
+ public void setContainer(Container container) {
+ this.container = container;
+ if (container instanceof Context) {
+ Context context = (Context)container;
+ proxies.put(context.getBaseName(), this);
+ }
+ }
+
+ public Realm getRealm() {
+ return realm;
+ }
+
+ public void setRealm(Realm realm) {
+ this.realm = realm;
+ realm.setContainer(container);
+ }
+
+ public static void registerRealm(String contextName, Realm realm) {
+ ProxyRealm proxy = proxies.get(contextName);
+ if (proxy == null) return;
+
+ proxy.setRealm(realm);
+ }
+
+ @Override
+ public Principal authenticate(String username, String password) {
+ return realm.authenticate(username, password);
+ }
+
+ @Override
+ public Principal authenticate(X509Certificate certs[]) {
+ return realm.authenticate(certs);
+ }
+
+ @Override
+ public Principal authenticate(
+ String username,
+ String digest,
+ String nonce,
+ String nc,
+ String cnonce,
+ String qop,
+ String realmName,
+ String md5a2
+ ) {
+ return realm.authenticate(username, digest, nonce, nc, cnonce, qop, realmName, md5a2);
+ }
+
+ @Override
+ public Principal authenticate(GSSContext gssContext, boolean storeCreds) {
+ return realm.authenticate(gssContext, storeCreds);
+ }
+
+ @Override
+ public boolean hasResourcePermission(
+ Request request,
+ Response response,
+ SecurityConstraint[] constraints,
+ Context context
+ ) throws IOException {
+ return realm.hasResourcePermission(request, response, constraints, context);
+ }
+
+ @Override
+ public String getInfo() {
+ return realm.getInfo();
+ }
+
+ @Override
+ public void backgroundProcess() {
+ realm.backgroundProcess();
+ }
+
+ @Override
+ public SecurityConstraint[] findSecurityConstraints(Request request, Context context) {
+ return realm.findSecurityConstraints(request, context);
+ }
+
+ @Override
+ public boolean hasRole(Wrapper wrapper, Principal principal, String role) {
+ return realm.hasRole(wrapper, principal, role);
+ }
+
+ @Override
+ public boolean hasUserDataPermission(
+ Request request,
+ Response response,
+ SecurityConstraint[] constraint
+ ) throws IOException {
+ return realm.hasUserDataPermission(request, response, constraint);
+ }
+
+ @Override
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ realm.addPropertyChangeListener(listener);
+ }
+
+ @Override
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ realm.removePropertyChangeListener(listener);
+ }
+}
diff --git a/base/server/tomcat7/src/com/netscape/cms/tomcat/SSLAuthenticatorWithFallback.java b/base/server/tomcat7/src/com/netscape/cms/tomcat/SSLAuthenticatorWithFallback.java
new file mode 100644
index 000000000..20bf85d22
--- /dev/null
+++ b/base/server/tomcat7/src/com/netscape/cms/tomcat/SSLAuthenticatorWithFallback.java
@@ -0,0 +1,172 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cms.tomcat;
+
+import java.io.IOException;
+import java.security.cert.X509Certificate;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+import org.apache.catalina.Container;
+import org.apache.catalina.Globals;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.authenticator.AuthenticatorBase;
+import org.apache.catalina.authenticator.BasicAuthenticator;
+import org.apache.catalina.authenticator.FormAuthenticator;
+import org.apache.catalina.authenticator.SSLAuthenticator;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.deploy.LoginConfig;
+
+/**
+ * @author Endi S. Dewata
+ */
+public class SSLAuthenticatorWithFallback extends AuthenticatorBase {
+
+ public final static String BASIC_AUTHENTICATOR = "BASIC";
+ public final static String FORM_AUTHENTICATOR = "FORM";
+
+ String fallbackMethod = BASIC_AUTHENTICATOR;
+
+ AuthenticatorBase sslAuthenticator = new SSLAuthenticator();
+ AuthenticatorBase fallbackAuthenticator = new BasicAuthenticator();
+
+ public SSLAuthenticatorWithFallback() {
+ log("Creating SSL authenticator with fallback");
+ }
+
+ @Override
+ public String getInfo() {
+ return "SSL authenticator with "+fallbackMethod+" fallback.";
+ }
+
+ public String getFallbackMethod() {
+ return fallbackMethod;
+ }
+
+ public void setFallbackMethod(String fallbackMethod) {
+ log("Fallback method: "+fallbackMethod);
+ this.fallbackMethod = fallbackMethod;
+
+ if (BASIC_AUTHENTICATOR.equalsIgnoreCase(fallbackMethod)) {
+ fallbackAuthenticator = new BasicAuthenticator();
+
+ } else if (FORM_AUTHENTICATOR.equalsIgnoreCase(fallbackMethod)) {
+ fallbackAuthenticator = new FormAuthenticator();
+ }
+
+ }
+
+ @Override
+ public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException {
+
+ X509Certificate certs[] = (X509Certificate[]) request.getAttribute(Globals.CERTIFICATES_ATTR);
+ boolean result;
+
+ if (certs != null && certs.length > 0) {
+ log("Authenticate with client certificate authentication");
+ HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper(response) {
+ public void setHeader(String name, String value) {
+ log("SSL auth header: "+name+"="+value);
+ };
+ public void sendError(int code) {
+ log("SSL auth return code: "+code);
+ }
+ };
+ result = sslAuthenticator.authenticate(request, wrapper, config);
+
+ } else {
+ log("Authenticating with "+fallbackMethod+" authentication");
+ HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper(response) {
+ public void setHeader(String name, String value) {
+ log("Fallback auth header: "+name+"="+value);
+ };
+ public void sendError(int code) {
+ log("Fallback auth return code: "+code);
+ }
+ };
+ result = fallbackAuthenticator.authenticate(request, wrapper, config);
+ }
+
+ if (result)
+ return true;
+
+ log("Result: "+result);
+
+ StringBuilder value = new StringBuilder(16);
+ value.append("Basic realm=\"");
+ if (config.getRealmName() == null) {
+ value.append(REALM_NAME);
+ } else {
+ value.append(config.getRealmName());
+ }
+ value.append('\"');
+ response.setHeader(AUTH_HEADER_NAME, value.toString());
+ response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+
+ return false;
+ }
+
+ @Override
+ protected String getAuthMethod() {
+ return HttpServletRequest.CLIENT_CERT_AUTH;
+ };
+
+ @Override
+ public void setContainer(Container container) {
+ log("Setting container");
+ super.setContainer(container);
+ sslAuthenticator.setContainer(container);
+ fallbackAuthenticator.setContainer(container);
+ }
+
+ @Override
+ protected void initInternal() throws LifecycleException {
+ log("Initializing authenticators");
+
+ super.initInternal();
+
+ sslAuthenticator.setAlwaysUseSession(alwaysUseSession);
+ sslAuthenticator.init();
+
+ fallbackAuthenticator.setAlwaysUseSession(alwaysUseSession);
+ fallbackAuthenticator.init();
+ }
+
+ @Override
+ public void startInternal() throws LifecycleException {
+ log("Starting authenticators");
+ super.startInternal();
+ sslAuthenticator.start();
+ fallbackAuthenticator.start();
+ }
+
+ @Override
+ public void stopInternal() throws LifecycleException {
+ log("Stopping authenticators");
+ super.stopInternal();
+ sslAuthenticator.stop();
+ fallbackAuthenticator.stop();
+ }
+
+ public void log(String message) {
+ System.out.println("SSLAuthenticatorWithFallback: "+message);
+ }
+}
diff --git a/base/server/tomcat7/src/pki-tomcat.mf b/base/server/tomcat7/src/pki-tomcat.mf
new file mode 100644
index 000000000..ca8d3bf1b
--- /dev/null
+++ b/base/server/tomcat7/src/pki-tomcat.mf
@@ -0,0 +1,3 @@
+Name: pki-tomcat
+Specification-Version: ${APPLICATION_VERSION}
+Implementation-Version: ${VERSION}