IPAccessHandler
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@1279 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
0b522aee32
commit
22adee9473
|
@ -0,0 +1,31 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||||
|
|
||||||
|
<!-- =============================================================== -->
|
||||||
|
<!-- Mixin the Statistics Handler -->
|
||||||
|
<!-- =============================================================== -->
|
||||||
|
|
||||||
|
|
||||||
|
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||||
|
|
||||||
|
<Get id="oldhandler" name="handler"/>
|
||||||
|
|
||||||
|
<Set name="handler">
|
||||||
|
<New id="IPAccessHandler" class="org.eclipse.jetty.server.handler.IPAccessHandler">
|
||||||
|
<Set name="handler"><Ref id="oldhandler"/></Set>
|
||||||
|
<Set name="white">
|
||||||
|
<Array type="String">
|
||||||
|
<Item>127.0.0.1</Item>
|
||||||
|
<Item>127.0.0.2/*.html</Item>
|
||||||
|
</Array>
|
||||||
|
</Set>
|
||||||
|
<Set name="black">
|
||||||
|
<Array type="String">
|
||||||
|
<Item>127.0.0.1/blacklisted</Item>
|
||||||
|
<Item>127.0.0.2/black.html</Item>
|
||||||
|
</Array>
|
||||||
|
</Set>
|
||||||
|
</New>
|
||||||
|
</Set>
|
||||||
|
|
||||||
|
</Configure>
|
|
@ -0,0 +1,201 @@
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 2010 Mort Bay Consulting Pty. Ltd.
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// All rights reserved. This program and the accompanying materials
|
||||||
|
// are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
// and Apache License v2.0 which accompanies this distribution.
|
||||||
|
// The Eclipse Public License is available at
|
||||||
|
// http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
// The Apache License v2.0 is available at
|
||||||
|
// http://www.opensource.org/licenses/apache2.0.php
|
||||||
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
|
// ========================================================================
|
||||||
|
|
||||||
|
package org.eclipse.jetty.server.handler;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.http.HttpStatus;
|
||||||
|
import org.eclipse.jetty.http.PathMap;
|
||||||
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
|
import org.eclipse.jetty.server.HttpConnection;
|
||||||
|
import org.eclipse.jetty.server.Request;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IP Access Handler
|
||||||
|
* <p>
|
||||||
|
* Control access to the wrapped handler by the real remote IP.
|
||||||
|
* The real IP of the connection is used (not the IP reported in the forwarded for headers),
|
||||||
|
* as this cannot be as easily forged.
|
||||||
|
* <p>
|
||||||
|
* Control is provided by white/black lists of both internet addresses and URIs.
|
||||||
|
* Internet addresses may be absolute (eg 10.1.2.3) or a prefix pattern (eg 10.1.3. ).
|
||||||
|
* URI patterns follow the servlet specification for simple prefix and suffix wild cards.
|
||||||
|
* <p>
|
||||||
|
* An empty white list is treated as match all. If there is at least one entry in the
|
||||||
|
* white list, then a request must match a white list entry. Black list entries are always
|
||||||
|
* appied, so that even if an entry matches the white list, a black list entry will override.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Examples of match specifications are:
|
||||||
|
* <ul>
|
||||||
|
* <li>10.1.2.3 - all requests from IP 10.1.2.3
|
||||||
|
* <li>10.1.2.3/foo/bar - all requests from IP 10.1.2.3 to URI /foo/bar
|
||||||
|
* <li>10.1.2.3/foo/* - all requests from IP 10.1.2.3 to URIs starting with /foo/
|
||||||
|
* <li>10.1.2.3/*.html - all requests from IP 10.1.2.3 to URIs ending with .html
|
||||||
|
* <li>10.1. - all requests from IPs starting with 10.1.
|
||||||
|
* <li>10.1./foo/bar - all requests from IPs starting with 10.1. to URI /foo/bar
|
||||||
|
* <li>10.1./foo/* - all requests from IPs starting with 10.1. to URIs starting with /foo/
|
||||||
|
* </ul>
|
||||||
|
* <p>
|
||||||
|
* Typically, the black/white lists will be used in one of three modes:
|
||||||
|
* <nl>
|
||||||
|
* <li>Blocking a few specific IPs/URLs by specifying several black list entries.
|
||||||
|
* <li>Allowing only some specific IPs/URLs by specifying several white lists entries.
|
||||||
|
* <li>Allowing a general range of IPs/URLs by specifying serveral general white list
|
||||||
|
* entries, that are then further refined by several specific black list exceptions
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class IPAccessHandler extends HandlerWrapper
|
||||||
|
{
|
||||||
|
Map<String,PathMap> _whiteAddr = new HashMap<String, PathMap>();
|
||||||
|
List<String> _whitePattern = new CopyOnWriteArrayList<String>();
|
||||||
|
Map<String,PathMap> _blackAddr = new HashMap<String, PathMap>();
|
||||||
|
List<String> _blackPattern = new CopyOnWriteArrayList<String>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public IPAccessHandler()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addBlack(String addrPath)
|
||||||
|
{
|
||||||
|
add(addrPath, _blackAddr, _blackPattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addWhite(String addrPath)
|
||||||
|
{
|
||||||
|
add(addrPath, _whiteAddr, _whitePattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBlack(String[] addrPaths)
|
||||||
|
{
|
||||||
|
set(addrPaths, _blackAddr, _blackPattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWhite(String[] addrPaths)
|
||||||
|
{
|
||||||
|
set(addrPaths, _whiteAddr, _whitePattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||||
|
{
|
||||||
|
// Get the real remote IP (not the one set by the forwarded headers (which may be forged))
|
||||||
|
HttpConnection connection = baseRequest.getConnection();
|
||||||
|
if (connection!=null)
|
||||||
|
{
|
||||||
|
EndPoint endp=connection.getEndPoint();
|
||||||
|
if (endp!=null)
|
||||||
|
{
|
||||||
|
String addr = endp.getRemoteAddr();
|
||||||
|
if (addr!=null && !isAddrUriAllowed(addr,baseRequest.getPathInfo()))
|
||||||
|
{
|
||||||
|
response.sendError(HttpStatus.FORBIDDEN_403);
|
||||||
|
baseRequest.setHandled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getHandler().handle(target,baseRequest, request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void add(String addrPath, Map<String,PathMap> addrMap, List<String> patternList)
|
||||||
|
{
|
||||||
|
int idx = addrPath.indexOf('/');
|
||||||
|
String addr = idx > 0 ? addrPath.substring(0,idx) : addrPath;
|
||||||
|
String path = idx > 0 ? addrPath.substring(idx) : null;
|
||||||
|
if (path!=null && path.length()>1 && path.charAt(1)=='*')
|
||||||
|
path=path.substring(1);
|
||||||
|
System.err.println("addr="+addr+" path="+path);
|
||||||
|
|
||||||
|
PathMap map = addrMap.get(addr);
|
||||||
|
if (map==null)
|
||||||
|
{
|
||||||
|
map = new PathMap(true);
|
||||||
|
addrMap.put(addr,map);
|
||||||
|
if (addr.endsWith("."))
|
||||||
|
patternList.add(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path != null)
|
||||||
|
map.put(path,path);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void set(String[] addrPaths, Map<String,PathMap> addrMap, List<String> patternList)
|
||||||
|
{
|
||||||
|
addrMap.clear();
|
||||||
|
patternList.clear();
|
||||||
|
for (String addrPath:addrPaths)
|
||||||
|
add(addrPath, addrMap, patternList);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isAddrUriAllowed(String addr, String path)
|
||||||
|
{
|
||||||
|
if (_whiteAddr.size()>0)
|
||||||
|
{
|
||||||
|
PathMap white=_whiteAddr.get(addr);
|
||||||
|
|
||||||
|
if (white==null || (white.size()>0 && white.match(path)==null))
|
||||||
|
{
|
||||||
|
boolean match=false;
|
||||||
|
for (String pattern:_whitePattern)
|
||||||
|
{
|
||||||
|
if (addr.startsWith(pattern))
|
||||||
|
{
|
||||||
|
white=_whiteAddr.get(pattern);
|
||||||
|
if (white!=null && white.size()>0 && white.match(path)!=null)
|
||||||
|
{
|
||||||
|
match=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!match)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PathMap black=_blackAddr.get(addr);
|
||||||
|
if (black!=null && (black.size()==0 || black.match(path)!=null))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (String pattern:_blackPattern)
|
||||||
|
{
|
||||||
|
if (addr.startsWith(pattern))
|
||||||
|
{
|
||||||
|
black=_blackAddr.get(pattern);
|
||||||
|
if (black!=null && black.match(path)!=null)
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue