| 
					
				 | 
			
			
				@@ -497,6 +497,105 @@ test_socks_5_malformed_commands(void *ptr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** check for correct behavior when the socks command has not arrived. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+test_socks_truncated(void *ptr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    enum { NONE, AUTH, ALL } setup; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const char *body; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    size_t len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } commands[] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* SOCKS4 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* Connect, to an IP. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { NONE, "\x04\x01\x05\x05\x01\x02\x03\x04\x00", 9}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* Connect, to an IP, with authentication. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { NONE, "\x04\x01\x05\x05\x01\x02\x03\x04hello\x00", 14}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* SOCKS4A */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* Connect, to a hostname */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { NONE, "\x04\x01\x09\x09\x00\x00\x00\x01\x00www.example.com\x00", 25}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* Connect, to a hostname, with authentication */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { NONE, "\x04\x01\x09\x09\x00\x00\x00\x01hi\x00www.example.com\x00", 27}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* SOCKS5 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* initial handshake */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { NONE, "\x05\x00", 2 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* no-auth handshake */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { NONE, "\x05\x03\x99\x21\x10", 5 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* SOCSK5, username-password, all empty. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { AUTH, "\x01\x00\x00", 3 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* SOCSK5, username-password, 1 char each. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { AUTH, "\x01\x01x\x01y", 5 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* SOCSK5, username-password, max length. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { AUTH, "\x01\xff" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "Ogni tempo ha il suo fascismo: se ne notano i segni premonitori " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "dovunque la concentrazione di potere nega al cittadino la " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "possibilit\xc3\xa0 e la capacit\xc3\xa0 di esprimere ed attuare la " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "sua volont\xc3\xa0. A questo si arriva in molti modi, non " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "necessariamente col terror" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "\xff" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "e dell'intimidazione poliziesca, ma anche negando o distorcendo " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "l'informazione, inquinando la giustizia, paralizzando la scuola, " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "diffondendo in molti modi sottili la nostalgia per un mondo in cui " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "regnava sovrano l'ordine, ed in cui la sicurezza dei pochi " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      /* privilegiati riposava sul lavoro forzato e sul silenzio forzato dei 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         molti. -- Primo Levi */ , 513 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* Socks5, IPv4 address */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { ALL, "\x05\x01\x00\x01\x01\x02\x03\x04\x20\x20", 10 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* Socks5, IPv6 address */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { ALL, "\x05\x01\x00\x04" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "\x49\x20\x48\x41\x5a\x20\x45\x41\x53\x54\x45\x52\x20\x45\x47\x47" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "\x20\x20", 22 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* Socks5, hostname, empty. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { ALL, "\x05\x01\x00\x03" "\x00" "\x00\x50", 7 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* Socks5, hostname, moderate. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { ALL, "\x05\x01\x00\x03" "\x11" "onion.example.com" "\x00\x50", 24 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* Socks5, hostname, maximum. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { ALL, "\x05\x01\x00\x03" "\xff" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "whatsoever.I.shall.see.or.hear.in.the.course.of.my.profession.as.well." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "as.outside.my.profession.in.my.intercourse.with.men.if.it.be.what." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "should.not.be.published.abroad.I.will.never.divulge.holding.such." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "things.to.be.holy.secrets.x.hippocratic.oath.wikipedia" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "\x00\x50", 262 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  unsigned i, j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SOCKS_TEST_INIT(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (i = 0; i < ARRAY_LENGTH(commands); ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (j = 0; j < commands[i].len; ++j) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      switch (commands[i].setup) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        default: /* Falls through */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case NONE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          /* This test calls for no setup on the socks state. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case AUTH: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          /* This test calls for the socks state to be waiting for 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           * username/password authentication */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ADD_DATA(buf, "\x05\x01\x02"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          tt_int_op(0, OP_EQ, fetch_from_buf_socks(buf, socks, 0, 0)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          tt_int_op(0, OP_EQ, buf_datalen(buf)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case ALL: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          /* This test calls for the socks state to be waiting for 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           * the connection request */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ADD_DATA(buf, "\x05\x01\x00"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          tt_int_op(0, OP_EQ, fetch_from_buf_socks(buf, socks, 0, 0)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          tt_int_op(0, OP_EQ, buf_datalen(buf)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      TT_BLATHER(("Checking command %u, length %u, omitting char %u", i, j, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  (unsigned)commands[i].body[j])); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      buf_add(buf, commands[i].body, j); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      /* This should return 0 meaning "not done yet" */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      tt_int_op(0, OP_EQ, fetch_from_buf_socks(buf, socks, 0, 0)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      tt_uint_op(j, OP_EQ, buf_datalen(buf)); /* Nothing was drained */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      buf_clear(buf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      socks_request_free(testdata->req); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      socks = testdata->req = socks_request_new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  done: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #define SOCKSENT(name)                                  \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   { #name, test_socks_##name, TT_FORK, &socks_setup, NULL } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -512,6 +611,8 @@ struct testcase_t socks_tests[] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   SOCKSENT(5_authenticate_with_data), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   SOCKSENT(5_malformed_commands), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SOCKSENT(truncated), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   END_OF_TESTCASES 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |