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.PropsUtil;
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                    _LOG_SANITIZER_ENABLED = GetterUtil.getBoolean(
034                            PropsUtil.get(PropsKeys.LOG_SANITIZER_ENABLED));
035    
036                    if (!_LOG_SANITIZER_ENABLED) {
037                            return;
038                    }
039    
040                    _LOG_SANITIZER_ESCAPE_HTML_ENABLED = GetterUtil.getBoolean(
041                            PropsUtil.get(PropsKeys.LOG_SANITIZER_ESCAPE_HTML_ENABLED));
042    
043                    _LOG_SANITIZER_REPLACEMENT_CHARACTER = (char)GetterUtil.getInteger(
044                            PropsUtil.get(PropsKeys.LOG_SANITIZER_REPLACEMENT_CHARACTER));
045    
046                    int[] whitelistCharacters = GetterUtil.getIntegerValues(
047                            PropsUtil.getArray(PropsKeys.LOG_SANITIZER_WHITELIST_CHARACTERS));
048    
049                    for (int whitelistCharacter : whitelistCharacters) {
050                            if ((whitelistCharacter >= 0) &&
051                                    (whitelistCharacter < _whitelistCharacters.length)) {
052    
053                                    _whitelistCharacters[whitelistCharacter] = 1;
054                            }
055                            else {
056                                    System.err.println(
057                                            "Unable to register log whitelist character " +
058                                                    whitelistCharacter);
059                            }
060                    }
061            }
062    
063            public SanitizerLogWrapper(Log log) {
064                    super(log);
065            }
066    
067            @Override
068            public void debug(Object msg) {
069                    if (!isDebugEnabled()) {
070                            return;
071                    }
072    
073                    super.debug(sanitize(msg));
074            }
075    
076            @Override
077            public void debug(Object msg, Throwable t) {
078                    if (!isDebugEnabled()) {
079                            return;
080                    }
081    
082                    super.debug(sanitize(msg), sanitize(t));
083            }
084    
085            @Override
086            public void debug(Throwable t) {
087                    if (!isDebugEnabled()) {
088                            return;
089                    }
090    
091                    super.debug(sanitize(t));
092            }
093    
094            @Override
095            public void error(Object msg) {
096                    if (!isErrorEnabled()) {
097                            return;
098                    }
099    
100                    super.error(sanitize(msg));
101            }
102    
103            @Override
104            public void error(Object msg, Throwable t) {
105                    if (!isErrorEnabled()) {
106                            return;
107                    }
108    
109                    super.error(sanitize(msg), sanitize(t));
110            }
111    
112            @Override
113            public void error(Throwable t) {
114                    if (!isErrorEnabled()) {
115                            return;
116                    }
117    
118                    super.error(sanitize(t));
119            }
120    
121            @Override
122            public void fatal(Object msg) {
123                    if (!isFatalEnabled()) {
124                            return;
125                    }
126    
127                    super.fatal(sanitize(msg));
128            }
129    
130            @Override
131            public void fatal(Object msg, Throwable t) {
132                    if (!isFatalEnabled()) {
133                            return;
134                    }
135    
136                    super.fatal(sanitize(msg), sanitize(t));
137            }
138    
139            @Override
140            public void fatal(Throwable t) {
141                    if (!isFatalEnabled()) {
142                            return;
143                    }
144    
145                    super.fatal(sanitize(t));
146            }
147    
148            @Override
149            public void info(Object msg) {
150                    if (!isInfoEnabled()) {
151                            return;
152                    }
153    
154                    super.info(sanitize(msg));
155            }
156    
157            @Override
158            public void info(Object msg, Throwable t) {
159                    if (!isInfoEnabled()) {
160                            return;
161                    }
162    
163                    super.info(sanitize(msg), sanitize(t));
164            }
165    
166            @Override
167            public void info(Throwable t) {
168                    if (!isInfoEnabled()) {
169                            return;
170                    }
171    
172                    super.info(sanitize(t));
173            }
174    
175            @Override
176            public void trace(Object msg) {
177                    if (!isTraceEnabled()) {
178                            return;
179                    }
180    
181                    super.trace(sanitize(msg));
182            }
183    
184            @Override
185            public void trace(Object msg, Throwable t) {
186                    if (!isTraceEnabled()) {
187                            return;
188                    }
189    
190                    super.trace(sanitize(msg), sanitize(t));
191            }
192    
193            @Override
194            public void trace(Throwable t) {
195                    if (!isTraceEnabled()) {
196                            return;
197                    }
198    
199                    super.trace(sanitize(t));
200            }
201    
202            @Override
203            public void warn(Object msg) {
204                    if (!isWarnEnabled()) {
205                            return;
206                    }
207    
208                    super.warn(sanitize(msg));
209            }
210    
211            @Override
212            public void warn(Object msg, Throwable t) {
213                    if (!isWarnEnabled()) {
214                            return;
215                    }
216    
217                    super.warn(sanitize(msg), sanitize(t));
218            }
219    
220            @Override
221            public void warn(Throwable t) {
222                    if (!isWarnEnabled()) {
223                            return;
224                    }
225    
226                    super.warn(sanitize(t));
227            }
228    
229            protected String sanitize(Object obj) {
230                    if (obj == null) {
231                            return null;
232                    }
233    
234                    String message = obj.toString();
235    
236                    return sanitize(message, message);
237            }
238    
239            protected String sanitize(String message, String defaultResult) {
240                    if (!_LOG_SANITIZER_ENABLED) {
241                            return message;
242                    }
243    
244                    if (message == null) {
245                            return null;
246                    }
247    
248                    char[] chars = message.toCharArray();
249                    boolean sanitized = false;
250    
251                    for (int i = 0; i < chars.length; i++) {
252                            int c = chars[i];
253    
254                            if ((c >= 0) && (c < _whitelistCharacters.length) &&
255                                    (_whitelistCharacters[c] == 0)) {
256    
257                                    chars[i] = _LOG_SANITIZER_REPLACEMENT_CHARACTER;
258                                    sanitized = true;
259                            }
260                    }
261    
262                    if (sanitized) {
263                            String sanitizedMessage = new String(chars);
264    
265                            sanitizedMessage = sanitizedMessage.concat(_SANITIZED);
266    
267                            if (_LOG_SANITIZER_ESCAPE_HTML_ENABLED) {
268                                    return HtmlUtil.escape(sanitizedMessage);
269                            }
270    
271                            return sanitizedMessage;
272                    }
273    
274                    return defaultResult;
275            }
276    
277            protected Throwable sanitize(Throwable throwable) {
278                    if (!_LOG_SANITIZER_ENABLED) {
279                            return throwable;
280                    }
281    
282                    List<Throwable> throwables = new ArrayList<Throwable>();
283    
284                    Throwable tempThrowable = throwable;
285    
286                    while (tempThrowable != null) {
287                            throwables.add(tempThrowable);
288    
289                            tempThrowable = tempThrowable.getCause();
290                    }
291    
292                    Throwable resultThrowable = null;
293    
294                    boolean sanitized = false;
295    
296                    for (int i = throwables.size() - 1; i > - 1; i--) {
297                            Throwable curThrowable = throwables.get(i);
298    
299                            String message = curThrowable.toString();
300    
301                            String sanitizedMessage = sanitize(message, null);
302    
303                            if (!sanitized && (sanitizedMessage == null)) {
304                                    resultThrowable = curThrowable;
305    
306                                    continue;
307                            }
308    
309                            if (sanitizedMessage == null) {
310                                    sanitizedMessage = message;
311                            }
312    
313                            sanitized = true;
314    
315                            resultThrowable = new LogSanitizerException(
316                                    sanitizedMessage, curThrowable.getStackTrace(),
317                                    resultThrowable);
318                    }
319    
320                    return resultThrowable;
321            }
322    
323            private static final String _SANITIZED = " [Sanitized]";
324    
325            private static boolean _LOG_SANITIZER_ENABLED = false;
326    
327            private static boolean _LOG_SANITIZER_ESCAPE_HTML_ENABLED = false;
328    
329            private static char _LOG_SANITIZER_REPLACEMENT_CHARACTER =
330                    CharPool.UNDERLINE;
331    
332            private static int[] _whitelistCharacters = new int[128];
333    
334    }