View | Details | Raw Unified | Return to bug 50570
Collapse All | Expand All

(-)java/org/apache/catalina/core/AprLifecycleListener.java (-60 / +263 lines)
Lines 23-29 Link Here
23
23
24
import org.apache.catalina.Lifecycle;
24
import org.apache.catalina.Lifecycle;
25
import org.apache.catalina.LifecycleEvent;
25
import org.apache.catalina.LifecycleEvent;
26
import org.apache.catalina.LifecycleException;
26
import org.apache.catalina.LifecycleListener;
27
import org.apache.catalina.LifecycleListener;
28
import org.apache.catalina.LifecycleState;
27
import org.apache.juli.logging.Log;
29
import org.apache.juli.logging.Log;
28
import org.apache.juli.logging.LogFactory;
30
import org.apache.juli.logging.LogFactory;
29
import org.apache.tomcat.jni.Library;
31
import org.apache.tomcat.jni.Library;
Lines 38-57 Link Here
38
 *
40
 *
39
 * @author Remy Maucherat
41
 * @author Remy Maucherat
40
 * @author Filip Hanik
42
 * @author Filip Hanik
43
 * @author cbeckey@gmail.com	added FIPS Mode and group library loading
41
 * @version $Id$
44
 * @version $Id$
42
 * @since 4.1
45
 * @since 4.1
43
 */
46
 */
44
47
45
public class AprLifecycleListener
48
public class AprLifecycleListener
46
    implements LifecycleListener {
49
implements LifecycleListener 
50
{
47
51
48
    private static final Log log = LogFactory.getLog(AprLifecycleListener.class);
52
    private static final Log log = LogFactory.getLog(AprLifecycleListener.class);
49
    private static boolean instanceCreated = false;
53
    private static boolean instanceCreated = false;
54
    
50
    /**
55
    /**
51
     * The string manager for this package.
56
     * The string manager for this package.
52
     */
57
     */
53
    protected static final StringManager sm =
58
    protected static final StringManager stringManager = StringManager.getManager(Constants.Package);
54
        StringManager.getManager(Constants.Package);
55
59
56
60
57
    // ---------------------------------------------- Constants
61
    // ---------------------------------------------- Constants
Lines 66-74 Link Here
66
70
67
    // ---------------------------------------------- Properties
71
    // ---------------------------------------------- Properties
68
    protected static String SSLEngine = "on"; //default on
72
    protected static String SSLEngine = "on"; //default on
73
    protected static String FIPSMode = "off"; //default off, valid only when SSLEngine is 'on'
69
    protected static String SSLRandomSeed = "builtin";
74
    protected static String SSLRandomSeed = "builtin";
70
    protected static boolean sslInitialized = false;
75
    protected static boolean sslInitialized = false;
71
    protected static boolean aprInitialized = false;
76
    protected static boolean aprInitialized = false;
77
    protected static boolean fipsModeActive = false;
72
    protected static boolean sslAvailable = false;
78
    protected static boolean sslAvailable = false;
73
    protected static boolean aprAvailable = false;
79
    protected static boolean aprAvailable = false;
74
80
Lines 78-90 Link Here
78
        //https://issues.apache.org/bugzilla/show_bug.cgi?id=48613
84
        //https://issues.apache.org/bugzilla/show_bug.cgi?id=48613
79
        if (instanceCreated) {
85
        if (instanceCreated) {
80
            synchronized (lock) {
86
            synchronized (lock) {
81
                init();
87
                initializeAPR();
82
            }
88
            }
83
        }
89
        }
84
        return aprAvailable;
90
        return aprAvailable;
85
    }
91
    }
86
92
87
    public AprLifecycleListener() {
93
    public AprLifecycleListener() 
94
    {
88
        instanceCreated = true;
95
        instanceCreated = true;
89
    }
96
    }
90
97
Lines 96-125 Link Here
96
     * @param event The event that has occurred
103
     * @param event The event that has occurred
97
     */
104
     */
98
    @Override
105
    @Override
99
    public void lifecycleEvent(LifecycleEvent event) {
106
    public void lifecycleEvent(LifecycleEvent event) 
100
107
    {
101
        if (Lifecycle.BEFORE_INIT_EVENT.equals(event.getType())) {
108
        if (Lifecycle.BEFORE_INIT_EVENT.equals(event.getType())) 
102
            synchronized (lock) {
109
        {
103
                init();
110
            synchronized (lock) 
104
                if (aprAvailable) {
111
            {
105
                    try {
112
                initializeAPR();
113
                if (aprAvailable) 
114
                    try 
115
                    {
106
                        initializeSSL();
116
                        initializeSSL();
107
                    } catch (Throwable t) {
117
                    } 
118
                    catch (Throwable t) 
119
                    {
108
                        ExceptionUtils.handleThrowable(t);
120
                        ExceptionUtils.handleThrowable(t);
109
                        log.info(sm.getString("aprListener.sslInit"));
121
                        log.info(stringManager.getString("aprListener.sslInit"));
110
                    }
122
                    }
111
                }
112
            }
123
            }
113
        } else if (Lifecycle.AFTER_DESTROY_EVENT.equals(event.getType())) {
124
        } 
114
            synchronized (lock) {
125
        else if (Lifecycle.AFTER_DESTROY_EVENT.equals(event.getType())) 
115
                if (!aprAvailable) {
126
        {
127
            synchronized (lock) 
128
            {
129
                if (!aprAvailable) 
116
                    return;
130
                    return;
117
                }
131
                
118
                try {
132
                try 
133
                {
119
                    terminateAPR();
134
                    terminateAPR();
120
                } catch (Throwable t) {
135
                } 
136
                catch (Throwable t) 
137
                {
121
                    ExceptionUtils.handleThrowable(t);
138
                    ExceptionUtils.handleThrowable(t);
122
                    log.info(sm.getString("aprListener.aprDestroy"));
139
                    log.info(stringManager.getString("aprListener.aprDestroy"));
123
                }
140
                }
124
            }
141
            }
125
        }
142
        }
Lines 127-179 Link Here
127
    }
144
    }
128
145
129
    private static void terminateAPR()
146
    private static void terminateAPR()
130
        throws ClassNotFoundException, NoSuchMethodException,
147
    throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException
131
               IllegalAccessException, InvocationTargetException
132
    {
148
    {
133
        String methodName = "terminate";
149
        String methodName = "terminate";
134
        Method method = Class.forName("org.apache.tomcat.jni.Library")
150
        Method method = Class.forName("org.apache.tomcat.jni.Library").getMethod(methodName, (Class [])null);
135
            .getMethod(methodName, (Class [])null);
136
        method.invoke(null, (Object []) null);
151
        method.invoke(null, (Object []) null);
137
        aprAvailable = false;
152
        aprAvailable = false;
138
        aprInitialized = false;
153
        aprInitialized = false;
154
        fipsModeActive = false;
155
        sslAvailable = false; // Well we cleaned the pool in terminate.
139
        sslInitialized = false; // Well we cleaned the pool in terminate.
156
        sslInitialized = false; // Well we cleaned the pool in terminate.
140
    }
157
    }
141
158
142
    private static void init()
159
    private static void initializeAPR()
