You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by kk...@apache.org on 2011/12/25 19:52:38 UTC

svn commit: r1224628 - in /tomcat/tc6.0.x/trunk: ./ java/org/apache/catalina/core/ java/org/apache/tomcat/jni/ webapps/docs/ webapps/docs/config/

Author: kkolinko
Date: Sun Dec 25 18:52:37 2011
New Revision: 1224628

URL: http://svn.apache.org/viewvc?rev=1224628&view=rev
Log:
- Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=50570
Enable FIPS mode to be set in AprLifecycleListener.
Based upon a patch from Chris Beckey.
- Backport AprLifecycleListener improvements from TC7
  This includes:
1. Use consistent external synchronization object for private
   initialization methods. Turn initialization flags to false after APR
   has been terminated. That is, to terminate it only once.
   (rev. 946671 + several after it)
2. Use ExceptionUtils.handleThrowable() for fatal errors (rev. 1001904)
3. Do not allow to change SSL options if SSL engine has already been
   initialised. (rev. 1199985 + several after it)

Modified:
    tomcat/tc6.0.x/trunk/STATUS.txt
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/AprLifecycleListener.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties
    tomcat/tc6.0.x/trunk/java/org/apache/tomcat/jni/SSL.java
    tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml
    tomcat/tc6.0.x/trunk/webapps/docs/config/listeners.xml

Modified: tomcat/tc6.0.x/trunk/STATUS.txt
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/STATUS.txt?rev=1224628&r1=1224627&r2=1224628&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/STATUS.txt (original)
+++ tomcat/tc6.0.x/trunk/STATUS.txt Sun Dec 25 18:52:37 2011
@@ -50,36 +50,6 @@ PATCHES PROPOSED TO BACKPORT:
       - getStuckThreadIds() returns a list of ids. It might be useful to
         have a similar method that returns Thread.getName() names.
 
-* Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=50570
-  Apply FIPS mode patch from TC7:
-  http://svn.apache.org/viewvc?rev=1199985&view=rev
-  http://svn.apache.org/viewvc?rev=1200004&view=rev
-  http://svn.apache.org/viewvc?rev=1200448&view=rev
-  +1: schultz, jfclere
-  -1: kkolinko: It needs to include more preceding and followup
-   changes. Updated patch proposed below.
-
-* Backport AprLifecycleListener improvements from TC7
-  This includes:
-   - Use consistent external synchronization object for private
-     initialization methods. Turn initialization flags to false after APR
-     has been terminated. That is, to terminate it only once.
-     (rev. 946671 + several after it)
-   - Use ExceptionUtils.handleThrowable() for fatal errors
-     (rev. 1001904)
-   - Do not allow to change SSL options if SSL engine has already been
-     initialised.
-     (rev. 1199985 + several after it)
-   - Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=50570
-     Enable FIPS mode to be set in AprLifecycleListener.
-     Based upon a patch from Chris Beckey.
-     (rev. 1199985 + several after it)
-  kkolinko: I tested only that it does not break things with the current
-    released tcnative version 1.1.22 that does not have FIPS mode support.
-  http://people.apache.org/~kkolinko/patches/2011-11-12_tc6_AprLifecycleListener.patch
-  +1: kkolinko, markt,funkman
-  -1:
-
 * Fix autodeployment of applications that have configuration errors.
   If autodeployment fails, create DeployedApplication object and register
   what we deployed (xml or war or dir - a single file) as redeployResource.

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/AprLifecycleListener.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/AprLifecycleListener.java?rev=1224628&r1=1224627&r2=1224628&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/AprLifecycleListener.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/AprLifecycleListener.java Sun Dec 25 18:52:37 2011
@@ -28,6 +28,8 @@ import org.apache.catalina.util.StringMa
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.jni.Library;
+import org.apache.tomcat.jni.SSL;
+import org.apache.tomcat.util.ExceptionUtils;
 
 
 
@@ -65,15 +67,23 @@ public class AprLifecycleListener
 
     // ---------------------------------------------- Properties
     protected static String SSLEngine = "on"; //default on
+    protected static String FIPSMode = "off"; // default off, valid only when SSLEngine="on"
     protected static String SSLRandomSeed = "builtin";
     protected static boolean sslInitialized = false;
     protected static boolean aprInitialized = false;
     protected static boolean sslAvailable = false;
     protected static boolean aprAvailable = false;
+    protected static boolean fipsModeActive = false;
+
+    protected static final Object lock = new Object();
 
     public static boolean isAprAvailable() {
         //https://issues.apache.org/bugzilla/show_bug.cgi?id=48613
-        if (instanceCreated) init();
+        if (instanceCreated) {
+            synchronized (lock) {
+                init();
+            }
+        }
         return aprAvailable;
     }
 
@@ -91,36 +101,46 @@ public class AprLifecycleListener
     public void lifecycleEvent(LifecycleEvent event) {
 
         if (Lifecycle.INIT_EVENT.equals(event.getType())) {
-            init();
-            if (aprAvailable) {
+            synchronized (lock) {
+                init();
+                if (aprAvailable) {
+                    try {
+                        initializeSSL();
+                    } catch (Throwable t) {
+                        ExceptionUtils.handleThrowable(t);
+                        log.error(sm.getString("aprListener.sslInit"), t);
+                    }
+                }
+                // Failure to initialize FIPS mode is fatal
+                if ("on".equalsIgnoreCase(FIPSMode) && !isFIPSModeActive()) {
+                    Error e = new Error(
+                            sm.getString("aprListener.initializeFIPSFailed"));
+                    // Log here, because thrown error might be not logged
+                    log.fatal(e.getMessage(), e);
+                    throw e;
+                }
+            }
+        } else if (Lifecycle.AFTER_STOP_EVENT.equals(event.getType())) {
+            synchronized (lock) {
+                if (!aprAvailable) {
+                    return;
+                }
                 try {
-                    initializeSSL();
+                    terminateAPR();
                 } catch (Throwable t) {
+                    ExceptionUtils.handleThrowable(t);
                     if (!log.isDebugEnabled()) {
-                        log.info(sm.getString("aprListener.sslInit"));
+                        log.info(sm.getString("aprListener.aprDestroy"));
                     } else {
-                        log.debug(sm.getString("aprListener.sslInit"), t);
+                        log.debug(sm.getString("aprListener.aprDestroy"), t);
                     }
                 }
             }
-        } else if (Lifecycle.AFTER_STOP_EVENT.equals(event.getType())) {
-            if (!aprAvailable) {
-                return;
-            }
-            try {
-                terminateAPR();
-            } catch (Throwable t) {
-                if (!log.isDebugEnabled()) {
-                    log.info(sm.getString("aprListener.aprDestroy"));
-                } else {
-                    log.debug(sm.getString("aprListener.aprDestroy"), t);
-                }
-            }
         }
 
     }
 
-    private static synchronized void terminateAPR()
+    private static void terminateAPR()
         throws ClassNotFoundException, NoSuchMethodException,
                IllegalAccessException, InvocationTargetException
     {
@@ -128,6 +148,11 @@ public class AprLifecycleListener
         Method method = Class.forName("org.apache.tomcat.jni.Library")
             .getMethod(methodName, (Class [])null);
         method.invoke(null, (Object []) null);
+        aprAvailable = false;
+        aprInitialized = false;
+        sslInitialized = false; // Well we cleaned the pool in terminate.
+        sslAvailable = false; // Well we cleaned the pool in terminate.
+        fipsModeActive = false;
     }
 
     private static void init()
@@ -157,6 +182,7 @@ public class AprLifecycleListener
             patch = clazz.getField("TCN_PATCH_VERSION").getInt(null);
             apver = major * 1000 + minor * 100 + patch;
         } catch (Throwable t) {
+            ExceptionUtils.handleThrowable(t);
             if (!log.isDebugEnabled()) {
                 log.info(sm.getString("aprListener.aprInit",
                         System.getProperty("java.library.path")));
@@ -177,7 +203,7 @@ public class AprLifecycleListener
                 // is below required.
                 terminateAPR();
             } catch (Throwable t) {
-                // Ignore
+                ExceptionUtils.handleThrowable(t);
             }
             return;
         }
@@ -210,7 +236,7 @@ public class AprLifecycleListener
         aprAvailable = true;
     }
 
-    private static synchronized void initializeSSL()
+    private static void initializeSSL()
         throws ClassNotFoundException, NoSuchMethodException,
                IllegalAccessException, InvocationTargetException
     {
@@ -239,6 +265,25 @@ public class AprLifecycleListener
         method = clazz.getMethod(methodName, paramTypes);
         method.invoke(null, paramValues);
 
+        if("on".equalsIgnoreCase(FIPSMode)) {
+            log.info(sm.getString("aprListener.initializingFIPS"));
+
+            int result = SSL.fipsModeSet(1);
+
+            // success is defined as return value = 1
+            if(1 == result) {
+                fipsModeActive = true;
+
+                log.info(sm.getString("aprListener.initializeFIPSSuccess"));
+            } else {
+                // This case should be handled by the native method,
+                // but we'll make absolutely sure, here.
+                String message = sm.getString("aprListener.initializeFIPSFailed");
+                log.error(message);
+                throw new IllegalStateException(message);
+            }
+        }
+
         sslAvailable = true;
     }
 
@@ -247,7 +292,15 @@ public class AprLifecycleListener
     }
 
     public void setSSLEngine(String SSLEngine) {
-        this.SSLEngine = SSLEngine;
+        if (!SSLEngine.equals(AprLifecycleListener.SSLEngine)) {
+            // Ensure that the SSLEngine is consistent with that used for SSL init
+            if (sslInitialized) {
+                throw new IllegalStateException(
+                        sm.getString("aprListener.tooLateForSSLEngine"));
+            }
+
+            AprLifecycleListener.SSLEngine = SSLEngine;
+        }
     }
 
     public String getSSLRandomSeed() {
@@ -255,7 +308,34 @@ public class AprLifecycleListener
     }
 
     public void setSSLRandomSeed(String SSLRandomSeed) {
-        this.SSLRandomSeed = SSLRandomSeed;
+        if (!SSLRandomSeed.equals(AprLifecycleListener.SSLRandomSeed)) {
+            // Ensure that the random seed is consistent with that used for SSL init
+            if (sslInitialized) {
+                throw new IllegalStateException(
+                        sm.getString("aprListener.tooLateForSSLRandomSeed"));
+            }
+
+            AprLifecycleListener.SSLRandomSeed = SSLRandomSeed;
+        }
+    }
+
+    public String getFIPSMode() {
+        return FIPSMode;
     }
 
+    public void setFIPSMode(String FIPSMode) {
+        if (!FIPSMode.equals(AprLifecycleListener.FIPSMode)) {
+            // Ensure that the FIPS mode is consistent with that used for SSL init
+            if (sslInitialized) {
+                throw new IllegalStateException(
+                        sm.getString("aprListener.tooLateForFIPSMode"));
+            }
+
+            AprLifecycleListener.FIPSMode = FIPSMode;
+        }
+    }
+
+    public boolean isFIPSModeActive() {
+        return fipsModeActive;
+    }
 }

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties?rev=1224628&r1=1224627&r2=1224628&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties Sun Dec 25 18:52:37 2011
@@ -42,6 +42,13 @@ aprListener.aprDestroy=Failed shutdown o
 aprListener.sslInit=Failed to initialize the SSLEngine.
 aprListener.tcnValid=Loaded APR based Apache Tomcat Native library {0}.
 aprListener.flags=APR capabilities: IPv6 [{0}], sendfile [{1}], accept filters [{2}], random [{3}].
+aprListener.initializingFIPS=Initializing FIPS mode...
+aprListener.initializeFIPSSuccess=Successfully entered FIPS mode
+aprListener.initializeFIPSFailed=Failed to enter FIPS mode
+aprListener.tooLateForSSLEngine=Cannot setSSLEngine: SSL has already been initialized
+aprListener.tooLateForSSLRandomSeed=Cannot setSSLRandomSeed: SSL has already been initialized
+aprListener.tooLateForFIPSMode=Cannot setFIPSMode: SSL has already been initialized
+
 containerBase.addDefaultMapper=Exception configuring default mapper of class {0}
 containerBase.alreadyStarted=Container {0} has already been started
 containerBase.notConfigured=No basic Valve has been configured

Modified: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/jni/SSL.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/jni/SSL.java?rev=1224628&r1=1224627&r2=1224628&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/jni/SSL.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/jni/SSL.java Sun Dec 25 18:52:37 2011
@@ -227,6 +227,15 @@ public final class SSL {
     public static native int initialize(String engine);
 
     /**
+     * Enable/Disable FIPS Mode.
+     *
+     * @param mode 1 - enable, 0 - disable
+     *
+     * @return FIPS_mode_set return code
+     */
+    public static native int fipsModeSet(int mode);
+
+    /**
       * Set source of entropy to use in SSL
       *  @param filename Filename containing random data
       */

Modified: tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml?rev=1224628&r1=1224627&r2=1224628&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Sun Dec 25 18:52:37 2011
@@ -46,7 +46,18 @@
 <section name="Tomcat 6.0.36 (jfclere)" rtext="">
   <subsection name="Catalina">
     <changelog>
-       <fix>
+      <fix>
+        <bug>50570</bug>: Enable FIPS mode to be set in AprLifecycleListener.
+        Based upon a patch from Chris Beckey. Note that this mode requires
+        tomcat-native 1.1.23 or later linked to a FIPS-capable OpenSSL library,
+        which one has to build by themselves. (schultz/kkolinko)
+      </fix>
+      <fix>
+        Improve synchronization and error handling in AprLifecycleListener.
+        Do not allow to change SSL options if SSL has already been initialized.
+        (schultz/kkolinko)
+      </fix>
+      <fix>
         <bug>52225</bug>: Fix ClassCastException when adding an alias for an
         existing host via JMX. (kkolinko)
       </fix>

Modified: tomcat/tc6.0.x/trunk/webapps/docs/config/listeners.xml
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/config/listeners.xml?rev=1224628&r1=1224627&r2=1224628&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/webapps/docs/config/listeners.xml (original)
+++ tomcat/tc6.0.x/trunk/webapps/docs/config/listeners.xml Sun Dec 25 18:52:37 2011
@@ -112,6 +112,16 @@
         this to <code>/dev/urandom</code> to allow quicker start times.</p>
       </attribute>
 
+      <attribute name="FIPSMode" required="false">
+        <p>Set to <code>on</code> to instruct OpenSSL to go into FIPS mode.
+        FIPS mode <em>requires you to have a FIPS-capable OpenSSL library which
+        you must build yourself</em>.
+        FIPS mode also requires Tomcat native library version 1.1.23 or later,
+        which <em>must be built against the FIPS-compatible OpenSSL</em> library.
+        If this attribute is "on", <b>SSLEngine</b> must be enabled as well.
+        The default value is <code>off</code>.</p>
+      </attribute>
+
     </attributes>
 
   </subsection>



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org