001 /* 002 * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.11/src/java/org/apache/commons/ssl/TomcatServerXML.java $ 003 * $Revision: 121 $ 004 * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $ 005 * 006 * ==================================================================== 007 * Licensed to the Apache Software Foundation (ASF) under one 008 * or more contributor license agreements. See the NOTICE file 009 * distributed with this work for additional information 010 * regarding copyright ownership. The ASF licenses this file 011 * to you under the Apache License, Version 2.0 (the 012 * "License"); you may not use this file except in compliance 013 * with the License. You may obtain a copy of the License at 014 * 015 * http://www.apache.org/licenses/LICENSE-2.0 016 * 017 * Unless required by applicable law or agreed to in writing, 018 * software distributed under the License is distributed on an 019 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 020 * KIND, either express or implied. See the License for the 021 * specific language governing permissions and limitations 022 * under the License. 023 * ==================================================================== 024 * 025 * This software consists of voluntary contributions made by many 026 * individuals on behalf of the Apache Software Foundation. For more 027 * information on the Apache Software Foundation, please see 028 * <http://www.apache.org/>. 029 * 030 */ 031 032 package org.apache.commons.ssl; 033 034 import org.w3c.dom.Document; 035 import org.w3c.dom.Element; 036 import org.w3c.dom.NodeList; 037 038 import javax.xml.parsers.DocumentBuilder; 039 import javax.xml.parsers.DocumentBuilderFactory; 040 import java.io.File; 041 import java.io.FileInputStream; 042 import java.io.IOException; 043 import java.io.InputStream; 044 import java.util.Collections; 045 import java.util.Map; 046 import java.util.SortedMap; 047 import java.util.TreeMap; 048 049 /** 050 * @author Credit Union Central of British Columbia 051 * @author <a href="http://www.cucbc.com/">www.cucbc.com</a> 052 * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a> 053 * @since 22-Feb-2007 054 */ 055 public class TomcatServerXML { 056 private final static LogWrapper log = LogWrapper.getLogger(TomcatServerXML.class); 057 058 /** 059 * KeyMaterial extracted from Tomcat's conf/server.xml. There might be 060 * several KeyMaterials to extract if Tomcat has different SSL Certificates 061 * listening on different ports. This particular KeyMaterial will come from 062 * the lowest secure port that Tomcat is properly configured to open. 063 */ 064 public final static KeyMaterial KEY_MATERIAL; 065 066 /** 067 * TrustMaterial extracted from Tomcat's conf/server.xml. There might be 068 * several TrustMaterials to extract if Tomcat has different SSL Certificates 069 * listening on different ports. This particular TrustMaterial will come 070 * from the lowest secure port that Tomcat is properly configured to open. 071 * </p><p> 072 * There's a good chance this will be set to TrustMaterial.DEFAULT (which 073 * use's the JVM's '$JAVA_HOME/jre/lib/security/cacerts' file). 074 * </p><p> 075 * Note: With SSLServerSockets, TrustMaterial only matters when the 076 * incoming client socket (SSLSocket) presents a client certificate. 077 * </p> 078 */ 079 public final static TrustMaterial TRUST_MATERIAL; 080 081 /** 082 * new Integer( port ) --> KeyMaterial mapping of SSL Certificates found 083 * inside Tomcat's conf/server.xml file. 084 */ 085 public final static SortedMap KEY_MATERIAL_BY_PORT; 086 087 /** 088 * new Integer( port ) --> TrustMaterial mapping of SSL configuration 089 * found inside Tomcat's conf/server.xml file. 090 * </p><p> 091 * Many of these will probably be TrustMaterial.DEFAULT (which uses the 092 * JVM's '$JAVA_HOME/jre/lib/security/cacerts' file). 093 * </p><p> 094 * Note: With SSLServerSockets, TrustMaterial only matters when the 095 * incoming client socket (SSLSocket) presents a client certificate. 096 * </p> 097 */ 098 public final static SortedMap TRUST_MATERIAL_BY_PORT; 099 100 static { 101 String tomcatHome = System.getProperty("catalina.home"); 102 String serverXML = tomcatHome + "/conf/server.xml"; 103 TreeMap keyMap = new TreeMap(); 104 TreeMap trustMap = new TreeMap(); 105 InputStream in = null; 106 Document doc = null; 107 try { 108 if (tomcatHome != null) { 109 File f = new File(serverXML); 110 if (f.exists()) { 111 try { 112 in = new FileInputStream(serverXML); 113 } 114 catch (IOException ioe) { 115 // oh well, no soup for us. 116 log.warn("Commons-SSL failed to load Tomcat's [" + serverXML + "] " + ioe); 117 } 118 } 119 } 120 if (in != null) { 121 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 122 try { 123 DocumentBuilder db = dbf.newDocumentBuilder(); 124 doc = db.parse(in); 125 } 126 catch (Exception e) { 127 log.warn("Commons-SSL failed to parse Tomcat's [" + serverXML + "] " + e); 128 } 129 } 130 if (doc != null) { 131 loadTomcatConfig(doc, keyMap, trustMap); 132 } 133 } 134 finally { 135 if (in != null) { 136 try { in.close(); } catch (Exception e) { /* . */ } 137 } 138 } 139 KEY_MATERIAL_BY_PORT = Collections.unmodifiableSortedMap(keyMap); 140 TRUST_MATERIAL_BY_PORT = Collections.unmodifiableSortedMap(trustMap); 141 142 KeyMaterial km = null; 143 TrustMaterial tm = null; 144 if (!keyMap.isEmpty()) { 145 km = (KeyMaterial) keyMap.get(keyMap.firstKey()); 146 } 147 if (!trustMap.isEmpty()) { 148 tm = (TrustMaterial) trustMap.get(trustMap.firstKey()); 149 } 150 KEY_MATERIAL = km; 151 TRUST_MATERIAL = tm; 152 153 } 154 155 private static void loadTomcatConfig(Document d, Map keyMap, Map trustMap) { 156 final String userHome = System.getProperty("user.home"); 157 NodeList nl = d.getElementsByTagName("Connector"); 158 for (int i = 0; i < nl.getLength(); i++) { 159 KeyMaterial km = null; 160 TrustMaterial tm = null; 161 162 Element element = (Element) nl.item(i); 163 String secure = element.getAttribute("secure"); 164 String portString = element.getAttribute("port"); 165 Integer port = null; 166 String pass; 167 try { 168 portString = portString != null ? portString.trim() : ""; 169 port = new Integer(portString); 170 } 171 catch (NumberFormatException nfe) { 172 // oh well 173 } 174 if (port != null && Util.isYes(secure)) { 175 // Key Material 176 String keystoreFile = element.getAttribute("keystoreFile"); 177 pass = element.getAttribute("keystorePass"); 178 if (!element.hasAttribute("keystoreFile")) { 179 keystoreFile = userHome + "/.keystore"; 180 } 181 if (!element.hasAttribute("keystorePass")) { 182 pass = "changeit"; 183 } 184 char[] keystorePass = pass != null ? pass.toCharArray() : null; 185 186 // Trust Material 187 String truststoreFile = element.getAttribute("truststoreFile"); 188 pass = element.getAttribute("truststorePass"); 189 if (!element.hasAttribute("truststoreFile")) { 190 truststoreFile = null; 191 } 192 if (!element.hasAttribute("truststorePass")) { 193 pass = null; 194 } 195 char[] truststorePass = pass != null ? pass.toCharArray() : null; 196 197 198 if (keystoreFile == null) { 199 km = null; 200 } else { 201 try { 202 km = new KeyMaterial(keystoreFile, keystorePass); 203 } 204 catch (Exception e) { 205 log.warn("Commons-SSL failed to load [" + keystoreFile + "] " + e); 206 } 207 } 208 if (truststoreFile == null) { 209 tm = TrustMaterial.DEFAULT; 210 } else { 211 try { 212 tm = new TrustMaterial(truststoreFile, truststorePass); 213 } 214 catch (Exception e) { 215 log.warn("Commons-SSL failed to load [" + truststoreFile + "] " + e); 216 } 217 } 218 219 Object o = keyMap.put(port, km); 220 if (o != null) { 221 log.debug("Commons-SSL TomcatServerXML keyMap clobbered port: " + port); 222 } 223 o = trustMap.put(port, tm); 224 if (o != null) { 225 log.debug("Commons-SSL TomcatServerXML trustMap clobbered port: " + port); 226 } 227 } 228 } 229 } 230 231 }