📄 ssladapter.java
字号:
/** * Copyright (c) 2000/2001 Thomas Kopp * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */// $Id: SSLAdapter.java,v 1.6 2004/02/10 14:32:49 ylafon Exp $package org.w3c.jigsaw.https;import java.lang.reflect.Method;import java.net.MalformedURLException;import java.net.URL;import java.util.StringTokenizer;import java.security.cert.Certificate;import java.security.cert.X509Certificate;import javax.net.ssl.SSLPeerUnverifiedException;import javax.net.ssl.SSLSession;import javax.net.ssl.SSLSocket;import org.w3c.jigsaw.daemon.ServerHandlerInitException;import org.w3c.jigsaw.auth.AuthFilter;import org.w3c.jigsaw.http.httpd;import org.w3c.jigsaw.http.Client;import org.w3c.jigsaw.http.Request;import org.w3c.jigsaw.https.socket.SSLProperties;import org.w3c.jigsaw.https.socket.SSLSocketClient;import org.w3c.jigsaw.https.socket.SSLSocketClientFactory;import org.w3c.tools.resources.ProtocolException;import org.w3c.tools.resources.RequestInterface;import org.w3c.util.ObservableProperties;/** * @author Thomas Kopp, Dialogika GmbH * @version 1.1, 27 December 2000, 6 February 2004 * * This class supplies a Jigsaw SSL daemon adapter * for enabling Jigsaw https support in accordance with the JSSE API * wrapping SSL features in order to solve multiple inheritance problems */public class SSLAdapter { private static Method initCause = null; static { Class c = java.lang.Exception.class; Class cp[] = { java.lang.Exception.class }; try { Method initCause = c.getMethod("initCause", cp); } catch (Exception ex) { initCause = null; } } /** * flag for enabling debug output if applicable */ private static boolean debug = false; /** * The servlet api spec request attribute name of the cipher suite */ private static final String ALGORITHM = "javax.servlet.request.cipher_suite"; /** * The servlet api spec request attribute name of the key size */ private static final String KEYSIZE = "javax.servlet.request.key_size"; /** * The servlet api spec request attribute name of the certificate chain */ private static final String CERTCHAIN = "javax.servlet.request.X509Certificate"; /** * The servlet api spec attribute value for client authentication */ private static final String CLIENT_CERT_AUTH = "CLIENT_CERT"; /** * flag indicating TLS support */ private boolean ssl_enabled = false; /** * reference to the daemon in question */ private httpd daemon = null; /** * uri of the daemon in question */ private URL url = null; /** * Supplies the ssl session attached to the specified request if any. * * @param request the request in question * @return the attached ssl session or null if not applicable */ private final static SSLSession getSession(Request request) { Client cl = request.getClient(); if (cl instanceof SSLSocketClient) { return ((SSLSocketClient)cl).getSession(); } return null; } /** * An ugly way to compute the key size (to be improved) * @param the algorithm name * @return the key size as an integer object */ public final static Integer getKeySize(String algorithm) { if (null != algorithm) { StringTokenizer parser = new StringTokenizer(algorithm, "_"); while (parser.hasMoreTokens()) { try { return Integer.valueOf(parser.nextToken()); } catch (NumberFormatException ex) { // ignore and continue lookup } } } return null; } /** * constructor for a TLS support adapter * @param server reference to the daemon in question */ public SSLAdapter(httpd server) { if (null != server) { ssl_enabled = false; daemon = server; url = null; } else { throw new NullPointerException("No daemon intance supplied for "+ " creating SSL adapter."); } } /** * method for initializing the properties of a daemon * @exception ServerHandlerInitException thrown if initialization fails */ public void initializeProperties() throws ServerHandlerInitException { ObservableProperties props = daemon.getProperties(); // default to well-known factory if applicable if (props.getBoolean(SSLProperties.SSL_ENABLED_P, true)) { String factory_class = props.getString(httpd.CLIENT_FACTORY_P, null); if (null != factory_class) { try { Class factory = Class.forName(factory_class); ssl_enabled = (SSLSocketClientFactory.class.isAssignableFrom(factory)); } catch (Exception ex) { String error = "Initialization failed."; daemon.errlog(error + " (" + ex.getMessage() + ")"); if (debug) { System.out.println(error); ex.printStackTrace(); } ServerHandlerInitException sub; sub = new ServerHandlerInitException(ex.getMessage()); if (initCause != null) { try { Object[] param = { ex }; initCause.invoke(sub, param); } catch (Exception iex) {} } throw sub; } } else { throw new ServerHandlerInitException("No socket client" +" factory specified."); } } else { ssl_enabled = false; } url = null; } /** * method for preparing a reply interface for a request * @param req the current request to be handled * @exception ProtocolException thrown if the request url is malformed */ public void perform(RequestInterface req) throws ProtocolException { Request request = (Request)req; if (ssl_enabled) { // set request protocol to https URL url = request.getURL(); try { request.setURL(new URL("https", url.getHost(), url.getPort(), url.getFile())); // tk, 1 February 2004, added SSL client attributes // according to Servlet v2.4 spec SSLSession session = getSession(request); if (null != session) { String algorithm = session.getCipherSuite(); request.setState(ALGORITHM, algorithm); // FIXME: find a better way to compute the key size // at least this ugly computation gets cached // at the moment Object keysize = session.getValue(KEYSIZE + "." + algorithm); if (null != keysize) { request.setState(KEYSIZE, keysize); } else { keysize = getKeySize(algorithm); if (null != keysize) { session.putValue(KEYSIZE+"."+algorithm, keysize); request.setState(KEYSIZE, keysize); } } try { Certificate[] chain = session.getPeerCertificates(); if (chain instanceof X509Certificate[]) { X509Certificate[] x509chain; x509chain = (X509Certificate[])chain; request.setState(CERTCHAIN, x509chain); request.setState(AuthFilter.STATE_AUTHTYPE, CLIENT_CERT_AUTH); if (x509chain.length > 0) { request.setState(AuthFilter.STATE_AUTHUSER, x509chain[0].getSubjectDN().getName()); } } } catch (SSLPeerUnverifiedException ex) { if (debug) { ex.printStackTrace(); } // no certificates available, ignore } } } catch (MalformedURLException ex) { String error = "Bad url during switching to https."; daemon.errlog(error + " (" + ex.getMessage() + ")"); if (debug) { System.out.println(error); ex.printStackTrace(); } ProtocolException sub = new ProtocolException(ex.getMessage()); if (initCause != null) { try { Object[] param = { ex }; initCause.invoke(sub, param); } catch (Exception iex) {} } throw sub; } } } /** * method for supplying a daemon uri * @return uri of the daemon in question */ public URL getURL() { if (url == null) { if (ssl_enabled) { try { if (daemon.getPort() != 443) { url = new URL("https", daemon.getHost(), daemon.getPort(), "/"); } else { url = new URL("https", daemon.getHost(), "/"); } } catch (MalformedURLException ex) { if (debug) { ex.printStackTrace(); } throw new RuntimeException("Unable to construct "+ "server uri. (" + ex.getMessage() + ")"); } } else { try { if (daemon.getPort() != 80 ) { url = new URL("http", daemon.getHost(), daemon.getPort(), "/"); } else { url = new URL("http", daemon.getHost(), "/"); } } catch (MalformedURLException ex) { throw new RuntimeException("Unable to construct"+ " server uri. (" + ex.getMessage() + ")"); } } } return url; } /** * method for indicating TLS support * @return flag for indicating TLS support enabled */ public boolean sslEnabled() { return ssl_enabled; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -