Author: markt Date: Tue Sep 29 14:04:20 2015 New Revision: 1705866 URL: http://svn.apache.org/viewvc?rev=1705866&view=rev Log: Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=56777 Allow trust stores, keystores, CRLs and the tomcat-users.xml file to be loaded from URLs as well as the file system.
Modified: tomcat/trunk/java/org/apache/catalina/realm/MemoryRealm.java tomcat/trunk/java/org/apache/catalina/users/MemoryUserDatabase.java tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java tomcat/trunk/webapps/docs/config/http.xml tomcat/trunk/webapps/docs/config/realm.xml tomcat/trunk/webapps/docs/jndi-resources-howto.xml Modified: tomcat/trunk/java/org/apache/catalina/realm/MemoryRealm.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/realm/MemoryRealm.java?rev=1705866&r1=1705865&r2=1705866&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/realm/MemoryRealm.java (original) +++ tomcat/trunk/java/org/apache/catalina/realm/MemoryRealm.java Tue Sep 29 14:04:20 2015 @@ -16,7 +16,8 @@ */ package org.apache.catalina.realm; -import java.io.File; +import java.io.IOException; +import java.io.InputStream; import java.security.Principal; import java.util.ArrayList; import java.util.HashMap; @@ -26,6 +27,7 @@ import org.apache.catalina.LifecycleExce import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.digester.Digester; +import org.apache.tomcat.util.file.ConfigFileLoader; /** @@ -241,31 +243,26 @@ public class MemoryRealm extends RealmB */ @Override protected void startInternal() throws LifecycleException { + String pathName = getPathname(); + try (InputStream is = ConfigFileLoader.getInputStream(pathName)) { + // Load the contents of the database file + if (log.isDebugEnabled()) { + log.debug(sm.getString("memoryRealm.loadPath", pathName)); + } - // Validate the existence of our database file - File file = new File(pathname); - if (!file.isAbsolute()) - file = new File(getContainer().getCatalinaBase(), pathname); - if (!file.exists() || !file.canRead()) - throw new LifecycleException - (sm.getString("memoryRealm.loadExist", - file.getAbsolutePath())); - - // Load the contents of the database file - if (log.isDebugEnabled()) - log.debug(sm.getString("memoryRealm.loadPath", - file.getAbsolutePath())); - Digester digester = getDigester(); - try { - synchronized (digester) { - digester.push(this); - digester.parse(file); + Digester digester = getDigester(); + try { + synchronized (digester) { + digester.push(this); + digester.parse(is); + } + } catch (Exception e) { + throw new LifecycleException(sm.getString("memoryRealm.readXml"), e); + } finally { + digester.reset(); } - } catch (Exception e) { - throw new LifecycleException - (sm.getString("memoryRealm.readXml"), e); - } finally { - digester.reset(); + } catch (IOException ioe) { + throw new LifecycleException(sm.getString("memoryRealm.loadExist", pathName), ioe); } super.startInternal(); Modified: tomcat/trunk/java/org/apache/catalina/users/MemoryUserDatabase.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/users/MemoryUserDatabase.java?rev=1705866&r1=1705865&r2=1705866&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/users/MemoryUserDatabase.java (original) +++ tomcat/trunk/java/org/apache/catalina/users/MemoryUserDatabase.java Tue Sep 29 14:04:20 2015 @@ -17,9 +17,9 @@ package org.apache.catalina.users; import java.io.File; -import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.HashMap; @@ -34,6 +34,7 @@ import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.digester.AbstractObjectCreationFactory; import org.apache.tomcat.util.digester.Digester; +import org.apache.tomcat.util.file.ConfigFileLoader; import org.apache.tomcat.util.res.StringManager; import org.xml.sax.Attributes; @@ -394,41 +395,29 @@ public class MemoryUserDatabase implemen groups.clear(); roles.clear(); - // Construct a reader for the XML input file (if it exists) - File file = new File(pathname); - if (!file.isAbsolute()) { - file = new File(System.getProperty(Globals.CATALINA_BASE_PROP), - pathname); - } - if (!file.exists()) { - log.error(sm.getString("memoryUserDatabase.fileNotFound", - file.getAbsolutePath())); + String pathName = getPathname(); + try (InputStream is = ConfigFileLoader.getInputStream(getPathname())) { + // Construct a digester to read the XML input file + Digester digester = new Digester(); + try { + digester.setFeature( + "http://apache.org/xml/features/allow-java-encodings", true); + } catch (Exception e) { + log.warn(sm.getString("memoryUserDatabase.xmlFeatureEncoding"), e); + } + digester.addFactoryCreate("tomcat-users/group", + new MemoryGroupCreationFactory(this), true); + digester.addFactoryCreate("tomcat-users/role", + new MemoryRoleCreationFactory(this), true); + digester.addFactoryCreate("tomcat-users/user", + new MemoryUserCreationFactory(this), true); + + // Parse the XML input to load this database + digester.parse(is); + } catch (IOException ioe) { + log.error(sm.getString("memoryUserDatabase.fileNotFound", pathName)); return; } - - // Construct a digester to read the XML input file - Digester digester = new Digester(); - try { - digester.setFeature( - "http://apache.org/xml/features/allow-java-encodings", - true); - } catch (Exception e) { - log.warn(sm.getString("memoryUserDatabase.xmlFeatureEncoding"), e); - } - digester.addFactoryCreate - ("tomcat-users/group", - new MemoryGroupCreationFactory(this), true); - digester.addFactoryCreate - ("tomcat-users/role", - new MemoryRoleCreationFactory(this), true); - digester.addFactoryCreate - ("tomcat-users/user", - new MemoryUserCreationFactory(this), true); - - // Parse the XML input file to load this database - try (FileInputStream fis = new FileInputStream(file)) { - digester.parse(fis); - } } } } Modified: tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java?rev=1705866&r1=1705865&r2=1705866&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java Tue Sep 29 14:04:20 2015 @@ -16,8 +16,6 @@ */ package org.apache.tomcat.util.net.jsse; -import java.io.File; -import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -55,6 +53,7 @@ import javax.net.ssl.X509KeyManager; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.compat.JreVendor; +import org.apache.tomcat.util.file.ConfigFileLoader; import org.apache.tomcat.util.net.SSLContext; import org.apache.tomcat.util.net.SSLHostConfig; import org.apache.tomcat.util.net.SSLHostConfigCertificate; @@ -187,7 +186,7 @@ public class JSSESocketFactory implement protected KeyStore getTrustStore() throws IOException { KeyStore trustStore = null; - String truststoreFile = SSLHostConfig.adjustRelativePath(sslHostConfig.getTruststoreFile()); + String truststoreFile = sslHostConfig.getTruststoreFile(); String truststoreType = sslHostConfig.getTruststoreType(); String truststoreProvider = sslHostConfig.getTruststoreProvider(); @@ -232,8 +231,7 @@ public class JSSESocketFactory implement if(!("PKCS11".equalsIgnoreCase(type) || "".equalsIgnoreCase(path)) || "NONE".equalsIgnoreCase(path)) { - File keyStoreFile = new File(path); - istream = new FileInputStream(keyStoreFile); + istream = ConfigFileLoader.getInputStream(path); } char[] storePass = null; @@ -278,8 +276,7 @@ public class JSSESocketFactory implement public KeyManager[] getKeyManagers() throws Exception { String keystoreType = certificate.getCertificateKeystoreType(); String keystoreProvider = certificate.getCertificateKeystoreProvider(); - String keystoreFile = SSLHostConfig.adjustRelativePath( - certificate.getCertificateKeystoreFile()); + String keystoreFile = certificate.getCertificateKeystoreFile(); String keystorePass = certificate.getCertificateKeystorePassword(); String keyAlias = certificate.getCertificateKeyAlias(); String algorithm = sslHostConfig.getKeyManagerAlgorithm(); @@ -324,8 +321,7 @@ public class JSSESocketFactory implement public TrustManager[] getTrustManagers() throws Exception { String algorithm = sslHostConfig.getTruststoreAlgorithm(); - String crlf = SSLHostConfig.adjustRelativePath( - sslHostConfig.getCertificateRevocationListFile()); + String crlf = sslHostConfig.getCertificateRevocationListFile(); String className = sslHostConfig.getTrustManagerClassName(); if(className != null && className.length() > 0) { @@ -402,11 +398,10 @@ public class JSSESocketFactory implement protected Collection<? extends CRL> getCRLs(String crlf) throws IOException, CRLException, CertificateException { - File crlFile = new File(crlf); Collection<? extends CRL> crls = null; try { CertificateFactory cf = CertificateFactory.getInstance("X.509"); - try (InputStream is = new FileInputStream(crlFile)) { + try (InputStream is = ConfigFileLoader.getInputStream(crlf)) { crls = cf.generateCRLs(is); } } catch(IOException iex) { Modified: tomcat/trunk/webapps/docs/config/http.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/http.xml?rev=1705866&r1=1705865&r2=1705866&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/http.xml (original) +++ tomcat/trunk/webapps/docs/config/http.xml Tue Sep 29 14:04:20 2015 @@ -1033,9 +1033,10 @@ <p>Name of the file that contains the concatenated certificate revocation lists for the certificate authorities. The format is PEM-encoded. If not defined, client certificates will not be checked against a certificate - revocation list (unless an OpenSSl based connector is used and + revocation list (unless an OpenSSL based connector is used and <strong>certificateRevocationPath</strong> is defined). Relative paths - will be resolved against <code>$CATALINA_BASE</code>.</p> + will be resolved against <code>$CATALINA_BASE</code>. JSSE based + connectors may also specify a URL for this attribute.</p> </attribute> <attribute name="certificateRevocationPath" required="false"> @@ -1207,7 +1208,8 @@ default is the value of the <code>javax.net.ssl.trustStore</code> system property. If neither this attribute nor the default system property is set, no trust store will be configured. Relative paths - will be resolved against <code>$CATALINA_BASE</code>.</p> + will be resolved against <code>$CATALINA_BASE</code>. A URL may also be + used for this attribute.</p> </attribute> <attribute name="truststorePass" required="false"> @@ -1299,7 +1301,8 @@ that is running Tomcat. If your <code>keystoreType</code> doesn't need a file use <code>""</code> (empty string) or <code>NONE</code> for this parameter. Relative paths will be resolved against - <code>$CATALINA_BASE</code>.</p> + <code>$CATALINA_BASE</code>. A URL may also be used for this attribute. + </p> </attribute> <attribute name="certificateKeystorePassword" required="false"> Modified: tomcat/trunk/webapps/docs/config/realm.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/realm.xml?rev=1705866&r1=1705865&r2=1705866&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/realm.xml (original) +++ tomcat/trunk/webapps/docs/config/realm.xml Tue Sep 29 14:04:20 2015 @@ -821,8 +821,8 @@ </attribute> <attribute name="pathname" required="false"> - <p>Absolute or relative (to $CATALINA_BASE) pathname to the XML file - containing our user information. See below for details on the + <p>URL, absolute path or relative path (to $CATALINA_BASE) for the XML + file containing our user information. See below for details on the XML element format required. If no pathname is specified, the default value is <code>conf/tomcat-users.xml</code>.</p> </attribute> Modified: tomcat/trunk/webapps/docs/jndi-resources-howto.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/jndi-resources-howto.xml?rev=1705866&r1=1705865&r2=1705866&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/jndi-resources-howto.xml (original) +++ tomcat/trunk/webapps/docs/jndi-resources-howto.xml Tue Sep 29 14:04:20 2015 @@ -471,8 +471,9 @@ public class MyBean2 { pathname="conf/tomcat-users.xml" readonly="false" />]]></source> - <p>The <code>pathname</code> attribute can be absolute or relative. If - relative, it is relative to <code>$CATALINA_BASE</code>.</p> + <p>The <code>pathname</code> attribute can be a URL, an absolute path or a + relative path. If relative, it is relative to <code>$CATALINA_BASE</code>. + </p> <p>The <code>readonly</code> attribute is optional and defaults to <code>true</code> if not supplied. If the XML is writeable then it will be --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org