KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > server > security > IPConstraint


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.server.security;
30
31 import com.caucho.config.ConfigException;
32 import com.caucho.log.Log;
33 import com.caucho.util.InetNetwork;
34 import com.caucho.util.L10N;
35 import com.caucho.util.LruCache;
36
37 import javax.annotation.PostConstruct;
38 import javax.servlet.ServletContext JavaDoc;
39 import javax.servlet.ServletException JavaDoc;
40 import javax.servlet.http.HttpServletRequest JavaDoc;
41 import javax.servlet.http.HttpServletResponse JavaDoc;
42 import java.io.IOException JavaDoc;
43 import java.util.ArrayList JavaDoc;
44 import java.util.logging.Logger JavaDoc;
45
46 /**
47  * Allow or deny requests based on the ip address of the client.
48  *
49  * <pre>
50  * &lt;security-constraint&gt;
51  * &lt;ip-constraint&gt;
52  * &lt;allow&gt;192.168.17.0/24&lt;/allow&gt;
53  * &lt;/ip-constraint&gt;
54  *
55  * &lt;web-resource-collection&gt;
56  * &lt;url-pattern&gt;/admin/*&lt;/url-pattern&gt;
57  * &lt;/web-resource-collection&gt;
58  * &lt;/security-constraint&gt;
59  * </pre>
60  *
61  * <pre>
62  * &lt;security-constraint&gt;
63  * &lt;ip-constraint&gt;
64  * &lt;deny&gt;205.11.12.3&lt;/deny&gt;
65  * &lt;deny&gt;213.43.62.45&lt;/deny&gt;
66  * &lt;deny&gt;123.4.45.6&lt;/deny&gt;
67  * &lt;deny&gt;233.15.25.35&lt;/deny&gt;
68  * &lt;deny&gt;233.14.87.12&lt;/deny&gt;
69  * &lt;/ip-constraint&gt;
70  *
71  * &lt;web-resource-collection&gt;
72  * &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
73  * &lt;/web-resource-collection&gt;
74  * &lt;/security-constraint&gt;
75  * </pre>
76  */

