From bf69a721cb4b29b63375cc13076668255e529055 Mon Sep 17 00:00:00 2001 From: orbiter Date: Fri, 9 Feb 2007 15:25:10 +0000 Subject: [PATCH] more protection against mis-use of YaCyHop interface: - target must not be at port 80 - target access not more than every 3 seconds - requester may not access more than every 10 seconds git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@3357 6c8d7289-2bf4-0310-a012-ef5d649a1542 --- source/de/anomic/http/httpd.java | 47 ++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/source/de/anomic/http/httpd.java b/source/de/anomic/http/httpd.java index 33f1dd1f6..e771a0644 100644 --- a/source/de/anomic/http/httpd.java +++ b/source/de/anomic/http/httpd.java @@ -124,19 +124,21 @@ public final class httpd implements serverHandler { private static String virtualHost = null; public static boolean keepAliveSupport = false; + private static HashMap YaCyHopAccessRequester = new HashMap(); + private static HashMap YaCyHopAccessTargets = new HashMap(); // class objects private serverCore.Session session; // holds the session object of the calling class private InetAddress userAddress; // the address of the client - private boolean allowProxy; - private boolean allowServer; - private boolean allowYaCyHop; // for authentication private boolean use_proxyAccounts = false; private boolean proxyAccounts_init = false; // is use_proxyAccounts set? private String serverAccountBase64MD5; private String clientIP; + private boolean allowProxy; + private boolean allowServer; + private boolean allowYaCyHop; // the connection properties private final Properties prop = new Properties(); @@ -337,7 +339,21 @@ public final class httpd implements serverHandler { } private boolean handleYaCyHopAuthentication(httpHeader header) throws IOException { - // proxy hops must identify with 3 criteria: + // check if the user has allowed that his/her peer is used for hops + if (!this.allowYaCyHop) return false; + + // proxy hops must identify with 4 criteria: + + // the accessed port must not be port 80 + String host = this.prop.getProperty(httpHeader.CONNECTION_PROP_HOST); + if (host == null) return false; + int pos; + if ((pos = host.indexOf(":")) < 0) { + // default port 80 + return false; // not allowed + } else { + if (Integer.parseInt(host.substring(pos + 1)) == 80) return false; + } // the access path must be into the yacy protocol path; it must start with 'yacy' if (!(this.prop.getProperty(httpHeader.CONNECTION_PROP_PATH, "").startsWith("/yacy/"))) return false; @@ -350,9 +366,30 @@ public final class httpd implements serverHandler { if (!test.equals(auth.trim().substring(6))) return false; // the accessing client must use a yacy user-agent - return (((String) header.get(httpHeader.USER_AGENT,"")).startsWith("yacy")); + if (!(((String) header.get(httpHeader.USER_AGENT,"")).startsWith("yacy"))) return false; + + // furthermore, YaCy hops must not exceed a specific access frequency + + // check access requester frequency: protection against DoS against this peer + String requester = this.prop.getProperty(httpHeader.CONNECTION_PROP_CLIENTIP); + if (requester == null) return false; + if (lastAccessDelta(YaCyHopAccessRequester, requester) < 10000) return false; + YaCyHopAccessRequester.put(requester, new Long(System.currentTimeMillis())); + + // check access target frequecy: protection against DoS from a single peer by several different requesters + if (lastAccessDelta(YaCyHopAccessTargets, host) < 3000) return false; + YaCyHopAccessTargets.put(host, new Long(System.currentTimeMillis())); + + // passed all tests + return true; } + private static long lastAccessDelta(HashMap accessTable, String domain) { + Long lastAccess = (Long) accessTable.get(domain); + if (lastAccess == null) return Long.MAX_VALUE; // never accessed + return System.currentTimeMillis() - lastAccess.longValue(); + } + private boolean handleProxyAuthentication(httpHeader header) throws IOException { // getting the http version that is used by the client String httpVersion = this.prop.getProperty("HTTP", "HTTP/0.9");