|
| 1 | +/** |
| 2 | + * OWASP Enterprise Security API (ESAPI) |
| 3 | + * |
| 4 | + * This file is part of the Open Web Application Security Project (OWASP) |
| 5 | + * Enterprise Security API (ESAPI) project. For details, please see |
| 6 | + * <a href="http://www.owasp.org/index.php/ESAPI">http://www.owasp.org/index.php/ESAPI</a>. |
| 7 | + * |
| 8 | + * Copyright (c) 2007 - The OWASP Foundation |
| 9 | + * |
| 10 | + * The ESAPI is published by OWASP under the BSD license. You should read and accept the |
| 11 | + * LICENSE before you use, modify, and/or redistribute this software. |
| 12 | + * |
| 13 | + * @created 2018 |
| 14 | + */ |
1 | 15 | package org.owasp.esapi.logging.java; |
2 | 16 |
|
3 | | -import java.io.Serializable; |
| 17 | +import java.util.ArrayList; |
4 | 18 | import java.util.HashMap; |
| 19 | +import java.util.List; |
| 20 | +import java.util.Map; |
5 | 21 |
|
| 22 | +import org.owasp.esapi.ESAPI; |
6 | 23 | import org.owasp.esapi.LogFactory; |
7 | 24 | import org.owasp.esapi.Logger; |
8 | | - |
| 25 | +import org.owasp.esapi.codecs.HTMLEntityCodec; |
| 26 | +import org.owasp.esapi.logging.appender.LogAppender; |
| 27 | +import org.owasp.esapi.logging.appender.LogPrefixAppender; |
| 28 | +import org.owasp.esapi.logging.cleaning.CodecLogScrubber; |
| 29 | +import org.owasp.esapi.logging.cleaning.CompositeLogScrubber; |
| 30 | +import org.owasp.esapi.logging.cleaning.LogScrubber; |
| 31 | +import org.owasp.esapi.logging.cleaning.NewlineLogScrubber; |
| 32 | +import org.owasp.esapi.reference.DefaultSecurityConfiguration; |
9 | 33 | /** |
10 | | - * Reference implementation of the LogFactory and Logger interfaces. This implementation uses the Java logging package, and marks each |
11 | | - * log message with the currently logged in user and the word "SECURITY" for security related events. See the |
12 | | - * <a href="JavaLogFactory.JavaLogger.html">JavaLogFactory.JavaLogger</a> Javadocs for the details on the JavaLogger reference implementation. |
13 | | - * |
14 | | - * @author Mike Fauzy ([email protected]) <a href="http://www.aspectsecurity.com">Aspect Security</a> |
15 | | - * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) <a href="http://www.aspectsecurity.com">Aspect Security</a> |
16 | | - * @since June 1, 2007 |
17 | | - * @see org.owasp.esapi.LogFactory |
18 | | - * @see org.owasp.esapi.logging.java.JavaLogFactory.JavaLogger |
| 34 | + * LogFactory implementation which creates JAVA supporting Loggers. |
| 35 | + * |
19 | 36 | */ |
20 | 37 | public class JavaLogFactory implements LogFactory { |
21 | | - private static volatile LogFactory singletonInstance; |
22 | | - |
23 | | - public static LogFactory getInstance() { |
24 | | - if ( singletonInstance == null ) { |
25 | | - synchronized ( JavaLogFactory.class ) { |
26 | | - if ( singletonInstance == null ) { |
27 | | - singletonInstance = new JavaLogFactory(); |
28 | | - } |
29 | | - } |
30 | | - } |
31 | | - return singletonInstance; |
| 38 | + /** Immune characters for the codec log scrubber for JAVA context.*/ |
| 39 | + private static final char[] IMMUNE_JAVA_HTML = {',', '.', '-', '_', ' ' }; |
| 40 | + /** Codec being used to clean messages for logging.*/ |
| 41 | + private static final HTMLEntityCodec HTML_CODEC = new HTMLEntityCodec(); |
| 42 | + /** Log appender instance.*/ |
| 43 | + private static LogAppender JAVA_LOG_APPENDER; |
| 44 | + /** Log cleaner instance.*/ |
| 45 | + private static LogScrubber JAVA_LOG_SCRUBBER; |
| 46 | + /** Bridge class for mapping esapi -> java log levels.*/ |
| 47 | + private static JavaLogBridge LOG_BRIDGE; |
| 48 | + |
| 49 | + static { |
| 50 | + boolean encodeLog = ESAPI.securityConfiguration().getBooleanProp(DefaultSecurityConfiguration.LOG_ENCODING_REQUIRED); |
| 51 | + JAVA_LOG_SCRUBBER = createLogScrubber(encodeLog); |
| 52 | + |
| 53 | + boolean logClientInfo = true; |
| 54 | + boolean logApplicationName = ESAPI.securityConfiguration().getBooleanProp(DefaultSecurityConfiguration.LOG_APPLICATION_NAME); |
| 55 | + String appName = ESAPI.securityConfiguration().getStringProp(DefaultSecurityConfiguration.APPLICATION_NAME); |
| 56 | + boolean logServerIp = ESAPI.securityConfiguration().getBooleanProp(DefaultSecurityConfiguration.LOG_SERVER_IP); |
| 57 | + JAVA_LOG_APPENDER = createLogAppender(logClientInfo, logServerIp, logApplicationName, appName); |
| 58 | + |
| 59 | + Map<Integer, JavaLogLevelHandler> levelLookup = new HashMap<>(); |
| 60 | + levelLookup.put(Logger.ALL, JavaLogLevelHandlers.ALL); |
| 61 | + levelLookup.put(Logger.TRACE, JavaLogLevelHandlers.FINEST); |
| 62 | + levelLookup.put(Logger.DEBUG, JavaLogLevelHandlers.FINE); |
| 63 | + levelLookup.put(Logger.INFO, JavaLogLevelHandlers.INFO); |
| 64 | + levelLookup.put(Logger.ERROR, JavaLogLevelHandlers.ERROR); |
| 65 | + levelLookup.put(Logger.WARNING, JavaLogLevelHandlers.WARNING); |
| 66 | + levelLookup.put(Logger.FATAL, JavaLogLevelHandlers.SEVERE); |
| 67 | + //LEVEL.OFF not used. If it's off why would we try to log it? |
| 68 | + |
| 69 | + LOG_BRIDGE = new JavaLogBridgeImpl(JAVA_LOG_APPENDER, JAVA_LOG_SCRUBBER, levelLookup); |
32 | 70 | } |
33 | | - |
34 | | - private HashMap<Serializable, Logger> loggersMap = new HashMap<Serializable, Logger>(); |
35 | | - |
36 | | - /** |
37 | | - * Null argument constructor for this implementation of the LogFactory interface |
38 | | - * needed for dynamic configuration. |
39 | | - */ |
40 | | - public JavaLogFactory() {} |
41 | | - |
42 | | - /** |
43 | | - * {@inheritDoc} |
44 | | - */ |
45 | | - public Logger getLogger(Class clazz) { |
46 | | - return getLogger(clazz.getName()); |
| 71 | + |
| 72 | + /** |
| 73 | + * Populates the default log scrubber for use in factory-created loggers. |
| 74 | + * @param requiresEncoding {@code true} if encoding is required for log content. |
| 75 | + * @return LogScrubber instance. |
| 76 | + */ |
| 77 | + /*package*/ static LogScrubber createLogScrubber(boolean requiresEncoding) { |
| 78 | + List<LogScrubber> messageScrubber = new ArrayList<>(); |
| 79 | + messageScrubber.add(new NewlineLogScrubber()); |
| 80 | + |
| 81 | + if (requiresEncoding) { |
| 82 | + messageScrubber.add(new CodecLogScrubber(HTML_CODEC, IMMUNE_JAVA_HTML)); |
| 83 | + } |
| 84 | + |
| 85 | + return new CompositeLogScrubber(messageScrubber); |
| 86 | + |
47 | 87 | } |
48 | | - |
| 88 | + |
49 | 89 | /** |
50 | | - * {@inheritDoc} |
51 | | - */ |
| 90 | + * Populates the default log appender for use in factory-created loggers. |
| 91 | + * @param appName |
| 92 | + * @param logApplicationName |
| 93 | + * @param logServerIp |
| 94 | + * @param logClientInfo |
| 95 | + * |
| 96 | + * @return LogAppender instance. |
| 97 | + */ |
| 98 | + /*package*/ static LogAppender createLogAppender(boolean logClientInfo, boolean logServerIp, boolean logApplicationName, String appName) { |
| 99 | + return new LogPrefixAppender(logClientInfo, logServerIp, logApplicationName, appName); |
| 100 | + } |
| 101 | + |
| 102 | + |
| 103 | + @Override |
52 | 104 | public Logger getLogger(String moduleName) { |
53 | | - |
54 | | - synchronized (loggersMap) { |
55 | | - // If a logger for this module already exists, we return the same one, otherwise we create a new one. |
56 | | - Logger moduleLogger = loggersMap.get(moduleName); |
57 | | - |
58 | | - if (moduleLogger == null) { |
59 | | - moduleLogger = new JavaLogger(moduleName); |
60 | | - loggersMap.put(moduleName, moduleLogger); |
61 | | - } |
62 | | - return moduleLogger; |
63 | | - } |
| 105 | + java.util.logging.Logger javaLogger = java.util.logging.Logger.getLogger(moduleName); |
| 106 | + return new JavaLogger(javaLogger, LOG_BRIDGE, Logger.ALL); |
64 | 107 | } |
65 | 108 |
|
66 | | - |
67 | | - |
| 109 | + @Override |
| 110 | + public Logger getLogger(@SuppressWarnings("rawtypes") Class clazz) { |
| 111 | + java.util.logging.Logger javaLogger = java.util.logging.Logger.getLogger(clazz.getName()); |
| 112 | + return new JavaLogger(javaLogger, LOG_BRIDGE, Logger.ALL); |
| 113 | + } |
68 | 114 |
|
69 | 115 | } |
0 commit comments