001
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.PropsKeys;
020 import com.liferay.portal.kernel.util.StringPool;
021 import com.liferay.portal.kernel.util.SystemProperties;
022
023 import java.util.ArrayList;
024 import java.util.List;
025
026
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 for (int i = 0; i < _whitelistCharacters.length; i++) {
045 _whitelistCharacters[i] = 1;
046 }
047
048 int[] whitelistCharacters = GetterUtil.getIntegerValues(
049 SystemProperties.getArray(
050 PropsKeys.LOG_SANITIZER_WHITELIST_CHARACTERS));
051
052 for (int whitelistCharacter : whitelistCharacters) {
053 if ((whitelistCharacter >= 0) &&
054 (whitelistCharacter < _whitelistCharacters.length)) {
055
056 _whitelistCharacters[whitelistCharacter] = 0;
057 }
058 else {
059 System.err.println(
060 "Unable to register log whitelist character " +
061 whitelistCharacter);
062 }
063 }
064 }
065
066 public static boolean isEnabled() {
067 return _LOG_SANITIZER_ENABLED;
068 }
069
070 public SanitizerLogWrapper(Log log) {
071 super(log);
072
073 setLogWrapperClassName(SanitizerLogWrapper.class.getName());
074 }
075
076 @Override
077 public void debug(Object msg) {
078 super.debug(sanitize(msg));
079 }
080
081 @Override
082 public void debug(Object msg, Throwable t) {
083 super.debug(sanitize(msg), sanitize(t));
084 }
085
086 @Override
087 public void debug(Throwable t) {
088 super.debug(sanitize(t));
089 }
090
091 @Override
092 public void error(Object msg) {
093 super.error(sanitize(msg));
094 }
095
096 @Override
097 public void error(Object msg, Throwable t) {
098 super.error(sanitize(msg), sanitize(t));
099 }
100
101 @Override
102 public void error(Throwable t) {
103 super.error(sanitize(t));
104 }
105
106 @Override
107 public void fatal(Object msg) {
108 super.fatal(sanitize(msg));
109 }
110
111 @Override
112 public void fatal(Object msg, Throwable t) {
113 super.fatal(sanitize(msg), sanitize(t));
114 }
115
116 @Override
117 public void fatal(Throwable t) {
118 super.fatal(sanitize(t));
119 }
120
121 @Override
122 public void info(Object msg) {
123 super.info(sanitize(msg));
124 }
125
126 @Override
127 public void info(Object msg, Throwable t) {
128 super.info(sanitize(msg), sanitize(t));
129 }
130
131 @Override
132 public void info(Throwable t) {
133 super.info(sanitize(t));
134 }
135
136 @Override
137 public void trace(Object msg) {
138 super.trace(sanitize(msg));
139 }
140
141 @Override
142 public void trace(Object msg, Throwable t) {
143 super.trace(sanitize(msg), sanitize(t));
144 }
145
146 @Override
147 public void trace(Throwable t) {
148 super.trace(sanitize(t));
149 }
150
151 @Override
152 public void warn(Object msg) {
153 super.warn(sanitize(msg));
154 }
155
156 @Override
157 public void warn(Object msg, Throwable t) {
158 super.warn(sanitize(msg), sanitize(t));
159 }
160
161 @Override
162 public void warn(Throwable t) {
163 super.warn(sanitize(t));
164 }
165
166 protected String sanitize(Object obj) {
167 if (obj == null) {
168 return null;
169 }
170
171 String message = obj.toString();
172
173 return sanitize(message, message);
174 }
175
176 protected String sanitize(String message, String defaultResult) {
177 if (message == null) {
178 return null;
179 }
180
181 char[] chars = message.toCharArray();
182 boolean hasLessThanCharacter = false;
183 boolean sanitized = false;
184
185 for (int i = 0; i < chars.length; i++) {
186 int c = chars[i];
187
188 if ((c >= 0) && (c < _whitelistCharacters.length) &&
189 (_whitelistCharacters[c] != 0)) {
190
191 chars[i] = _LOG_SANITIZER_REPLACEMENT_CHARACTER;
192 sanitized = true;
193 }
194
195 if (c == CharPool.LESS_THAN) {
196 hasLessThanCharacter = true;
197 }
198 }
199
200 boolean escapeHTML = false;
201
202 if (_LOG_SANITIZER_ESCAPE_HTML_ENABLED && hasLessThanCharacter) {
203 escapeHTML = true;
204 }
205
206 if (sanitized || escapeHTML) {
207 String sanitizedMessage = new String(chars);
208
209 if (escapeHTML) {
210 sanitizedMessage = sanitizedMessage.replaceAll(
211 StringPool.LESS_THAN, _LESS_THAN_ESCAPED);
212 }
213
214 sanitizedMessage = sanitizedMessage.concat(_SANITIZED);
215
216 return sanitizedMessage;
217 }
218
219 return defaultResult;
220 }
221
222 protected Throwable sanitize(Throwable throwable) {
223 List<Throwable> throwables = new ArrayList<Throwable>();
224
225 Throwable tempThrowable = throwable;
226
227 while (tempThrowable != null) {
228 throwables.add(tempThrowable);
229
230 tempThrowable = tempThrowable.getCause();
231 }
232
233 Throwable resultThrowable = null;
234
235 boolean sanitized = false;
236
237 for (int i = throwables.size() - 1; i > - 1; i--) {
238 Throwable curThrowable = throwables.get(i);
239
240 String message = curThrowable.toString();
241
242 String sanitizedMessage = sanitize(message, null);
243
244 if (!sanitized && (sanitizedMessage == null)) {
245 resultThrowable = curThrowable;
246
247 continue;
248 }
249
250 if (sanitizedMessage == null) {
251 sanitizedMessage = message;
252 }
253
254 sanitized = true;
255
256 resultThrowable = new LogSanitizerException(
257 sanitizedMessage, curThrowable.getStackTrace(),
258 resultThrowable);
259 }
260
261 return resultThrowable;
262 }
263
264 private static final String _LESS_THAN_ESCAPED = "<";
265
266 private static final String _SANITIZED = " [Sanitized]";
267
268 private static boolean _LOG_SANITIZER_ENABLED = GetterUtil.getBoolean(
269 SystemProperties.get(PropsKeys.LOG_SANITIZER_ENABLED));
270
271 private static boolean _LOG_SANITIZER_ESCAPE_HTML_ENABLED = false;
272
273 private static char _LOG_SANITIZER_REPLACEMENT_CHARACTER =
274 CharPool.UNDERLINE;
275
276 private static int[] _whitelistCharacters = new int[128];
277
278 }