143
    {
160
    {
144
        int major = 0;
161
        int major = 0;
145
        int minor = 0;
162
        int minor = 0;
146
        int patch = 0;
163
        int patch = 0;
164
        
165
        // installed version
147
        int apver = 0;
166
        int apver = 0;
167
        
168
        // required version
148
        int rqver = TCN_REQUIRED_MAJOR * 1000 + TCN_REQUIRED_MINOR * 100 + TCN_REQUIRED_PATCH;
169
        int rqver = TCN_REQUIRED_MAJOR * 1000 + TCN_REQUIRED_MINOR * 100 + TCN_REQUIRED_PATCH;
170
        
171
        // recommended version
149
        int rcver = TCN_REQUIRED_MAJOR * 1000 + TCN_REQUIRED_MINOR * 100 + TCN_RECOMMENDED_PV;
172
        int rcver = TCN_REQUIRED_MAJOR * 1000 + TCN_REQUIRED_MINOR * 100 + TCN_RECOMMENDED_PV;
150
173
151
        if (aprInitialized) {
174
        if (aprInitialized)
152
            return;
175
            return;
153
        }
176
        
154
        aprInitialized = true;
177
        aprInitialized = true;		// aprInitialized indicates whether initialization has been attempted
178
        							// aprAvailable indicates whether initialization has succeeded
155
179
156
        try {
180
        try 
181
        {
182
            Class<?> clazz = Class.forName("org.apache.tomcat.jni.Library");
157
            String methodName = "initialize";
183
            String methodName = "initialize";
158
            Class<?> paramTypes[] = new Class[1];
184
            Class<?> paramTypes[] = new Class[]{String.class};
159
            paramTypes[0] = String.class;
185
            Object paramValues[] = new Object[]{null};
160
            Object paramValues[] = new Object[1];
161
            paramValues[0] = null;
162
            Class<?> clazz = Class.forName("org.apache.tomcat.jni.Library");
163
            Method method = clazz.getMethod(methodName, paramTypes);
186
            Method method = clazz.getMethod(methodName, paramTypes);
164
            method.invoke(null, paramValues);
187
            method.invoke(null, paramValues);		// invoke the static "initialize" method
188
            
165
            major = clazz.getField("TCN_MAJOR_VERSION").getInt(null);
189
            major = clazz.getField("TCN_MAJOR_VERSION").getInt(null);
166
            minor = clazz.getField("TCN_MINOR_VERSION").getInt(null);
190
            minor = clazz.getField("TCN_MINOR_VERSION").getInt(null);
167
            patch = clazz.getField("TCN_PATCH_VERSION").getInt(null);
191
            patch = clazz.getField("TCN_PATCH_VERSION").getInt(null);
168
            apver = major * 1000 + minor * 100 + patch;
192
            apver = major * 1000 + minor * 100 + patch;
169
        } catch (Throwable t) {
193
        } 
194
        catch (Throwable t) 
195
        {
170
            ExceptionUtils.handleThrowable(t);
196
            ExceptionUtils.handleThrowable(t);
171
            log.info(sm.getString("aprListener.aprInit",
197
            log.info(stringManager.getString("aprListener.aprInit",
172
                    System.getProperty("java.library.path")));
198
                    System.getProperty("java.library.path")));
173
            return;
199
            return;
174
        }
200
        }
175
        if (apver < rqver) {
201
        if (apver < rqver) 
176
            log.error(sm.getString("aprListener.tcnInvalid", major + "."
202
        {
203
            log.error(stringManager.getString("aprListener.tcnInvalid", major + "."
177
                    + minor + "." + patch,
204
                    + minor + "." + patch,
178
                    TCN_REQUIRED_MAJOR + "." +
205
                    TCN_REQUIRED_MAJOR + "." +
179
                    TCN_REQUIRED_MINOR + "." +
206
                    TCN_REQUIRED_MINOR + "." +
Lines 187-224 Link Here
187
            }
214
            }
188
            return;
215
            return;
189
        }
216
        }
190
        if (apver < rcver) {
217
        if (apver < rcver) 
191
            log.info(sm.getString("aprListener.tcnVersion", major + "."
218
        {
219
            log.info(stringManager.getString("aprListener.tcnVersion", major + "."
192
                    + minor + "." + patch,
220
                    + minor + "." + patch,
193
                    TCN_REQUIRED_MAJOR + "." +
221
                    TCN_REQUIRED_MAJOR + "." +
194
                    TCN_RECOMMENDED_MINOR + "." +
222
                    TCN_RECOMMENDED_MINOR + "." +
195
                    TCN_RECOMMENDED_PV));
223
                    TCN_RECOMMENDED_PV));
196
        }
224
        }
197
225
198
        log.info(sm.getString("aprListener.tcnValid", major + "."
226
        log.info(stringManager.getString("aprListener.tcnValid", major + "."
199
                    + minor + "." + patch));
227
                    + minor + "." + patch));
200
228
201
        // Log APR flags
229
        // Log APR flags
202
        log.info(sm.getString("aprListener.flags",
230
        log.info(stringManager.getString("aprListener.flags",
203
                Boolean.valueOf(Library.APR_HAVE_IPV6),
231
                Boolean.valueOf(Library.APR_HAVE_IPV6),
204
                Boolean.valueOf(Library.APR_HAS_SENDFILE),
232
                Boolean.valueOf(Library.APR_HAS_SENDFILE),
205
                Boolean.valueOf(Library.APR_HAS_SO_ACCEPTFILTER),
233
                Boolean.valueOf(Library.APR_HAS_SO_ACCEPTFILTER),
206
                Boolean.valueOf(Library.APR_HAS_RANDOM)));
234
                Boolean.valueOf(Library.APR_HAS_RANDOM)));
235
        
236
        // initialization is complete and the library version(s) are compatible
207
        aprAvailable = true;
237
        aprAvailable = true;
208
    }
238
    }
209
239
240
    /**
241
     * 
242
     * @throws ClassNotFoundException
243
     * @throws NoSuchMethodException
244
     * @throws IllegalAccessException
245
     * @throws InvocationTargetException
246
     */
210
    private static void initializeSSL()
247
    private static void initializeSSL()
211
        throws ClassNotFoundException, NoSuchMethodException,
248
    throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException
212
               IllegalAccessException, InvocationTargetException
213
    {
249
    {
214
250
        if ("off".equalsIgnoreCase(SSLEngine))
215
        if ("off".equalsIgnoreCase(SSLEngine)) {
216
            return;
251
            return;
217
        }
252
        
218
        if (sslInitialized) {
253
        //only once per VM
219
             //only once per VM
254
        if (sslInitialized)
220
            return;
255
            return;
221
        }
222
        sslInitialized = true;
256
        sslInitialized = true;
223
257
224
        String methodName = "randSet";
258
        String methodName = "randSet";
Lines 230-258 Link Here
230
        Method method = clazz.getMethod(methodName, paramTypes);
264
        Method method = clazz.getMethod(methodName, paramTypes);
231
        method.invoke(null, paramValues);
265
        method.invoke(null, paramValues);
232
266
233
234
        methodName = "initialize";
267
        methodName = "initialize";
235
        paramValues[0] = "on".equalsIgnoreCase(SSLEngine)?null:SSLEngine;
268
        paramValues[0] = "on".equalsIgnoreCase(SSLEngine)?null:SSLEngine;
236
        method = clazz.getMethod(methodName, paramTypes);
269
        method = clazz.getMethod(methodName, paramTypes);
237
        method.invoke(null, paramValues);
270
        method.invoke(null, paramValues);
238
271
272
        boolean initializeFIPS = isFIPSModeOn();
273
        if(initializeFIPS)
274
        {
275
            log.info( stringManager.getString("aprListener.initializingFIPS") );
276
        	boolean success = initializeFIPS();
277
        	if(success)
278
        		log.info( stringManager.getString("aprListener.initializeFIPSSuccess") );
279
        	else
280
        	{
281
        		String msg = stringManager.getString("aprListener.initializeFIPSFailed");
282
        		log.info( msg );
283
        		
284
        		// do not allow SSL to be called if FIPS was requested but did not initialize
285
        		throw new InvocationTargetException(null, msg);
286
        	}
287
        }
288
        
239
        sslAvailable = true;
289
        sslAvailable = true;
240
    }
290
    }
241
291
242
    public String getSSLEngine() {
292
    /**
293
     * Initialize FIPS mode in a way that won't crash if the FIPS libtcnative
294
     * and associated libraries are not available.
295
     * 
296
     * @param initializeFIPS
297
     * @return
298
     */
299
	private static boolean initializeFIPS()
300
	throws NoSuchMethodException
301
	{
302
		try
303
        {
304
            Class<?> clazz = Class.forName("org.apache.tomcat.jni.SSL");
305
	        String methodName = "fipsModeSet";
306
	        Method method = clazz.getMethod(methodName, new Class[]{Integer.class});
307
	        Object[] fipsParamValues = new Object[]{Integer.valueOf(1)};
308
		    Object result = method.invoke(null, fipsParamValues);
309
		    if(result instanceof Integer)
310
		    {
311
		    	fipsModeActive = ((Integer) result).intValue() > 0; 
312
		    	return fipsModeActive;		// success is a return value greater than zero
313
		    }
314
		    else
315
                log.info( stringManager.getString("aprListener.fipsModeSetInvalid") );
316
        }
317
        catch(InvocationTargetException itX)
318
        {
319
            log.info( stringManager.getString("aprListener.fipsModeUnavailable") + "\n" + itX.getMessage() );
320
	    } 
321
        catch (Throwable t) 
322
        {
323
	        if (!log.isDebugEnabled())
324
	            log.debug(stringManager.getString("aprListener.aprInit", System.getProperty("java.library.path")), t);
325
	        else
326
	            log.info(stringManager.getString("aprListener.aprInit", System.getProperty("java.library.path")));
327
	    }
328
        return false;
329
	}
330
331
	/**
332
	 * Determine if the SSL property is set in the AprLifecycleListener configuration (i.e. SSL is requested to be available)
333
	 * 
334
	 * @return
335
	 */
336
    public static boolean isSSLOn()
337
    {
338
    	return ! "off".equalsIgnoreCase(AprLifecycleListener.SSLEngine);    	
339
    }
340
341
    /**
342
	 * Determine if the FIPSMode property is set in the AprLifecycleListener configuration (i.e. FIPS mode must be on)
343
     * 
344
     * @return
345
     */
346
    public static boolean isFIPSModeOn()
347
    {
348
    	return "on".equalsIgnoreCase(AprLifecycleListener.FIPSMode);    	
349
    }
350
351
    /**
352
     * If FIPS mode has been requested and was successfully initialized then return TRUE,
353
     * else return FALSE
354
     * 
355
     * @return
356
     */
357
    public boolean isFIPSModeActive()
358
    {
359
    	return fipsModeActive;
360
    }
361
    
362
    public String getSSLEngine() 
363
    {
243
        return SSLEngine;
364
        return SSLEngine;
244
    }
365
    }
245
366
246
    public void setSSLEngine(String SSLEngine) {
367
    /**
247
        AprLifecycleListener.SSLEngine = SSLEngine;
368
     * The SSLEngine must be set before SSL is initialized, else this will have no effect.
369
     * 
370
     * @param SSLEngine
371
     */
372
    public void setSSLEngine(String SSLEngine) 
373
    {
374
    	if(! sslInitialized)		// added so that the random seem class being used is consistent with that returned from getSSLEngine
375
    		AprLifecycleListener.SSLEngine = SSLEngine;
248
    }
376
    }
249
377
250
    public String getSSLRandomSeed() {
378
    public String getFIPSMode() 
379
    {
380
        return AprLifecycleListener.FIPSMode;
381
    }
382
383
    /**
384
     * FIPSMode must be set before SSL is initialized, else this will have no effect.
385
     * 
386
     * @param FIPSMode
387
     */
388
    public void setFIPSMode(String FIPSMode) 
389
    {
390
    	if(! sslInitialized)		// added so that the random seem class being used is consistent with that returned from getFIPSMode
391
    		AprLifecycleListener.FIPSMode = FIPSMode;
392
    }
393
394
    public String getSSLRandomSeed() 
395
    {
251
        return SSLRandomSeed;
396
        return SSLRandomSeed;
252
    }
397
    }
253
398
254
    public void setSSLRandomSeed(String SSLRandomSeed) {
399
    /**
255
        AprLifecycleListener.SSLRandomSeed = SSLRandomSeed;
400
     * SSLRandomSeed must be set before this instance is initialized, else this will have no effect.
401
     * 
402
     * @param SSLRandomSeed
403
     */
404
    public void setSSLRandomSeed(String SSLRandomSeed) 
405
    {
406
    	if(! sslInitialized)		// added so that the random seem class being used is consistent with that returned from getSSLRandomSeed()
407
    		AprLifecycleListener.SSLRandomSeed = SSLRandomSeed;
256
    }
408
    }
257
409
410
    /**
411
     * This is not a production method, it is just a simple way to test
412
     * that the APR libraries can be loaded and that the versions are usable.
413
     * 
414
     * @param argv
415
     */
416
    public static void main(String[] argv)
417
    {
418
    	System.out.println( "Loading APR libraries from " + System.getProperty("java.library.path") );
419
    	AprLifecycleListener lifecycleListener = new AprLifecycleListener();
420
    	Lifecycle lifecycle = new Lifecycle()
421
		{
422
    		private LifecycleState state = LifecycleState.NEW;
423
    		
424
			@Override
425
			public void stop() throws LifecycleException{state = LifecycleState.STOPPED;}
426
			
427
			@Override
428
			public void start() throws LifecycleException{state = LifecycleState.STARTED;}
429
			
430
			@Override
431
			public void removeLifecycleListener(LifecycleListener listener){}
432
			
433
			@Override
434
			public LifecycleListener[] findLifecycleListeners(){return null;}
435
			
436
			@Override
437
			public void addLifecycleListener(LifecycleListener listener){}
438
439
			@Override
440
			public void init() throws LifecycleException {state = LifecycleState.INITIALIZED;}
441
442
			@Override
443
			public void destroy() throws LifecycleException {state = LifecycleState.DESTROYED;}
444
445
			@Override
446
			public LifecycleState getState() {return state;}
447
448
			@Override
449
			public String getStateName() {return state.toString();}
450
		};
451
		
452
    	LifecycleEvent initEvent = new LifecycleEvent(lifecycle, Lifecycle.BEFORE_INIT_EVENT, null);
453
    	LifecycleEvent destroyEvent = new LifecycleEvent(lifecycle, Lifecycle.AFTER_DESTROY_EVENT, null);
454
    	
455
    	lifecycleListener.setSSLEngine("on");
456
    	lifecycleListener.setFIPSMode("on");
457
    	lifecycleListener.lifecycleEvent(initEvent);
458
    	
459
    	lifecycleListener.lifecycleEvent(destroyEvent);
460
    }
258
}
461
}
(-)java/org/apache/catalina/core/LocalStrings.properties (+7 lines)
Lines 59-64 Link Here
59
aprListener.sslInit=Failed to initialize the SSLEngine.
59
aprListener.sslInit=Failed to initialize the SSLEngine.
60
aprListener.tcnValid=Loaded APR based Apache Tomcat Native library {0}.
60
aprListener.tcnValid=Loaded APR based Apache Tomcat Native library {0}.
61
aprListener.flags=APR capabilities: IPv6 [{0}], sendfile [{1}], accept filters [{2}], random [{3}].
61
aprListener.flags=APR capabilities: IPv6 [{0}], sendfile [{1}], accept filters [{2}], random [{3}].
62
aprListener.initializingSSL=Initializing APR SSL library now ...
63
aprListener.initializedSSL=APR library has been successfully initialized.
64
aprListener.initializedSSLFailed=APR library initialization FAILED.
65
aprListener.initializingFIPS=FIPS mode has been requested, initializing FIPS mode now ...
66
aprListener.initializeFIPSSuccess=FIPS mode has been successfully initialized.
67
aprListener.fipsModeSetInvalid=The call to set FIPS mode returned an invalid value or type.  OpenSSL is not running in FIPS mode.
68
aprListener.initializeFIPSFailed=FIPS mode initialization FAILED.
62
containerBase.alreadyStarted=Container {0} has already been started
69
containerBase.alreadyStarted=Container {0} has already been started
63
containerBase.notConfigured=No basic Valve has been configured
70
containerBase.notConfigured=No basic Valve has been configured
64
containerBase.notStarted=Container {0} has not been started
71
containerBase.notStarted=Container {0} has not been started
(-)java/org/apache/tomcat/jni/Library.java (-51 / +130 lines)
Lines 20-76 Link Here
20
/** Library
20
/** Library
21
 *
21
 *
22
 * @author Mladen Turk
22
 * @author Mladen Turk
23
 * @author cbeckey@gmail.com	added FIPS Mode
23
 * @version $Id$
24
 * @version $Id$
24
 */
25
 */
25
26
26
public final class Library {
27
public final class Library 
27
28
{
28
    /* Default library names */
29
    // Library names, organized as "groups".  
29
    private static String [] NAMES = {"tcnative-1", "libtcnative-1"};
30
	// 1.) Only one group must successfully load for the initialization to succeed.
31
	// 2.) An entire group must be loaded for the initialization to succeed.
32
    private static String [][] LIBRARY_NAMES = 
33
    {
34
    	new String[]{"tcnative-1"}, 
35
    	new String[]{"libapr-1", "libeay32", "libtcnative-1"}
36
    };
37
    
30
    /*
38
    /*
31
     * A handle to the unique Library singleton instance.
39
     * A handle to the unique Library singleton instance.
32
     */
40
     */
33
    private static Library _instance = null;
41
    private static Library _instance = null;
34
42
43
    // grab the relevant system properties so we can produce useful error messages
44
    private final String libraryPath = System.getProperty("java.library.path");
45
    private final String systemPathSeperator = System.getProperty("path.separator");
46
    private final String [] libraryPaths = libraryPath == null || systemPathSeperator == null ? null : libraryPath.split(systemPathSeperator);
47
    
48
    /**
49
     * Load the default librar(ies).
50
     * 
51
     * @throws Exception
52
     */
35
    private Library()
53
    private Library()
36
        throws Exception
54
    throws Exception
37
    {
55
    {
56
        StringBuilder err = new StringBuilder();
57
        StringBuilder status = new StringBuilder();
58
        StringBuilder libraryGroupStatus = null;
59
38
        boolean loaded = false;
60
        boolean loaded = false;
39
        StringBuilder err = new StringBuilder();
61
        for( int libraryGroup = 0; libraryGroup < LIBRARY_NAMES.length && ! loaded; libraryGroup++ ) 
40
        for (int i = 0; i < NAMES.length; i++) {
62
        {
41
            try {
63
        	//System.out.println( "Attempting to load library group " + libraryGroup );
42
                System.loadLibrary(NAMES[i]);
64
        	libraryGroupStatus = new StringBuilder();
43
                loaded = true;
65
        	String libName = null;
44
            }
66
        	
45
            catch (Throwable t) {
67
        	// all libraries in a group (i.e. same primary index) must be loaded
46
                if (t instanceof ThreadDeath) {
68
        	// this was changed to allow error reporting to specify the missing library
47
                    throw (ThreadDeath) t;
69
        	boolean groupLoaded = true;
48
                }
70
        	for(int libraryGroupMember = 0; libraryGroupMember < LIBRARY_NAMES[libraryGroup].length; ++libraryGroupMember)
49
                if (t instanceof VirtualMachineError) {
71
        	{
50
                    throw (VirtualMachineError) t;
72
        		libName = LIBRARY_NAMES[libraryGroup][libraryGroupMember];
51
                }
73
        		if(libraryGroupStatus.length() > 0) libraryGroupStatus.append(",");
52
                String name = System.mapLibraryName(NAMES[i]);
74
        		libraryGroupStatus.append(libName);
53
                String path = System.getProperty("java.library.path");
75
	            try 
54
                String sep = System.getProperty("path.separator");
76
	            { 
55
                String [] paths = path.split(sep);
77
	            	//System.out.println( "Attempting to load library " + libName );
56
                for (int j=0; j<paths.length; j++) {
78
	            	System.loadLibrary(libName);
57
                    java.io.File fd = new java.io.File(paths[j] , name);
79
	            	libraryGroupStatus.append("[loaded]");
58
                    if (fd.exists()) {
80
	            }
59
                        t.printStackTrace();
81
	            catch (ThreadDeath tde)
60
                    }
82
	            {
61
                }
83
	            	groupLoaded = false;		// not really needed because an error is being thrown 
62
                if ( i > 0)
84
	            	throw tde;		// seriously out of luck, just throw the runtime exception
63
                    err.append(", ");
85
	            }
64
                err.append(t.getMessage());
86
	            catch (VirtualMachineError vme)
65
            }
87
	            {
66
            if (loaded)
88
	            	groupLoaded = false;		// not really needed because an error is being thrown 
67
                break;
89
	            	throw vme;		// seriously out of luck, just throw the runtime exception
90
	            }
91
	            catch (Throwable t) 
92
	            {
93
	            	// the entire group fails to load if any one element fails to load
94
	            	groupLoaded = false; 
95
	            	
96
	            	// throwable instances that we can't recover from but can give some useful information for debugging.
97
	            	// This code will differentiate between a library simply not existing from one which failed to load
98
	            	// for some other reason.
99
	            	
100
	                // Maps a library name into a platform-specific string representing a native library.
101
	            	// Useful for producing the error message.
102
	            	String libraryFileName = libraryFileAbsolutePath(libName);
103
	            	if(libraryFileName == null)
104
		            	libraryGroupStatus.append("[not found]");
105
	            	else
106
		            	libraryGroupStatus.append("[found @ " + libraryFileName + ", but failed to load]");
107
	            		
108
	                err.append( t.getMessage() );
109
	            }
110
	            
111
	            status.append(libraryGroupStatus + "\n");
112
        	}
113
        	
114
            loaded = groupLoaded;
68
        }
115
        }
69
        if (!loaded) {
116
70
            err.append('(');
117
        if(! loaded)
71
            err.append(System.getProperty("java.library.path"));
118
        {
72
            err.append(')');
119
	        err.append(status);
73
            throw new UnsatisfiedLinkError(err.toString());
120
	        //System.out.println(status);
121
	        throw new UnsatisfiedLinkError(err.toString());
74
        }
122
        }
75
    }
123
    }
76
124
Lines 79-88 Link Here
79
        System.loadLibrary(libraryName);
127
        System.loadLibrary(libraryName);
80
    }
128
    }
81
129
130
    /**
131
     * If the library exists on the library path then return the 
132
     * native path as a string, else return null.
133
     * This method is intended to assist in providing useful error messages, other uses
134
     * may be possible.
135
     *  
136
     * @param libraryName
137
     * @return
138
     * @since 14March2011 
139
     * @author cbeckey@gmail.com
140
     */
141
    private String libraryFileAbsolutePath(String libraryName)
142
    {
143
        String systemDependentlibName = System.mapLibraryName(libraryName);
144
        for( String libPathElement : libraryPaths ) 
145
        {
146
            java.io.File fd = new java.io.File( libPathElement, systemDependentlibName );
147
            if( fd.exists() )
148
            	return fd.getAbsolutePath();
149
        }
150
        
151
    	return null;
152
    }
153
    
82
    /* create global TCN's APR pool
154
    /* create global TCN's APR pool
83
     * This has to be the first call to TCN library.
155
     * This has to be the first call to TCN library.
84
     */
156
     */
85
    private static native boolean initialize();
157
    private static native boolean initialize();
158
    
86
    /* destroy global TCN's APR pool
159
    /* destroy global TCN's APR pool
87
     * This has to be the last call to TCN library.
160
     * This has to be the last call to TCN library.
88
     */
161
     */
Lines 133-155 Link Here
133
    public static boolean APR_HAS_LARGE_FILES     = false;
206
    public static boolean APR_HAS_LARGE_FILES     = false;
134
    public static boolean APR_HAS_XTHREAD_FILES   = false;
207
    public static boolean APR_HAS_XTHREAD_FILES   = false;
135
    public static boolean APR_HAS_OS_UUID         = false;
208
    public static boolean APR_HAS_OS_UUID         = false;
209
    
136
    /* Are we big endian? */
210
    /* Are we big endian? */
137
    public static boolean APR_IS_BIGENDIAN        = false;
211
    public static boolean APR_IS_BIGENDIAN        = false;
212
    
138
    /* APR sets APR_FILES_AS_SOCKETS to 1 on systems where it is possible
213
    /* APR sets APR_FILES_AS_SOCKETS to 1 on systems where it is possible
139
     * to poll on files/pipes.
214
     * to poll on files/pipes.
140
     */
215
     */
141
    public static boolean APR_FILES_AS_SOCKETS    = false;
216
    public static boolean APR_FILES_AS_SOCKETS    = false;
217
    
142
    /* This macro indicates whether or not EBCDIC is the native character set.
218
    /* This macro indicates whether or not EBCDIC is the native character set.
143
     */
219
     */
144
    public static boolean APR_CHARSET_EBCDIC      = false;
220
    public static boolean APR_CHARSET_EBCDIC      = false;
