Fixed up security fix, so it filters correctly for clients and servers.

This commit is contained in:
mathiasdm
2010-12-10 06:04:23 +00:00
parent 59343b5899
commit 6983380668
2 changed files with 33 additions and 14 deletions

View File

@ -15,6 +15,7 @@ import java.util.Properties;
import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPOutputStream;
import net.i2p.client.streaming.I2PSocket; import net.i2p.client.streaming.I2PSocket;
import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper; import net.i2p.data.DataHelper;
import net.i2p.util.EventDispatcher; import net.i2p.util.EventDispatcher;
import net.i2p.util.I2PAppThread; import net.i2p.util.I2PAppThread;
@ -36,6 +37,9 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
private static final String HASH_HEADER = "X-I2P-DestHash"; private static final String HASH_HEADER = "X-I2P-DestHash";
private static final String DEST64_HEADER = "X-I2P-DestB64"; private static final String DEST64_HEADER = "X-I2P-DestB64";
private static final String DEST32_HEADER = "X-I2P-DestB32"; private static final String DEST32_HEADER = "X-I2P-DestB32";
private static final String[] CLIENT_SKIPHEADERS = {HASH_HEADER, DEST64_HEADER, DEST32_HEADER};
private static final String SERVER_HEADER = "Server";
private static final String[] SERVER_SKIPHEADERS = {SERVER_HEADER};
public I2PTunnelHTTPServer(InetAddress host, int port, String privData, String spoofHost, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) { public I2PTunnelHTTPServer(InetAddress host, int port, String privData, String spoofHost, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) {
super(host, port, privData, l, notifyThis, tunnel); super(host, port, privData, l, notifyThis, tunnel);
@ -75,7 +79,8 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
InputStream in = socket.getInputStream(); InputStream in = socket.getInputStream();
StringBuilder command = new StringBuilder(128); StringBuilder command = new StringBuilder(128);
Properties headers = readHeaders(in, command); Properties headers = readHeaders(in, command,
CLIENT_SKIPHEADERS, getTunnel().getContext());
headers.setProperty(HASH_HEADER, socket.getPeerDestination().calculateHash().toBase64()); headers.setProperty(HASH_HEADER, socket.getPeerDestination().calculateHash().toBase64());
headers.setProperty(DEST32_HEADER, Base32.encode(socket.getPeerDestination().calculateHash().getData()) + ".b32.i2p" ); headers.setProperty(DEST32_HEADER, Base32.encode(socket.getPeerDestination().calculateHash().getData()) + ".b32.i2p" );
headers.setProperty(DEST64_HEADER, socket.getPeerDestination().toBase64()); headers.setProperty(DEST64_HEADER, socket.getPeerDestination().toBase64());
@ -118,7 +123,9 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
useGZIP = true; useGZIP = true;
if (allowGZIP && useGZIP) { if (allowGZIP && useGZIP) {
I2PAppThread req = new I2PAppThread(new CompressedRequestor(s, socket, modifiedHeader), Thread.currentThread().getName()+".hc"); I2PAppThread req = new I2PAppThread(
new CompressedRequestor(s, socket, modifiedHeader, getTunnel().getContext()),
Thread.currentThread().getName()+".hc");
req.start(); req.start();
} else { } else {
new I2PTunnelRunner(s, socket, slock, null, modifiedHeader.getBytes(), null); new I2PTunnelRunner(s, socket, slock, null, modifiedHeader.getBytes(), null);
@ -155,10 +162,12 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
private Socket _webserver; private Socket _webserver;
private I2PSocket _browser; private I2PSocket _browser;
private String _headers; private String _headers;
public CompressedRequestor(Socket webserver, I2PSocket browser, String headers) { private I2PAppContext _ctx;
public CompressedRequestor(Socket webserver, I2PSocket browser, String headers, I2PAppContext ctx) {
_webserver = webserver; _webserver = webserver;
_browser = browser; _browser = browser;
_headers = headers; _headers = headers;
_ctx = ctx;
} }
public void run() { public void run() {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
@ -200,8 +209,8 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
//Change headers to protect server identity //Change headers to protect server identity
StringBuilder command = new StringBuilder(128); StringBuilder command = new StringBuilder(128);
Properties headers = readHeaders(serverin, command); Properties headers = readHeaders(serverin, command,
headers.setProperty("Server", "I2PServer"); SERVER_SKIPHEADERS, _ctx);
String modifiedHeaders = formatHeaders(headers, command); String modifiedHeaders = formatHeaders(headers, command);
compressedOut.write(modifiedHeaders.getBytes()); compressedOut.write(modifiedHeaders.getBytes());
@ -336,7 +345,7 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
/** ridiculously long, just to prevent OOM DOS @since 0.7.13 */ /** ridiculously long, just to prevent OOM DOS @since 0.7.13 */
private static final int MAX_HEADERS = 60; private static final int MAX_HEADERS = 60;
private static Properties readHeaders(InputStream in, StringBuilder command) throws IOException { private static Properties readHeaders(InputStream in, StringBuilder command, String[] skipHeaders, I2PAppContext ctx) throws IOException {
Properties headers = new Properties(); Properties headers = new Properties();
StringBuilder buf = new StringBuilder(128); StringBuilder buf = new StringBuilder(128);
@ -356,8 +365,8 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
} }
} }
} }
//if (trimmed > 0) if (trimmed > 0)
// getTunnel().getContext().statManager().addRateData("i2ptunnel.httpNullWorkaround", trimmed, 0); ctx.statManager().addRateData("i2ptunnel.httpNullWorkaround", trimmed, 0);
int i = 0; int i = 0;
while (true) { while (true) {
@ -379,16 +388,24 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
value = buf.substring(split+1).trim(); // ":" value = buf.substring(split+1).trim(); // ":"
else else
value = ""; value = "";
if ("Accept-encoding".equalsIgnoreCase(name)) if ("Accept-encoding".equalsIgnoreCase(name))
name = "Accept-encoding"; name = "Accept-encoding";
else if ("X-Accept-encoding".equalsIgnoreCase(name)) else if ("X-Accept-encoding".equalsIgnoreCase(name))
name = "X-Accept-encoding"; name = "X-Accept-encoding";
else if (HASH_HEADER.equalsIgnoreCase(name))
continue; // Prevent spoofing //We want to remove certain headers to improve anonymity
else if (DEST64_HEADER.equalsIgnoreCase(name)) boolean skip = false;
continue; // Prevent spoofing for (String skipHeader: skipHeaders) {
else if (DEST32_HEADER.equalsIgnoreCase(name)) if (skipHeader.equalsIgnoreCase(name)) {
continue; // Prevent spoofing skip = true;
break;
}
}
if(skip) {
continue;
}
headers.setProperty(name, value); headers.setProperty(name, value);
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
_log.debug("Read the header [" + name + "] = [" + value + "]"); _log.debug("Read the header [" + name + "] = [" + value + "]");

View File

@ -1,3 +1,5 @@
2010-12-10 Mathiasdm
* I2PTunnel: Fixed up security fix.
2010-12-07 Mathiasdm 2010-12-07 Mathiasdm
* I2PTunnel: Security fix: change server reply * I2PTunnel: Security fix: change server reply
to return 'I2PServer' instead of the actual servername. to return 'I2PServer' instead of the actual servername.