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    
070            @Override
071            public void debug(Object msg) {
072                    super.debug(sanitize(msg));
073            }
074    
075            @Override
076            public void debug(Object msg, Throwable t) {
077                    super.debug(sanitize(msg), sanitize(t));
078            }
079    
080            @Override
081            public void debug(Throwable t) {
082                    super.debug(sanitize(t));
083            }
084    
085            @Override
086            public void error(Object msg) {
087                    super.error(sanitize(msg));
088            }
089    
090            @Override
091            public void error(Object msg, Throwable t) {
092                    super.error(sanitize(msg), sanitize(t));
093            }
094    
095            @Override
096            public void error(Throwable t) {
097                    super.error(sanitize(t));
098            }
099    
100            @Override
101            public void fatal(Object msg) {
102                    super.fatal(sanitize(msg));
103            }
104    
105            @Override
106            public void fatal(Object msg, Throwable t) {
107                    super.fatal(sanitize(msg), sanitize(t));
108            }
109    
110            @Override
111            public void fatal(Throwable t) {
112                    super.fatal(sanitize(t));
113            }
114    
115            @Override
116            public void info(Object msg) {
117                    super.info(sanitize(msg));
118            }
119    
120            @Override
121            public void info(Object msg, Throwable t) {
122                    super.info(sanitize(msg), sanitize(t));
123            }
124    
125            @Override
126            public void info(Throwable t) {
127                    super.info(sanitize(t));
128            }
129    
130            @Override
131            public void trace(Object msg) {
132                    super.trace(sanitize(msg));
133            }
134    
135            @Override
136            public void trace(Object msg, Throwable t) {
137                    super.trace(sanitize(msg), sanitize(t));
138            }
139    
140            @Override
141            public void trace(Throwable t) {
142                    super.trace(sanitize(t));
143            }
144    
145            @Override
146            public void warn(Object msg) {
147                    super.warn(sanitize(msg));
148            }
149    
150            @Override
151            public void warn(Object msg, Throwable t) {
152                    super.warn(sanitize(msg), sanitize(t));
153            }
154    
155            @Override
156            public void warn(Throwable t) {
157                    super.warn(sanitize(t));
158            }
159    
160            protected String sanitize(Object obj) {
161                    if (obj == null) {
162                            return null;
163                    }
164    
165                    String message = obj.toString();
166    
167                    return sanitize(message, message);
168            }
169    
170            protected String sanitize(String message, String defaultResult) {
171                    if (message == null) {
172                            return null;
173                    }
174    
175                    char[] chars = message.toCharArray();
176                    boolean sanitized = false;
177    
178                    for (int i = 0; i < chars.length; i++) {
179                            int c = chars[i];
180    
181                            if ((c >= 0) && (c < _whitelistCharacters.length) &&
182                                    (_whitelistCharacters[c] == 0)) {
183    
184                                    chars[i] = _LOG_SANITIZER_REPLACEMENT_CHARACTER;
185                                    sanitized = true;
186                            }
187                    }
188    
189                    if (sanitized) {
190                            String sanitizedMessage = new String(chars);
191    
192                            sanitizedMessage = sanitizedMessage.concat(_SANITIZED);
193    
194                            if (_LOG_SANITIZER_ESCAPE_HTML_ENABLED) {
195                                    return HtmlUtil.escape(sanitizedMessage);
196                            }
197    
198                            return sanitizedMessage;
199                    }
200    
201                    return defaultResult;
202            }
203    
204            protected Throwable sanitize(Throwable throwable) {
205                    List<Throwable> throwables = new ArrayList<Throwable>();
206    
207                    Throwable tempThrowable = throwable;
208    
209                    while (tempThrowable != null) {
210                            throwables.add(tempThrowable);
211    
212                            tempThrowable = tempThrowable.getCause();
213                    }
214    
215                    Throwable resultThrowable = null;
216    
217                    boolean sanitized = false;
218    
219                    for (int i = throwables.size() - 1; i > - 1; i--) {
220                            Throwable curThrowable = throwables.get(i);
221    
222                            String message = curThrowable.toString();
223    
224                            String sanitizedMessage = sanitize(message, null);
225    
226                            if (!sanitized && (sanitizedMessage == null)) {
227                                    resultThrowable = curThrowable;
228    
229                                    continue;
230                            }
231    
232                            if (sanitizedMessage == null) {
233                                    sanitizedMessage = message;
234                            }
235    
236                            sanitized = true;
237    
238                            resultThrowable = new LogSanitizerException(
239                                    sanitizedMessage, curThrowable.getStackTrace(),
240                                    resultThrowable);
241                    }
242    
243                    return resultThrowable;
244            }
245    
246            private static final String _SANITIZED = " [Sanitized]";
247    
248            private static boolean _LOG_SANITIZER_ENABLED = GetterUtil.getBoolean(
249                    SystemProperties.get(PropsKeys.LOG_SANITIZER_ENABLED));
250    
251            private static boolean _LOG_SANITIZER_ESCAPE_HTML_ENABLED = false;
252    
253            private static char _LOG_SANITIZER_REPLACEMENT_CHARACTER =
254                    CharPool.UNDERLINE;
255    
256            private static int[] _whitelistCharacters = new int[128];
257    
258    }