From c410c7a35b4aa78e7c35d11a72cc96ff932df982 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Fri, 3 Mar 2017 09:19:58 +0100 Subject: [PATCH 1/2] Renamed getEndpointAttribute(). The getEndpointAttribute() in JSSSocketFactory has been renamed to getProperty() for clarity. --- .../tomcat/util/net/jss/JSSSocketFactory.java | 44 +++++++++++----------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/org/apache/tomcat/util/net/jss/JSSSocketFactory.java b/src/org/apache/tomcat/util/net/jss/JSSSocketFactory.java index ebf5505..bc096c1 100644 --- a/src/org/apache/tomcat/util/net/jss/JSSSocketFactory.java +++ b/src/org/apache/tomcat/util/net/jss/JSSSocketFactory.java @@ -377,7 +377,7 @@ public class JSSSocketFactory implements } public void setSSLCiphers(String attr) throws SocketException, IOException { - String ciphers = getEndpointAttribute(attr); + String ciphers = getProperty(attr); if (StringUtils.isEmpty(ciphers)) { debugWrite("JSSSocketFactory setSSLCiphers: " + attr + " not found"); return; @@ -451,7 +451,7 @@ public class JSSSocketFactory implements * parameter is ignored. */ public void setSSLOptions() throws SocketException, IOException { - String options = getEndpointAttribute("sslOptions"); + String options = getProperty("sslOptions"); if (StringUtils.isEmpty(options)) { debugWrite("no sslOptions specified"); return; @@ -562,7 +562,7 @@ public class JSSSocketFactory implements return -1; } - String getEndpointAttribute(String tag) { + String getProperty(String tag) { // check /conf/server.xml String value = (String)endpoint.getAttribute(tag); @@ -575,8 +575,8 @@ public class JSSSocketFactory implements return value; } - String getEndpointAttribute(String tag, String defaultValue) { - String value = getEndpointAttribute(tag); + String getProperty(String tag, String defaultValue) { + String value = getProperty(tag); if (value == null) { return defaultValue; } @@ -585,7 +585,7 @@ public class JSSSocketFactory implements void init() throws IOException { // debug enabled? - String deb = getEndpointAttribute("debug"); + String deb = getProperty("debug"); if (StringUtils.equals(deb, "true")) { debug = true; debugFile = new FileWriter("/tmp/tomcatjss.log", true); @@ -613,14 +613,14 @@ public class JSSSocketFactory implements // MUST look for "clientauth" (ALL lowercase) since "clientAuth" // (camel case) has already been processed by Tomcat 7 - String clientAuthStr = getEndpointAttribute("clientauth"); + String clientAuthStr = getProperty("clientauth"); if (clientAuthStr == null) { debugWrite("JSSSocketFactory init - \"clientauth\" not found, default to want."); clientAuthStr = "want"; } File file = null; try { - mServerCertNickPath = getEndpointAttribute("serverCertNickFile"); + mServerCertNickPath = getProperty("serverCertNickFile"); if (mServerCertNickPath == null) { throw new IOException("serverCertNickFile not specified"); } @@ -656,7 +656,7 @@ public class JSSSocketFactory implements "JSSSocketFactory: no serverCertNickFile defined"); } - // serverCertNick = (String)getEndpointAttribute("serverCert"); + // serverCertNick = (String)getProperty("serverCert"); if (clientAuthStr.equalsIgnoreCase("true") || clientAuthStr.equalsIgnoreCase("yes")) { requireClientAuth = true; @@ -670,7 +670,7 @@ public class JSSSocketFactory implements && ocspConfigured == false) { debugWrite("JSSSocketFactory init - checking for OCSP settings. \n"); boolean enableOCSP = false; - String doOCSP = getEndpointAttribute("enableOCSP"); + String doOCSP = getProperty("enableOCSP"); debugWrite("JSSSocketFactory init - doOCSP flag:" + doOCSP + " \n"); @@ -682,10 +682,10 @@ public class JSSSocketFactory implements + "\n"); if (enableOCSP == true) { - String ocspResponderURL = getEndpointAttribute("ocspResponderURL"); + String ocspResponderURL = getProperty("ocspResponderURL"); debugWrite("JSSSocketFactory init - ocspResponderURL " + ocspResponderURL + "\n"); - String ocspResponderCertNickname = getEndpointAttribute( + String ocspResponderCertNickname = getProperty( "ocspResponderCertNickname"); debugWrite("JSSSocketFactory init - ocspResponderCertNickname" + ocspResponderCertNickname + "\n"); @@ -700,9 +700,9 @@ public class JSSSocketFactory implements int ocspMinCacheEntryDuration_i = 3600; int ocspMaxCacheEntryDuration_i = 86400; - String ocspCacheSize = getEndpointAttribute("ocspCacheSize"); - String ocspMinCacheEntryDuration = getEndpointAttribute("ocspMinCacheEntryDuration"); - String ocspMaxCacheEntryDuration = getEndpointAttribute("ocspMaxCacheEntryDuration"); + String ocspCacheSize = getProperty("ocspCacheSize"); + String ocspMinCacheEntryDuration = getProperty("ocspMinCacheEntryDuration"); + String ocspMaxCacheEntryDuration = getProperty("ocspMaxCacheEntryDuration"); if (ocspCacheSize != null || ocspMinCacheEntryDuration != null @@ -729,7 +729,7 @@ public class JSSSocketFactory implements } // defualt to 60 seconds; - String ocspTimeout = getEndpointAttribute("ocspTimeout"); + String ocspTimeout = getProperty("ocspTimeout"); if (ocspTimeout != null) { debugWrite("JSSSocketFactory init - ocspTimeout= \n" + ocspTimeout); int ocspTimeout_i = Integer.parseInt(ocspTimeout); @@ -760,7 +760,7 @@ public class JSSSocketFactory implements // 12 hours = 43200 seconds SSLServerSocket.configServerSessionIDCache(0, 43200, 43200, null); - String strictCiphersStr = getEndpointAttribute("strictCiphers"); + String strictCiphersStr = getProperty("strictCiphers"); if (StringUtils.equalsIgnoreCase(strictCiphersStr, "true") || StringUtils.equalsIgnoreCase(strictCiphersStr, "yes")) { mStrictCiphers = true; @@ -773,7 +773,7 @@ public class JSSSocketFactory implements debugWrite("SSSocketFactory init - before setSSLCiphers, strictCiphers is false\n"); } - String sslVersionRangeStream = getEndpointAttribute("sslVersionRangeStream"); + String sslVersionRangeStream = getProperty("sslVersionRangeStream"); if ((sslVersionRangeStream != null) && !sslVersionRangeStream.equals("")) { debugWrite("SSSocketFactory init - calling setSSLVersionRangeDefault() for type STREAM\n"); @@ -783,7 +783,7 @@ public class JSSSocketFactory implements debugWrite("SSSocketFactory init - after setSSLVersionRangeDefault() for type STREAM\n"); } - String sslVersionRangeDatagram = getEndpointAttribute("sslVersionRangeDatagram"); + String sslVersionRangeDatagram = getProperty("sslVersionRangeDatagram"); if ((sslVersionRangeDatagram != null) && !sslVersionRangeDatagram.equals("")) { debugWrite("SSSocketFactory init - calling setSSLVersionRangeDefault() for type DATA_GRAM\n"); @@ -854,11 +854,11 @@ public class JSSSocketFactory implements private void initializePasswordStore() throws InstantiationException, IllegalAccessException, ClassNotFoundException, IOException { - mPwdClass = getEndpointAttribute("passwordClass"); + mPwdClass = getProperty("passwordClass"); if (mPwdClass == null) { throw new IOException("Misconfiguration: passwordClass is not defined"); } - mPwdPath = getEndpointAttribute("passwordFile"); + mPwdPath = getProperty("passwordFile"); mPasswordStore = (IPasswordStore) Class.forName(mPwdClass).newInstance(); debugWrite("JSSSocketFactory init - password reader initialized\n"); @@ -869,7 +869,7 @@ public class JSSSocketFactory implements private CryptoManager getCryptoManager() throws KeyDatabaseException, CertDatabaseException, GeneralSecurityException, NotInitializedException, IOException { - String certDir = getEndpointAttribute("certdbDir"); + String certDir = getProperty("certdbDir"); if (certDir == null) { throw new IOException("Misconfiguration: certdir not defined"); } -- 1.8.3.1 From 7612272aa337c413ac4b96cd13d5a1384b80b5aa Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Fri, 27 Jan 2017 04:31:41 +0100 Subject: [PATCH 2/2] Added SSLSocketListener registry. A new TomcatJSS class has been added as a mechanism to register SSLSocketListeners for all SSLSockets created by TomcatJSS. https://pagure.io/tomcatjss/issue/4 --- .../tomcat/util/net/jss/JSSSocketFactory.java | 4 ++ src/org/apache/tomcat/util/net/jss/TomcatJSS.java | 69 ++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 src/org/apache/tomcat/util/net/jss/TomcatJSS.java diff --git a/src/org/apache/tomcat/util/net/jss/JSSSocketFactory.java b/src/org/apache/tomcat/util/net/jss/JSSSocketFactory.java index bc096c1..4992600 100644 --- a/src/org/apache/tomcat/util/net/jss/JSSSocketFactory.java +++ b/src/org/apache/tomcat/util/net/jss/JSSSocketFactory.java @@ -934,6 +934,10 @@ public class JSSSocketFactory implements SSLSocket asock = null; try { asock = (SSLSocket) socket.accept(); + + TomcatJSS tomcatjss = TomcatJSS.getInstance(); + asock.addSocketListener(tomcatjss); + if (wantClientAuth || requireClientAuth) { asock.requestClientAuth(true); if (requireClientAuth == true) { diff --git a/src/org/apache/tomcat/util/net/jss/TomcatJSS.java b/src/org/apache/tomcat/util/net/jss/TomcatJSS.java new file mode 100644 index 0000000..9717921 --- /dev/null +++ b/src/org/apache/tomcat/util/net/jss/TomcatJSS.java @@ -0,0 +1,69 @@ +/* BEGIN COPYRIGHT BLOCK + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Copyright (C) 2017 Red Hat, Inc. + * All rights reserved. + * END COPYRIGHT BLOCK */ + +package org.apache.tomcat.util.net.jss; + +import java.util.ArrayList; +import java.util.Collection; + +import org.mozilla.jss.ssl.SSLAlertEvent; +import org.mozilla.jss.ssl.SSLHandshakeCompletedEvent; +import org.mozilla.jss.ssl.SSLSocketListener; + +public class TomcatJSS implements SSLSocketListener { + + public final static TomcatJSS INSTANCE = new TomcatJSS(); + + public static TomcatJSS getInstance() { return INSTANCE; } + + Collection socketListeners = new ArrayList(); + + public void addSocketListener(SSLSocketListener listener) { + socketListeners.add(listener); + } + + public void removeSocketListener(SSLSocketListener listener) { + socketListeners.remove(listener); + } + + public Collection getSocketListeners() { + return socketListeners; + } + + @Override + public void alertReceived(SSLAlertEvent event) { + for (SSLSocketListener listener : socketListeners) { + listener.alertReceived(event); + } + } + + @Override + public void alertSent(SSLAlertEvent event) { + for (SSLSocketListener listener : socketListeners) { + listener.alertSent(event); + } + } + + @Override + public void handshakeCompleted(SSLHandshakeCompletedEvent event) { + for (SSLSocketListener listener : socketListeners) { + listener.handshakeCompleted(event); + } + } +} -- 1.8.3.1