KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > google > gwt > dev > shell > BrowserWidgetHostChecker


1 /*
2  * Copyright 2006 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */

16 package com.google.gwt.dev.shell;
17
18 import com.google.gwt.core.ext.TreeLogger;
19
20 import java.util.HashSet JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.Set JavaDoc;
23 import java.util.regex.Pattern JavaDoc;
24 import java.util.regex.PatternSyntaxException JavaDoc;
25
26 /**
27  * This class contains utility functions to do whitelist/blacklist handling.
28  */

29 public class BrowserWidgetHostChecker {
30
31   /**
32    * The set of always allowed URLs, which are immune to blacklisting.
33    */

34   private static final Set JavaDoc alwaysValidHttpHosts = new HashSet JavaDoc();
35
36   /**
37    * The set of blacklisted URLs.
38    */

39   private static final Set JavaDoc invalidHttpHosts = new HashSet JavaDoc();
40
41   private static String JavaDoc oldBlackList = null;
42
43   private static String JavaDoc oldWhiteList = null;
44
45   /**
46    * The set of whitelisted URLs.
47    */

48   private static final Set JavaDoc validHttpHosts = new HashSet JavaDoc();
49
50   static {
51     alwaysValidHttpHosts.add("^https?://localhost");
52     alwaysValidHttpHosts.add("^file:");
53     alwaysValidHttpHosts.add("^about:");
54     alwaysValidHttpHosts.add("^res:");
55     alwaysValidHttpHosts.add("^javascript:");
56     alwaysValidHttpHosts.add("^([a-zA-Z][:])[/\\\\]");
57     // matches c:\ and c:/
58
alwaysValidHttpHosts.add("^https?://localhost/");
59     alwaysValidHttpHosts.add("^https?://localhost[.]localdomain/");
60     alwaysValidHttpHosts.add("^https?://127[.]0[.]0[.]1/");
61     alwaysValidHttpHosts.add("^https?://localhost$");
62     alwaysValidHttpHosts.add("^https?://localhost[.]localdomain$");
63     alwaysValidHttpHosts.add("^https?://127[.]0[.]0[.]1$");
64   }
65
66   /**
67    * This method blacklists the supplied regexes, separated by comma or space.
68    *
69    * @param regexes the regexes to be forbidden
70    */

71   public static boolean blacklistRegexes(String JavaDoc regexes) {
72     return addRegex(regexes, false);
73   }
74
75   /**
76    * This method blacklists the supplied URL, and any that share the same host.
77    *
78    * @param url the host to be forbidden
79    */

80   public static void blacklistURL(String JavaDoc url) {
81     String JavaDoc hostRegex = computeHostRegex(url);
82     blacklistRegexes(hostRegex);
83   }
84
85   /**
86    * This method checks the host to see if it is in the supplied set of regexes.
87    *
88    * @param hostUnderConsideration the host to be checked
89    * @param hosts the set of regexes to be checked against
90    * @return true if the host matches
91    */

92   public static String JavaDoc checkHost(String JavaDoc hostUnderConsideration, Set JavaDoc hosts) {
93     hostUnderConsideration = hostUnderConsideration.toLowerCase();
94     for (Iterator JavaDoc i = hosts.iterator(); i.hasNext();) {
95       String JavaDoc rule = i.next().toString().toLowerCase();
96       // match on lowercased regex
97
if (hostUnderConsideration.matches(".*" + rule + ".*")) {
98         return rule;
99       }
100     }
101     return null;
102   }
103
104   /**
105    * This method computes the host regular expression for the given url.
106    *
107    * @param url the url to be allowed or disallowed
108    * @return the regex that matches the host in the url
109    */

110   public static String JavaDoc computeHostRegex(String JavaDoc url) {
111     // the entire URL up to the first slash not prefixed by a slash or colon.
112
String JavaDoc raw = url.split("(?<![:/])/")[0];
113     // escape the dots and put a begin line specifier on the result
114
return "^" + escapeString(raw);
115   }
116
117   /**
118    * This method formats the blacklist for display in the treeLogger.
119    *
120    * @return the list of regexes as a String
121    */

122   public static String JavaDoc formatBlackList() {
123     return formatRules(invalidHttpHosts);
124   }
125
126   /**
127    * This method formats the list of rules for display in the treeLogger.
128    *
129    * @param hosts the set of regexes that match hosts
130    * @return the list of regexes as a String
131    */

132   public static String JavaDoc formatRules(Set JavaDoc hosts) {
133     StringBuffer JavaDoc out = new StringBuffer JavaDoc();
134     for (Iterator JavaDoc i = hosts.iterator(); i.hasNext();) {
135       String JavaDoc rule = (String JavaDoc) i.next();
136       out.append(rule);
137       out.append(" ");
138     }
139     return out.toString();
140   }
141
142   /**
143    * This method formats the whitelist for display in the treeLogger.
144    *
145    * @return the list of regexes as a String
146    */

147   public static String JavaDoc formatWhiteList() {
148     return formatRules(validHttpHosts);
149   }
150
151   /**
152    * This method returns true if the host is always admissable, regardless of
153    * the blacklist.
154    *
155    * @param url the URL to be verified
156    * @return returns true if the host is always admissable
157    */

158   public static boolean isAlwaysWhitelisted(String JavaDoc url) {
159     String JavaDoc whitelistRuleFound;
160     whitelistRuleFound = checkHost(url, alwaysValidHttpHosts);
161     return whitelistRuleFound != null;
162   }
163
164   /**
165    * This method returns true if the host is forbidden.
166    *
167    * @param url the URL to be verified
168    * @return returns the regex that specified the host matches the blacklist
169    */

170   public static String JavaDoc matchBlacklisted(String JavaDoc url) {
171     oldBlackList = formatBlackList();
172     return checkHost(url, invalidHttpHosts);
173   }
174
175   /**
176    * This method returns true if the host is admissable, provided it is not on
177    * the blacklist.
178    *
179    * @param url the URL to be verified
180    * @return returns the regex that specified the host matches the whitelist
181    */

182   public static String JavaDoc matchWhitelisted(String JavaDoc url) {
183     oldWhiteList = formatWhiteList();
184     return checkHost(url, validHttpHosts);
185   }
186
187   /**
188    * This method formats a message, and logs it to the treelogger, stating that
189    * the url was blocked.
190    *
191    * @param url the URL that was disallowed
192    * @param header the treelogger under which these messages will be put
193    * @param msgType either a caution or an error
194    */

195   public static void notifyBlacklistedHost(String JavaDoc blacklistRuleFound,
196       String JavaDoc url, TreeLogger header, TreeLogger.Type msgType) {
197     TreeLogger reason = header.branch(msgType, "reason: " + url
198         + " is blacklisted", null);
199     reason.log(msgType, "To fix: remove \"" + blacklistRuleFound
200         + "\" from system property gwt.hosts.blacklist", null);
201   }
202
203   /**
204    * This method formats a message, and logs it to the treelogger, stating that
205    * the url was not trusted.
206    *
207    * @param url the URL that provoked the dialog box
208    * @param header the treelogger under which these messages will be put
209    * @param msgType either a caution or an error
210    */

211   public static void notifyUntrustedHost(String JavaDoc url, TreeLogger header,
212       TreeLogger.Type msgType) {
213     String JavaDoc whiteListStr = oldWhiteList;
214     String JavaDoc blackListStr = oldBlackList;
215     String JavaDoc hostRegex = computeHostRegex(url);
216     TreeLogger reason = header.branch(msgType, "reason: " + url
217         + " is not in the whitelist", null);
218     reason.log(msgType, "whitelist: " + whiteListStr, null);
219     reason.log(msgType, "blacklist: " + blackListStr, null);
220     TreeLogger fix = header.branch(msgType, "To fix: add regex matching "
221         + "URL to -whitelist command line argument", null);
222     fix.log(msgType, "Example: -whitelist=\"" + whiteListStr + " " + hostRegex
223         + "\"", null);
224     TreeLogger reject = header.branch(msgType,
225         "To reject automatically: add regex matching "
226             + "URL to -blacklist command line argument", null);
227     reject.log(msgType, "Example: -blacklist=\"" + blackListStr + " "
228         + hostRegex + "\"", null);
229   }
230
231   /**
232    * This method whitelists the supplied String of regexes, separated by comma
233    * or space.
234    *
235    * @param regexes the regexes to be allowed
236    */

237   public static boolean whitelistRegexes(String JavaDoc regexes) {
238     return addRegex(regexes, true);
239   }
240
241   /**
242    * This method whitelists the supplied URL, and any that share the same host.
243    *
244    * @param url the host to be allowed
245    */

246   public static void whitelistURL(String JavaDoc url) {
247     String JavaDoc hostRegex = computeHostRegex(url);
248     whitelistRegexes(hostRegex);
249   }
250
251   /**
252    * This method blacklists or whitelists the supplied regexes, and any that
253    * share the same host.
254    *
255    * @param whitelist if <code>true</code> the host will be whitelisted
256    * @param regexes the regular expressions to be forbidden, seperated by comma
257    * or space
258    */

259   private static boolean addRegex(String JavaDoc regexes, boolean whitelist) {
260     if (regexes.equals("")) {
261       return true; // adding empty string is harmless and happens by default
262
}
263     String JavaDoc[] items = regexes.split("[ ,]");
264     for (int i = 0; i < items.length; i++) {
265       try {
266         Pattern.compile(items[i]);
267       } catch (PatternSyntaxException JavaDoc e) {
268         System.err.println("The regex '" + items[i] + " has syntax errors.");
269         System.err.println(e.toString());
270         return false;
271       }
272       if (whitelist) {
273         validHttpHosts.add(items[i]);
274       } else {
275         invalidHttpHosts.add(items[i]);
276       }
277     }
278     return true;
279   }
280
281   private static String JavaDoc escapeString(String JavaDoc raw) {
282     StringBuffer JavaDoc out = new StringBuffer JavaDoc();
283     for (int i = 0; i < raw.length(); i++) {
284       char c = raw.charAt(i);
285       if (Character.isLetterOrDigit(c) || c == '-' || c == '_') {
286         out.append(c);
287       } else if (c == '\\') {
288         out.append("[\\\\]");
289       } else if (c == ']') {
290         out.append("[\\]]");
291       } else if (c == '^') {
292         out.append("[\\^]");
293       } else if (c == '[') {
294         out.append("[\\[]");
295       } else {
296         out.append("[");
297         out.append(c);
298         out.append("]");
299       }
300     }
301     return out.toString();
302   }
303
304 }
305
Popular Tags