From f06cef5d5b01519aa2bfc6b766d84076f97961e2 Mon Sep 17 00:00:00 2001 From: reger Date: Mon, 6 Jan 2014 15:00:14 +0100 Subject: [PATCH] reimplement proxy access by configured whitlist pattern was currently limited to own ip. --- .../net/yacy/http/AbstractRemoteHandler.java | 29 ++++++++++++++--- source/net/yacy/http/ProxyHandler.java | 11 ++++--- .../yacy/http/servlets/YaCyProxyServlet.java | 31 +++++++++++++++++-- 3 files changed, 59 insertions(+), 12 deletions(-) diff --git a/source/net/yacy/http/AbstractRemoteHandler.java b/source/net/yacy/http/AbstractRemoteHandler.java index f7a8ad6c0..129db93e2 100644 --- a/source/net/yacy/http/AbstractRemoteHandler.java +++ b/source/net/yacy/http/AbstractRemoteHandler.java @@ -28,6 +28,7 @@ import java.io.IOException; import java.net.InetAddress; import java.util.LinkedList; import java.util.List; +import java.util.StringTokenizer; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -111,11 +112,11 @@ abstract public class AbstractRemoteHandler extends AbstractHandler implements H return; } - String remoteHost = request.getRemoteHost(); - if (!Domains.isThisHostIP(remoteHost)) { // isThisHostIP checks resolves & isAnyLocal & isLoopback IP - // TODO: handle proxy account ~ ? use proxyClient config instead fix of localIP? + final String remoteHost = request.getRemoteHost(); + if (!proxyippatternmatch(remoteHost)) { + // TODO: handle proxy account response.sendError(HttpServletResponse.SC_FORBIDDEN, - "proxy use not granted for IP " + request.getRemoteAddr() + " (see Server Proxy Access settings)."); + "proxy use not granted for IP " + remoteHost + " (see Server Proxy Access settings)."); baseRequest.setHandled(true); return; } @@ -124,4 +125,24 @@ abstract public class AbstractRemoteHandler extends AbstractHandler implements H } + /** + * helper for proxy IP config pattern check + */ + private boolean proxyippatternmatch(final String key) { + // the cfgippattern is a comma-separated list of patterns + // each pattern may contain one wildcard-character '*' which matches anything + final String cfgippattern = Switchboard.getSwitchboard().getConfig("proxyClient", "*"); + if (cfgippattern.equals("*")) { + return true; + } + final StringTokenizer st = new StringTokenizer(cfgippattern, ","); + String pattern; + while (st.hasMoreTokens()) { + pattern = st.nextToken(); + if (key.matches(pattern)) { + return true; + } + } + return false; + } } diff --git a/source/net/yacy/http/ProxyHandler.java b/source/net/yacy/http/ProxyHandler.java index 35e4e92da..64e0c8275 100644 --- a/source/net/yacy/http/ProxyHandler.java +++ b/source/net/yacy/http/ProxyHandler.java @@ -45,6 +45,7 @@ import net.yacy.cora.protocol.HeaderFramework; import net.yacy.cora.protocol.RequestHeader; import net.yacy.cora.protocol.ResponseHeader; import net.yacy.cora.protocol.http.HTTPClient; +import net.yacy.cora.util.ConcurrentLog; import net.yacy.document.TextParser; import net.yacy.crawler.data.Cache; import net.yacy.crawler.retrieval.Response; @@ -61,7 +62,7 @@ import org.eclipse.jetty.util.IO; * proxies request, caches responses and adds urls to crawler */ public class ProxyHandler extends AbstractRemoteHandler implements Handler { - + public static RequestHeader convertHeaderFromJetty(HttpServletRequest request) { RequestHeader result = new RequestHeader(); Enumeration headerNames = request.getHeaderNames(); @@ -91,7 +92,7 @@ public class ProxyHandler extends AbstractRemoteHandler implements Handler { public void handleRemote(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - if (request.getMethod().equals(HeaderFramework.METHOD_CONNECT)) { + if (request.getMethod().equalsIgnoreCase(HeaderFramework.METHOD_CONNECT)) { handleConnect(request, response); return; } @@ -100,7 +101,7 @@ public class ProxyHandler extends AbstractRemoteHandler implements Handler { setProxyHeaderForClient(request, proxyHeaders); final HTTPClient client = new HTTPClient(ClientIdentification.yacyProxyAgent); - int timeout = 60000; + int timeout = 10000; client.setTimout(timeout); client.setHeader(proxyHeaders.entrySet()); client.setRedirecting(false); @@ -313,7 +314,7 @@ public class ProxyHandler extends AbstractRemoteHandler implements Handler { host = uri.substring(0, c); if (host.indexOf('/') > 0) { host = host.substring(host.indexOf('/') + 1); - } +} } // TODO - make this async! @@ -338,5 +339,5 @@ public class ProxyHandler extends AbstractRemoteHandler implements Handler { IO.copyThread(socket.getInputStream(), out); IO.copy(in, socket.getOutputStream()); } - } + } } diff --git a/source/net/yacy/http/servlets/YaCyProxyServlet.java b/source/net/yacy/http/servlets/YaCyProxyServlet.java index a98eb7f6c..364eee926 100644 --- a/source/net/yacy/http/servlets/YaCyProxyServlet.java +++ b/source/net/yacy/http/servlets/YaCyProxyServlet.java @@ -9,6 +9,7 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLDecoder; import java.util.HashMap; +import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -80,10 +81,14 @@ public class YaCyProxyServlet extends ProxyServlet implements Servlet { return; } - String remoteHost = req.getRemoteHost(); - if (!Domains.isThisHostIP(remoteHost)) { + final String remoteHost = req.getRemoteHost(); + if (!Domains.isThisHostIP(remoteHost)) { response.sendError(HttpServletResponse.SC_FORBIDDEN, - "proxy use not granted for IP " + req.getRemoteAddr()); + "proxy use not granted for IP " + remoteHost); + return; + } else if (!proxyippatternmatch(remoteHost)) { + response.sendError(HttpServletResponse.SC_FORBIDDEN, + "proxy use not granted for IP " + remoteHost); return; } @@ -322,6 +327,26 @@ public class YaCyProxyServlet extends ProxyServlet implements Servlet { return buf.toString("UTF-8"); } + /** + * helper for proxy IP config pattern check + */ + private boolean proxyippatternmatch(final String key) { + // the cfgippattern is a comma-separated list of patterns + // each pattern may contain one wildcard-character '*' which matches anything + final String cfgippattern = Switchboard.getSwitchboard().getConfig("proxyClient", "*"); + if (cfgippattern.equals("*")) { + return true; + } + final StringTokenizer st = new StringTokenizer(cfgippattern, ","); + String pattern; + while (st.hasMoreTokens()) { + pattern = st.nextToken(); + if (key.matches(pattern)) { + return true; + } + } + return false; + } /** * get destination url (from query parameter &url=http://....)