Aurélien GÉRÔME wrote:
Thanks to this bug, cutter got blindly removed from testing, and I
still _cannot_ reproduce it. It would ne nice to get some recipe to
reproduce it, if we ever want it to be released with Lenny.

I've added some debug to the program, and it seems to me that it simply cannot work. Either that or I'm grossly misunderstanding what it does.

The attached patch applies my debug code to the debian cutter version 1.03-2. Apologies for the code quality; I haven't written any C for a good number of years, now, and it was thrown together in a hurry.

To reproduce the situation where it doesn't work for me, you need three systems: A (10.1.20.42 /16) and C (192.168.130.252 /21) are connected via B (10.1.1.106 /16 and 192.168.133.13 /21). There's no NAT involved. On A, ssh to C. Log in to B and you'll see an entry in /proc/net/ip_conntrack matching the connection.

I picked it out with this ugly line:

sudo grep 'tcp.*ESTABLISHED' /proc/net/ip_conntrack | grep '10.1.20.42' | grep '192.168.*252' | grep 'port=22 '

Now run the patched version of cutter and you'll see something like this:

Args: /tmp/cutter 192.168.130.252 22 10.1.20.42
...
Got tcp/ESTABLISHED
> src=10.1.20.42
> dst=192.168.130.252
> sport=36707
> dport=22
> src=192.168.130.252
> dst=10.1.20.42
> sport=22
> dport=36707
Matched IP and port
 localip(src1n=10.1.20.42)=0, localip(dst1n=192.168.130.252)=0,
 localip(src2n=192.168.130.252)=0, localip(dst2n=10.1.20.42)=0
Got tcp/ESTABLISHED
...

Looking at the code around 540, there are a number of condition criteria that check for local/remote IP address (I guess that "local" means a local interface for the box on which cutter is running).

If you have a connection from A to C, via B, then neither of the address pairs are going to be local, so neither of the two if() statements can succeed.

I haven't had time to dig further (maybe tomorrow), but I would imagine a patch will be pretty straightforward.

Regards,
Chris
--- cutter.c.2008-02-14	2008-02-14 11:24:45.000000000 +0000
+++ cutter.c	2008-02-14 11:52:41.000000000 +0000
@@ -494,7 +494,18 @@
 			continue;
 
 		p = buff;
-
+puts("Got tcp/ESTABLISHED");
+{
+char item[32]; char *i = buff;
+if (get_str_field(&i, " src=", item, sizeof(item))) printf("> src=%s\n", item); else puts(" no src");
+if (get_str_field(&i, " dst=", item, sizeof(item))) printf("> dst=%s\n", item); else puts(" no dst");
+if (get_str_field(&i, " sport=", item, sizeof(item))) printf("> sport=%s\n", item); else puts(" no sport");
+if (get_str_field(&i, " dport=", item, sizeof(item))) printf("> dport=%s\n", item); else puts(" no dport");
+if (get_str_field(&i, " src=", item, sizeof(item))) printf("> src=%s\n", item); else puts(" no src");
+if (get_str_field(&i, " dst=", item, sizeof(item))) printf("> dst=%s\n", item); else puts(" no dst");
+if (get_str_field(&i, " sport=", item, sizeof(item))) printf("> sport=%s\n", item); else puts(" no sport");
+if (get_str_field(&i, " dport=", item, sizeof(item))) printf("> dport=%s\n", item); else puts(" no dport");
+}
 		if (
 			!get_str_field(&p, " src=", src1, sizeof(src1)) ||
 			!get_str_field(&p, " dst=", dst1, sizeof(dst1)) ||
@@ -504,7 +515,7 @@
 			!get_str_field(&p, " dst=", dst2, sizeof(dst2)) ||
 			!get_int_field(&p, " sport=", &sport2) ||
 			!get_int_field(&p, " dport=", &dport2)
-		) continue;
+		) { puts("Not got all required fields; continuing"); continue; }
 
 		src1n = inet_addr(src1);
 		src2n = inet_addr(src2);
@@ -517,11 +528,13 @@
 			(match(ip1,port1,src1n,sport1) && match(ip2,port2,dst1n,dport1)) ||
 			(match(ip1,port1,dst1n,dport1) && match(ip2,port2,src1n,sport1))
 		) {
+puts("Matched IP and port");
+printf (" localip(src1n=%s)=%d, localip(dst1n=%s)=%d, localip(src2n=%s)=%d, localip(dst2n=%s)=%d\n", src1, localip(src1n), dst1, localip(dst1n), src2, localip(src2n), dst2, localip(dst2n));
 			/*
 			 * local network to public network - forwarded connection
 			 */
-
 			if (!localip(src1n) && !localip(dst1n) && !localip(src2n) && localip(dst2n)) {
+puts("Local network to public network - forwarded connection");
 				found ++;
 				printf("For connection %s:%d -> %s:%d\n", src1, sport1, dst1, dport1);
 				ok = send_rst(dst1,dport1,src1,sport1) && ok;
@@ -531,6 +544,7 @@
 			/* Inbound connection forwarded to private network device */
 
 			else if (!localip(src1n) && localip(dst1n) && !localip(src2n) && !localip(dst2n)) {
+puts("Inbound connection forwarded to private network device");
 				found ++;
 				printf("For connection %s:%d -> %s:%d\n", dst2, dport2, src2, sport2);
 				ok = send_rst(dst1,dport1,src1,sport1) && ok;
@@ -564,6 +578,7 @@
 		exit(EXIT_FAILURE);
 	}
 
+{ int i; printf("Args:"); for (i=0; i<argc; i++) { printf(" %s", argv[i]); } putchar('\n'); }
 	getifconfig();
 	if (scan_conntrack(ip1, port1, ip2, port2))
 		return EXIT_SUCCESS;

Reply via email to