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

Reply via email to