221
    
145
    /* Is the TCP_NODELAY socket option inherited from listening sockets?
222
    /* Is the TCP_NODELAY socket option inherited from listening sockets?
146
     */
223
     */
147
    public static boolean APR_TCP_NODELAY_INHERITED = false;
224
    public static boolean APR_TCP_NODELAY_INHERITED = false;
225
    
148
    /* Is the O_NONBLOCK flag inherited from listening sockets?
226
    /* Is the O_NONBLOCK flag inherited from listening sockets?
149
     */
227
     */
150
    public static boolean APR_O_NONBLOCK_INHERITED  = false;
228
    public static boolean APR_O_NONBLOCK_INHERITED  = false;
151
229
152
153
    public static int APR_SIZEOF_VOIDP;
230
    public static int APR_SIZEOF_VOIDP;
154
    public static int APR_PATH_MAX;
231
    public static int APR_PATH_MAX;
155
    public static int APRMAXHOSTLEN;
232
    public static int APRMAXHOSTLEN;
Lines 162-179 Link Here
162
    public static native long globalPool();
239
    public static native long globalPool();
163
240
164
    /**
241
    /**
165
     * Setup any APR internal data structures.  This MUST be the first function
242
     * Setup any APR internal data structures.  This is THE entry point for this module and
166
     * called for any APR library.
243
     * MUST be the first function called for any APR library.
167
     * @param libraryName the name of the library to load
244
     * 
245
     * @param libraryName the name of the library to load, or null to load the default libraries.
168
     */
