summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2017-09-27 10:54:56 -0400
committerNick Mathewson <nickm@torproject.org>2017-09-27 10:54:56 -0400
commit5427365907ef42a25ba1f3de072dcd6244e7a75b (patch)
tree6afac34b6e04b134a46f51d06cd508c6009cefac
parenta57f495c1a55c0e04ee29d87d4085768c35372e0 (diff)
downloadtor-5427365907ef42a25ba1f3de072dcd6244e7a75b.tar.gz
tor-5427365907ef42a25ba1f3de072dcd6244e7a75b.zip
testing: test many possible truncated SOCKS commands
Many of the 'truncated command' paths in fetch_from_buf_socks() were not reached by the tests. This new unit test tries to check them exhaustively.
-rw-r--r--src/test/test_socks.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/test/test_socks.c b/src/test/test_socks.c
index 6dc8215a95..74dd757930 100644
--- a/src/test/test_socks.c
+++ b/src/test/test_socks.c
@@ -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
};