Fixed up security fix, so it filters correctly for clients and servers.
This commit is contained in:
@ -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 + "]");
|
||||||
|
@ -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.
|
||||||
|
Reference in New Issue
Block a user