001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.log;
016    
017    import com.liferay.portal.kernel.util.CharPool;
018    import com.liferay.portal.kernel.util.GetterUtil;
019    import com.liferay.portal.kernel.util.HtmlUtil;
020    import com.liferay.portal.kernel.util.PropsKeys;
021    import com.liferay.portal.kernel.util.SystemProperties;
022    
023    import java.util.ArrayList;
024    import java.util.List;
025    
026    /**
027     * @author Tomas Polesovsky
028     * @author Raymond Aug??
029     */
030    public class SanitizerLogWrapper extends LogWrapper {
031    
032            public static void init() {
033                    if (!_LOG_SANITIZER_ENABLED) {
034                            return;
035                    }
036    
037                    _LOG_SANITIZER_ESCAPE_HTML_ENABLED = GetterUtil.getBoolean(
038                            SystemProperties.get(PropsKeys.LOG_SANITIZER_ESCAPE_HTML_ENABLED));
039    
040                    _LOG_SANITIZER_REPLACEMENT_CHARACTER = (char)GetterUtil.getInteger(
041                            SystemProperties.get(
042                                    PropsKeys.LOG_SANITIZER_REPLACEMENT_CHARACTER));
043    
044                    int[] whitelistCharacters = GetterUtil.getIntegerValues(
045                            SystemProperties.getArray(
046                                    PropsKeys.LOG_SANITIZER_WHITELIST_CHARACTERS));
047    
048                    for (int whitelistCharacter : whitelistCharacters) {
049                            if ((whitelistCharacter >= 0) &&
050                                    (whitelistCharacter < _whitelistCharacters.length)) {
051    
052                                    _whitelistCharacters[whitelistCharacter] = 1;
053                            }
054                            else {
055                                    System.err.println(
056                                            "Unable to register log whitelist character " +
057                                                    whitelistCharacter);
058                            }
059                    }
060            }
061    
062            public static boolean isEnabled() {
063                    return _LOG_SANITIZER_ENABLED;
064            }
065    
066            public SanitizerLogWrapper(Log log) {
067                    super(log);
068    
069                    setLogWrapperClassName(SanitizerLogWrapper.class.getName());
070            }
071    
072            @Override
073            public void debug(Object msg) {
074                    super.debug(sanitize(msg));
075            }
076    
077            @Override
078            public void debug(Object msg, Throwable t) {
079                    super.debug(sanitize(msg), sanitize(t));
080            }
081    
082            @Override
083            public void debug(Throwable t) {
084                    super.debug(sanitize(t));
085            }
086    
087            @Override
088            public void error(Object msg) {
089                    super.error(sanitize(msg));
090            }
091    
092            @Override
093            public void error(Object msg, Throwable t) {
094                    super.error(sanitize(msg), sanitize(t));
095            }
096    
097            @Override
098            public void error(Throwable t) {
099                    super.error(sanitize(t));
100            }
101    
102            @Override
103            public void fatal(Object msg) {
104                    super.fatal(sanitize(msg));
105            }
106    
107            @Override
108            public void fatal(Object msg, Throwable t) {
109                    super.fatal(sanitize(msg), sanitize(t));
110            }
111    
112            @Override
113            public void fatal(Throwable t) {
114                    super.fatal(sanitize(t));
115            }
116    
117            @Override
118            public void info(Object msg) {
119                    super.info(sanitize(msg));
120            }
121    
122            @Override
123            public void info(Object msg, Throwable t) {
124                    super.info(sanitize(msg), sanitize(t));
125            }
126    
127            @Override
128            public void info(Throwable t) {
129                    super.info(sanitize(t));
130            }
131    
132            @Override
133            public void trace(Object msg) {
134                    super.trace(sanitize(msg));
135            }
136    
137            @Override
138            public void trace(Object msg, Throwable t) {
139                    super.trace(sanitize(msg), sanitize(t));
140            }
141    
142            @Override
143            public void trace(Throwable t) {
144                    super.trace(sanitize(t));
145            }
146    
147            @Override
148            public void warn(Object msg) {
149                    super.warn(sanitize(msg));
150            }
151    
152            @Override
153            public void warn(Object msg, Throwable t) {
154                    super.warn(sanitize(msg), sanitize(t));
155            }
156    
157            @Override
158            public void warn(Throwable t) {
159                    super.warn(sanitize(t));
160            }
161    
162            protected String sanitize(Object obj) {
163                    if (obj == null) {
164                            return null;
165                    }
166    
167                    String message = obj.toString();
168    
169                    return sanitize(message, message);
170            }
171    
172            protected String sanitize(String message, String defaultResult) {
173                    if (message == null) {
174                            return null;
175                    }
176    
177                    char[] chars = message.toCharArray();
178                    boolean sanitized = false;
179    
180                    for (int i = 0; i < chars.length; i++) {
181                            int c = chars[i];
182    
183                            if ((c >= 0) && (c < _whitelistCharacters.length) &&
184                                    (_whitelistCharacters[c] == 0)) {
185    
186                                    chars[i] = _LOG_SANITIZER_REPLACEMENT_CHARACTER;
187                                    sanitized = true;
188                            }
189                    }
190    
191                    if (sanitized) {
192                            String sanitizedMessage = new String(chars);
193    
194                            sanitizedMessage = sanitizedMessage.concat(_SANITIZED);
195    
196                            if (_LOG_SANITIZER_ESCAPE_HTML_ENABLED) {
197                                    return HtmlUtil.escape(sanitizedMessage);
198                            }
199    
200                            return sanitizedMessage;
201                    }
202    
203                    return defaultResult;
204            }
205    
206            protected Throwable sanitize(Throwable throwable) {
207                    List<Throwable> throwables = new ArrayList<Throwable>();
208    
209                    Throwable tempThrowable = throwable;
210    
211                    while (tempThrowable != null) {
212                            throwables.add(tempThrowable);
213    
214                            tempThrowable = tempThrowable.getCause();
215                    }
216    
217                    Throwable resultThrowable = null;
218    
219                    boolean sanitized = false;
220    
221                    for (int i = throwables.size() - 1; i > - 1; i--) {
222                            Throwable curThrowable = throwables.get(i);
223    
224                            String message = curThrowable.toString();
225    
226                            String sanitizedMessage = sanitize(message, null);
227    
228                            if (!sanitized && (sanitizedMessage == null)) {
229                                    resultThrowable = curThrowable;
230    
231                                    continue;
232                            }
233    
234                            if (sanitizedMessage == null) {
235                                    sanitizedMessage = message;
236                            }
237    
238                            sanitized = true;
239    
240                            resultThrowable = new LogSanitizerException(
241                                    sanitizedMessage, curThrowable.getStackTrace(),
242                                    resultThrowable);
243                    }
244    
245                    return resultThrowable;
246            }
247    
248            private static final String _SANITIZED = " [Sanitized]";
249    
250            private static boolean _LOG_SANITIZER_ENABLED = GetterUtil.getBoolean(
251                    SystemProperties.get(PropsKeys.LOG_SANITIZER_ENABLED));
252    
253            private static boolean _LOG_SANITIZER_ESCAPE_HTML_ENABLED = false;
254    
255            private static char _LOG_SANITIZER_REPLACEMENT_CHARACTER =
256                    CharPool.UNDERLINE;
257    
258            private static int[] _whitelistCharacters = new int[128];
259    
260    }