246
     */
169
    public static boolean initialize(String libraryName)
247
    public static boolean initialize(String libraryName)
170
        throws Exception
248
    throws Exception
171
    {
249
    {
172
        if (_instance == null) {
250
        if (_instance == null) 
251
        {
173
            if (libraryName == null)
252
            if (libraryName == null)
174
                _instance = new Library();
253
                _instance = new Library();
175
            else
254
            else
176
                _instance = new Library(libraryName);
255
                _instance = new Library(libraryName);
256
            
177
            TCN_MAJOR_VERSION  = version(0x01);
257
            TCN_MAJOR_VERSION  = version(0x01);
178
            TCN_MINOR_VERSION  = version(0x02);
258
            TCN_MINOR_VERSION  = version(0x02);
179
            TCN_PATCH_VERSION  = version(0x03);
259
            TCN_PATCH_VERSION  = version(0x03);
Lines 212-224 Link Here
212
            APR_CHARSET_EBCDIC      = has(18);
292
            APR_CHARSET_EBCDIC      = has(18);
213
            APR_TCP_NODELAY_INHERITED = has(19);
293
            APR_TCP_NODELAY_INHERITED = has(19);
214
            APR_O_NONBLOCK_INHERITED  = has(20);
294
            APR_O_NONBLOCK_INHERITED  = has(20);
215
            if (APR_MAJOR_VERSION < 1) {
295
            
216
                throw new UnsatisfiedLinkError("Unsupported APR Version (" +
296
            if (APR_MAJOR_VERSION < 1)
217
                                               aprVersionString() + ")");
297
                throw new UnsatisfiedLinkError("Unsupported APR Version (" + aprVersionString() + ")");
218
            }
298
            if (!APR_HAS_THREADS)
219
            if (!APR_HAS_THREADS) {
220
                throw new UnsatisfiedLinkError("Missing APR_HAS_THREADS");
299
                throw new UnsatisfiedLinkError("Missing APR_HAS_THREADS");
221
            }
300
            
222
        }
301
        }
223
        return initialize();
302
        return initialize();
224
    }
303
    }
(-)java/org/apache/tomcat/jni/SSL.java (+12 lines)
Lines 20-25 Link Here
20
/** SSL
20
/** SSL
21
 *
21
 *
22
 * @author Mladen Turk
22
 * @author Mladen Turk
23
 * @author cbeckey@gmail.com	added FIPS Mode
23
 * @version $Id$
24
 * @version $Id$
24
 */
25
 */
25
26
Lines 241-246 Link Here
241
    public static native boolean randLoad(String filename);
242
    public static native boolean randLoad(String filename);
242
243
243
    /**
244
    /**
245
     * Enable/Disable FIPS Mode.
246
     * @param mode 1 - enable, 0 - disable
247
     * @return FIPS_mode_set return code
248
     */
249
    public static int fipsModeSet(Integer mode)
250
    {
251
    	return fipsModeSet(mode.intValue());
252
    }
253
    public static native int fipsModeSet(int mode);
254
255
    /**
244
     * Writes a number of random bytes (currently 1024) to
256
     * Writes a number of random bytes (currently 1024) to
245
     * file <code>filename</code> which can be used to initialize the PRNG
257
     * file <code>filename</code> which can be used to initialize the PRNG
246
     * by calling randLoad in a later session.
258
     * by calling randLoad in a later session.

Return to bug 50570