2006-04-01 jrandom

* Take out the router watchdog's teeth (don't restart on leaseset failure)
    * Filter the IRC ping/pong messages, as some clients send unsafe
      information in them (thanks aardvax and dust!)
This commit is contained in:
jrandom
2006-04-03 10:07:22 +00:00
committed by zzz
parent 1b3ad31bff
commit 764149aef3
4 changed files with 83 additions and 9 deletions

View File

@ -27,6 +27,8 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
protected List dests;
private static final long DEFAULT_READ_TIMEOUT = 5*60*1000; // -1
protected long readTimeout = DEFAULT_READ_TIMEOUT;
/** this is the pong response the client expects for their last ping. at least, i hope so... */
private String _expectedPong;
/**
* @throws IllegalArgumentException if the I2PTunnel does not contain
@ -44,6 +46,8 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
l,
notifyThis,
"IRCHandler " + (++__clientId), tunnel);
_expectedPong = null;
StringTokenizer tok = new StringTokenizer(destinations, ",");
dests = new ArrayList(1);
@ -147,6 +151,8 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
break;
if(inmsg.endsWith("\r"))
inmsg=inmsg.substring(0,inmsg.length()-1);
if (_log.shouldLog(Log.DEBUG))
_log.debug("in: [" + inmsg + "]");
String outmsg = inboundFilter(inmsg);
if(outmsg!=null)
{
@ -217,9 +223,41 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
break;
if(inmsg.endsWith("\r"))
inmsg=inmsg.substring(0,inmsg.length()-1);
if (_log.shouldLog(Log.DEBUG))
_log.debug("out: [" + inmsg + "]");
String outmsg = outboundFilter(inmsg);
if(outmsg!=null)
{
if (outmsg.indexOf("PING") >= 0) {
// 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:
// "PING :irc.freshcoffee.i2p" and "PING 1234567890 127.0.0.1" (where the IP is the proxy)
// the PONG to the former seems to be "PONG 127.0.0.1", while the PONG to the later is
// ":irc.freshcoffee.i2p PONG irc.freshcoffe.i2p :1234567890".
// We don't want to send them our proxy's IP address, so we need to rewrite the PING
// sent to the server, but when we get a PONG back, use what we expected, rather than
// what they sent.
//
// Yuck.
StringTokenizer tok = new StringTokenizer(inmsg, " ");
int tokens = tok.countTokens();
if ( (tokens <= 2) || (tokens == 3) ) { // "PING nonce" or "PING nonce serverIP"
tok.nextToken(); // skip
//_expectedPong = "PONG 127.0.0.1 :" + tok.nextToken();
_expectedPong = "PONG " + tok.nextToken();
} else {
// if it isn't one of those two, we will filter out all PONGs, which means
// the client will fail. whee!
if (_log.shouldLog(Log.ERROR))
_log.error("IRC client sent a PING we don't understand (\"" + inmsg + "\"), so we're filtering it");
_expectedPong = null;
}
if (_log.shouldLog(Log.WARN)) {
_log.warn("outbound rewritten PING: "+outmsg + ", waiting for [" + _expectedPong + "]");
_log.warn(" - outbound was: "+inmsg);
}
}
if(!inmsg.equals(outmsg)) {
if (_log.shouldLog(Log.WARN)) {
_log.warn("outbound FILTERED: "+outmsg);
@ -256,7 +294,7 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
*
*/
public static String inboundFilter(String s) {
public String inboundFilter(String s) {
String field[]=s.split(" ",4);
String command;
@ -264,8 +302,8 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
final String[] allowedCommands =
{
"NOTICE",
"PING",
"PONG",
//"PING",
//"PONG",
"MODE",
"JOIN",
"NICK",
@ -293,6 +331,21 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
new Integer(command);
return s;
} catch(NumberFormatException nfe){}
if ("PING".equals(command))
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)) {
// 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
// though, does 127.0.0.1 work for irc clients connecting remotely? and for all of them? sure would
// be great if irc clients actually followed the RFCs here, but i guess thats too much to ask.
// If we haven't PINGed them, or the PING we sent isn't something we know how to filter, this
// is null.
String pong = _expectedPong;
_expectedPong = null;
return pong;
}
// Allow all allowedCommands
for(int i=0;i<allowedCommands.length;i++) {
@ -331,7 +384,6 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
final String[] allowedCommands =
{
"NOTICE",
"PONG",
"MODE",
"JOIN",
"NICK",
@ -345,7 +397,8 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
"MAP", // seems safe enough, the ircd should protect themselves though
"PART",
"OPER",
"PING",
// "PONG", // replaced with a filtered PING/PONG since some clients send the server IP (thanks aardvax!)
// "PING",
"KICK",
"HELPME",
"RULES",
@ -361,6 +414,23 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
command = field[0].toUpperCase();
if ("PING".equals(command)) {
// e.g. "PING", "PING nonce", or "PING nonce serverIP"
if (field.length == 1) {
return "PING";
} else if (field.length == 2) {
return "PING " + field[1];
} else if (field.length == 3) {
return "PING " + field[1];
} else {
if (_log.shouldLog(Log.ERROR))
_log.error("IRC client sent a PING we don't understand, filtering it (\"" + s + "\")");
return null;
}
}
if ("PONG".equals(command))
return "PONG 127.0.0.1"; // no way to know what the ircd to i2ptunnel server con is, so localhost works
// Allow all allowedCommands
for(int i=0;i<allowedCommands.length;i++)
{

View File

@ -1,7 +1,9 @@
$Id: history.txt,v 1.441 2006/03/30 02:26:43 jrandom Exp $
$Id: history.txt,v 1.442 2006/04/01 14:05:37 jrandom Exp $
2006-04-01 jrandom
* Take out the router watchdog's teeth (don't restart on leaseset failure)
* Filter the IRC ping/pong messages, as some clients send unsafe
information in them (thanks aardvax and dust!)
2006-03-30 jrandom
* Substantially reduced the lock contention in the message registry (a

View File

@ -326,7 +326,9 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM
}
}
protected void verifyUnwritten() { if (_written) throw new RuntimeException("Already written"); }
protected void verifyUnwritten() {
// if (_written) throw new RuntimeException("Already written");
}
protected void written() { _written = true; }
protected void read() { _read = true; }

View File

@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
*
*/
public class RouterVersion {
public final static String ID = "$Revision: 1.382 $ $Date: 2006/03/30 02:26:49 $";
public final static String ID = "$Revision: 1.383 $ $Date: 2006/04/01 14:08:41 $";
public final static String VERSION = "0.6.1.13";
public final static long BUILD = 2;
public final static long BUILD = 3;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID);