2007-10-11 zzz

* IRC Proxy: Fix several possible anonymity holes:
      - Block CTCP in NOTICE messages
      - Block CTCP anywhere in PRIVMSG and NOTICE, not just at first character
      - Check for lower case commands
    (Thanks sponge!)
This commit is contained in:
zzz
2007-10-11 06:03:21 +00:00
committed by zzz
parent e480931e20
commit 819a72d4f6
3 changed files with 24 additions and 19 deletions

View File

@ -272,7 +272,7 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
int idx=0; int idx=0;
final String[] allowedCommands = final String[] allowedCommands =
{ {
"NOTICE", // "NOTICE", // can contain CTCP
//"PING", //"PING",
//"PONG", //"PONG",
"MODE", "MODE",
@ -306,9 +306,9 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
} catch(NumberFormatException nfe){} } catch(NumberFormatException nfe){}
if ("PING".equals(command)) if ("PING".equalsIgnoreCase(command))
return "PING 127.0.0.1"; // no way to know what the ircd to i2ptunnel server con is, so localhost works return "PING 127.0.0.1"; // no way to know what the ircd to i2ptunnel server con is, so localhost works
if ("PONG".equals(command)) { if ("PONG".equalsIgnoreCase(command)) {
// Turn the received ":irc.freshcoffee.i2p PONG irc.freshcoffee.i2p :127.0.0.1" // Turn the received ":irc.freshcoffee.i2p PONG irc.freshcoffee.i2p :127.0.0.1"
// into ":127.0.0.1 PONG 127.0.0.1 " so that the caller can append the client's extra parameter // into ":127.0.0.1 PONG 127.0.0.1 " so that the caller can append the client's extra parameter
// though, does 127.0.0.1 work for irc clients connecting remotely? and for all of them? sure would // though, does 127.0.0.1 work for irc clients connecting remotely? and for all of them? sure would
@ -322,18 +322,17 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
// Allow all allowedCommands // Allow all allowedCommands
for(int i=0;i<allowedCommands.length;i++) { for(int i=0;i<allowedCommands.length;i++) {
if(allowedCommands[i].equals(command)) if(allowedCommands[i].equalsIgnoreCase(command))
return s; return s;
} }
// Allow PRIVMSG, but block CTCP. // Allow PRIVMSG, but block CTCP.
if("PRIVMSG".equals(command)) if("PRIVMSG".equalsIgnoreCase(command) || "NOTICE".equalsIgnoreCase(command))
{ {
String msg; String msg;
msg = field[idx++]; msg = field[idx++];
byte[] bytes = msg.getBytes(); if(msg.indexOf(0x01) >= 0) // CTCP marker ^A can be anywhere, not just immediately after the ':'
if(bytes[1]==0x01)
{ {
// CTCP // CTCP
msg=msg.substring(2); msg=msg.substring(2);
@ -356,7 +355,7 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
String command; String command;
final String[] allowedCommands = final String[] allowedCommands =
{ {
"NOTICE", // "NOTICE", // can contain CTCP
"MODE", "MODE",
"JOIN", "JOIN",
"NICK", "NICK",
@ -387,7 +386,7 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
command = field[0].toUpperCase(); command = field[0].toUpperCase();
if ("PING".equals(command)) { if ("PING".equalsIgnoreCase(command)) {
// Most clients just send a PING and are happy with any old PONG. Others, // Most clients just send a PING and are happy with any old PONG. Others,
// like BitchX, actually expect certain behavior. It sends two different pings: // like BitchX, actually expect certain behavior. It sends two different pings:
// "PING :irc.freshcoffee.i2p" and "PING 1234567890 127.0.0.1" (where the IP is the proxy) // "PING :irc.freshcoffee.i2p" and "PING 1234567890 127.0.0.1" (where the IP is the proxy)
@ -421,24 +420,23 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
return rv; return rv;
} }
if ("PONG".equals(command)) if ("PONG".equalsIgnoreCase(command))
return "PONG 127.0.0.1"; // no way to know what the ircd to i2ptunnel server con is, so localhost works return "PONG 127.0.0.1"; // no way to know what the ircd to i2ptunnel server con is, so localhost works
// Allow all allowedCommands // Allow all allowedCommands
for(int i=0;i<allowedCommands.length;i++) for(int i=0;i<allowedCommands.length;i++)
{ {
if(allowedCommands[i].equals(command)) if(allowedCommands[i].equalsIgnoreCase(command))
return s; return s;
} }
// Allow PRIVMSG, but block CTCP (except ACTION). // Allow PRIVMSG, but block CTCP (except ACTION).
if("PRIVMSG".equals(command)) if("PRIVMSG".equalsIgnoreCase(command) || "NOTICE".equalsIgnoreCase(command))
{ {
String msg; String msg;
msg = field[2]; msg = field[2];
byte[] bytes = msg.getBytes(); if(msg.indexOf(0x01) >= 0) // CTCP marker ^A can be anywhere, not just immediately after the ':'
if(bytes[1]==0x01)
{ {
// CTCP // CTCP
msg=msg.substring(2); msg=msg.substring(2);
@ -451,14 +449,14 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
return s; return s;
} }
if("USER".equals(command)) { if("USER".equalsIgnoreCase(command)) {
int idx = field[2].lastIndexOf(":"); int idx = field[2].lastIndexOf(":");
if(idx<0) if(idx<0)
return "USER user hostname localhost :realname"; return "USER user hostname localhost :realname";
String realname = field[2].substring(idx+1); String realname = field[2].substring(idx+1);
String ret = "USER "+field[1]+" hostname localhost :"+realname; String ret = "USER "+field[1]+" hostname localhost :"+realname;
return ret; return ret;
} else if ("QUIT".equals(command)) { } else if ("QUIT".equalsIgnoreCase(command)) {
return "QUIT :leaving"; return "QUIT :leaving";
} }

View File

@ -1,4 +1,11 @@
$Id: history.txt,v 1.593 2007-10-07 22:01:47 jrandom Exp $ $Id: history.txt,v 1.594 2007-10-07 23:11:36 jrandom Exp $
2007-10-11 zzz
* IRC Proxy: Fix several possible anonymity holes:
- Block CTCP in NOTICE messages
- Block CTCP anywhere in PRIVMSG and NOTICE, not just at first character
- Check for lower case commands
(Thanks sponge!)
2007-10-07 jrandom 2007-10-07 jrandom
* back out the NTCP backlog pushback, as it could be used to mount an * back out the NTCP backlog pushback, as it could be used to mount an

View File

@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
* *
*/ */
public class RouterVersion { public class RouterVersion {
public final static String ID = "$Revision: 1.529 $ $Date: 2007-10-07 22:01:49 $"; public final static String ID = "$Revision: 1.530 $ $Date: 2007-10-07 23:11:37 $";
public final static String VERSION = "0.6.1.30"; public final static String VERSION = "0.6.1.30";
public final static long BUILD = 1; public final static long BUILD = 2;
public static void main(String args[]) { public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD); System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID); System.out.println("Router ID: " + RouterVersion.ID);