77 public class IPConstraint extends AbstractConstraint {
78   /** updated 2004-11-19 Sam to accept <allow> and <deny> */
79
80   static final Logger JavaDoc log = Log.open(IPConstraint.class);
81   static L10N L = new L10N(IPConstraint.class);
82
83   private ArrayList JavaDoc<InetNetwork> _allowNetworkList;
84   private ArrayList JavaDoc<InetNetwork> _denyNetworkList;
85
86   private int _cacheSize = 256;
87   private int _errorCode = HttpServletResponse.SC_FORBIDDEN;
88   private String JavaDoc _errorMessage = L.l("Forbidden IP Address");
89
90   private LruCache<String JavaDoc,Boolean JavaDoc> _cache;
91
92   /** see method SecurityConstraint.addIPConstraint() for explanation */
93   private boolean _oldStyle = false;
94
95   public IPConstraint()
96   {
97   }
98
99   /**
100    * The error code to send with response.sendError, default is 403.
101    */

102   public void setErrorCode(int errorCode)
103   {
104     _errorCode = errorCode;
105   }
106
107   /**
108    * The error code to send with response.sendError, default is 403.
109    */

110   public int getErrorCode()
111   {
112     return _errorCode;
113   }
114
115   /**
116    * The error message to send with response.sendError, default is
117    * "Forbidden IP Address"
118    */

119   public void setErrorMessage(String JavaDoc errorMessage)
120   {
121     _errorMessage = errorMessage;
122   }
123
124   /**
125    * The error message to send with response.sendError, default is
126    * "Forbidden IP Address"
127    */

128   public String JavaDoc getErrorMessage()
129   {
130     return _errorMessage;
131   }
132
133   /**
134    * Size of the cache used to hold whether or not to allow a certain IP
135    * address, default is 256. The first time a request is received from an ip,
136    * the allow and deny rules are checked to determine if the ip is allowed.
137    * The result of this check is cached in a an LRU cache. Subsequent requests
138    * can do a cache lookup based on the ip instead of checking the rules. This
139    * is especially important if there are a large number of allow and/or deny
140    * rules, and to protect against denial of service attacks.
141    */

142   public void setCacheSize(int cacheSize)
143   {
144     _cacheSize = cacheSize;
145   }
146
147   /**
148    * Size of the cache used to hold whether or not to allow a certain IP
149    * address.
150    */

151   public int getCacheSize()
152   {
153     return _cacheSize;
154   }
155
156   /**
157    * Add an ip network to allow. If allow is never used, (only deny is used),
158    * then all are allowed except those in deny.
159    */

160   public void addAllow(String JavaDoc network)
161   {
162     if (_allowNetworkList == null)
163       _allowNetworkList = new ArrayList JavaDoc<InetNetwork>();
164
165     _allowNetworkList.add(InetNetwork.create(network));
166   }
167
168   /**
169    * Add an ip network to deny.
170    */

171   public void addDeny(String JavaDoc network)
172   {
173     if (_denyNetworkList == null)
174       _denyNetworkList = new ArrayList JavaDoc<InetNetwork>();
175
176     _denyNetworkList.add(InetNetwork.create(network));
177   }
178
179   /** backwards compatibility, same as addAllow() */
180   public void addText(String JavaDoc network)
181   {
182     _oldStyle = true;
183     addAllow(network);
184   }
185
186   /** backwards compatibility, used by SecurityConstraint.addIPConstraint() */
187   boolean isOldStyle()
188   {
189     return _oldStyle;
190   }
191
192   /** backwards compatibility, used by SecurityConstraint.addIPConstraint() */
193   void copyInto(IPConstraint target)
194   {
195     if (_allowNetworkList != null) {
196       for (int i = 0; i < _allowNetworkList.size(); i++) {
197         target.addAllowInetNetwork(_allowNetworkList.get(i));
198       }
199     }
200     if (_denyNetworkList != null) {
201       for (int i = 0; i < _denyNetworkList.size(); i++) {
202         target.addDenyInetNetwork(_denyNetworkList.get(i));
203       }
204     }
205   }
206
207   private void addAllowInetNetwork(InetNetwork a)
208   {
209     if (_allowNetworkList == null)
210       _allowNetworkList = new ArrayList JavaDoc<InetNetwork>();
211     _allowNetworkList.add(a);
212   }
213
214   private void addDenyInetNetwork(InetNetwork d)
215   {
216     if (_denyNetworkList == null)
217       _denyNetworkList = new ArrayList JavaDoc<InetNetwork>();
218     _denyNetworkList.add(d);
219   }
220
221   @PostConstruct
222   public void init()
223     throws ConfigException
224   {
225     if (_allowNetworkList == null && _denyNetworkList == null)
226       throw new ConfigException(L.l("either `{0}' or `{1}' or both are expected", "<allow>", "<deny>"));
227
228     if (_allowNetworkList != null)
229       _allowNetworkList.trimToSize();
230
231     if (_denyNetworkList != null)
232       _denyNetworkList.trimToSize();
233
234     int rules = _allowNetworkList == null ? 0 : _allowNetworkList.size();
235     rules += _denyNetworkList == null ? 0 : _denyNetworkList.size();
236
237     _cache = new LruCache<String JavaDoc,Boolean JavaDoc>(_cacheSize);
238   }
239
240   /**
241    * Returns true if the user is authorized for the resource.
242    */

243   public boolean isAuthorized(HttpServletRequest JavaDoc request,
244                               HttpServletResponse JavaDoc response,
245                               ServletContext JavaDoc application)
246     throws ServletException JavaDoc, IOException JavaDoc
247   {
248     String JavaDoc remoteAddr = request.getRemoteAddr();
249     long addr = 0;
250     boolean allow = false;
251
252     if (remoteAddr != null) {
253       if (_cache != null) {
254         Boolean JavaDoc cacheValue = _cache.get(remoteAddr);
255         if (cacheValue != null) {
256           allow = cacheValue.booleanValue();
257
258           if (!allow)
259             response.sendError(_errorCode, _errorMessage);
260
261           return allow;
262         }
263       }
264
265       int len = remoteAddr.length();
266       int ch;
267       int i = 0;
268
269       while (i < len && (ch = remoteAddr.charAt(i)) >= '0' && ch <= '9') {
270         int digit = 0;
271     
272         for (; i < len && (ch = remoteAddr.charAt(i)) >= '0' && ch <= '9'; i++)
273           digit = 10 * digit + ch - '0';
274
275         addr = 256 * addr + digit;
276
277         if (ch == '.')
278           i++;
279       }
280     }
281
282     // check allow
283

284     if (_allowNetworkList == null) {
285       // if no allow specified, then allow all
286
allow = true;
287     }
288     else {
289       for (int i = 0; i < _allowNetworkList.size(); i++) {
290         InetNetwork net = _allowNetworkList.get(i);
291
292         if (net.isMatch(addr)) {
293           allow = true;
294           break;
295         }
296       }
297     }
298
299     // check deny
300

301     if (allow && _denyNetworkList != null) {
302       for (int i = 0; i < _denyNetworkList.size(); i++) {
303         InetNetwork net = _denyNetworkList.get(i);
304
305         if (net.isMatch(addr)) {
306           allow = false;
307           break;
308         }
309       }
310     }
311
312     // update cache
313

314     if (_cache != null)
315       _cache.put(remoteAddr, allow ? Boolean.TRUE : Boolean.FALSE);
316
317     // respond accordingly
318

319     if (!allow)
320       response.sendError(_errorCode, _errorMessage);
321
322     return allow;
323
324   }
325
326 }
327
Popular Tags