static void test_util_format_unaligned_accessors(void *ignored) { (void)ignored; char buf[9] = "onionsoup"; // 6f6e696f6e736f7570 tt_u64_op(get_uint64(buf+1), OP_EQ, htonll(U64_LITERAL(0x6e696f6e736f7570))); tt_uint_op(get_uint32(buf+1), OP_EQ, htonl(0x6e696f6e)); tt_uint_op(get_uint16(buf+1), OP_EQ, htons(0x6e69)); tt_uint_op(get_uint8(buf+1), OP_EQ, 0x6e); set_uint8(buf+7, 0x61); tt_mem_op(buf, OP_EQ, "onionsoap", 9); set_uint16(buf+6, htons(0x746f)); tt_mem_op(buf, OP_EQ, "onionstop", 9); set_uint32(buf+1, htonl(0x78696465)); tt_mem_op(buf, OP_EQ, "oxidestop", 9); set_uint64(buf+1, htonll(U64_LITERAL(0x6266757363617465))); tt_mem_op(buf, OP_EQ, "obfuscate", 9); done: ; }
static void test_buffers_zlib_fin_at_chunk_end(void *arg) { char *msg = NULL; char *contents = NULL; char *expanded = NULL; buf_t *buf = NULL; tor_zlib_state_t *zlib_state = NULL; size_t out_len, in_len; size_t sz, headerjunk; (void) arg; buf = buf_new_with_capacity(128); /* will round up */ sz = buf_get_default_chunk_size(buf); msg = tor_malloc_zero(sz); write_to_buf(msg, 1, buf); tt_assert(buf->head); /* Fill up the chunk so the zlib stuff won't fit in one chunk. */ tt_uint_op(buf->head->memlen, OP_LT, sz); headerjunk = buf->head->memlen - 7; write_to_buf(msg, headerjunk-1, buf); tt_uint_op(buf->head->datalen, OP_EQ, headerjunk); tt_uint_op(buf_datalen(buf), OP_EQ, headerjunk); /* Write an empty string, with finalization on. */ zlib_state = tor_zlib_new(1, ZLIB_METHOD, HIGH_COMPRESSION); tt_int_op(write_to_buf_zlib(buf, zlib_state, "", 0, 1), OP_EQ, 0); in_len = buf_datalen(buf); contents = tor_malloc(in_len); tt_int_op(fetch_from_buf(contents, in_len, buf), OP_EQ, 0); tt_uint_op(in_len, OP_GT, headerjunk); tt_int_op(0, OP_EQ, tor_gzip_uncompress(&expanded, &out_len, contents + headerjunk, in_len - headerjunk, ZLIB_METHOD, 1, LOG_WARN)); tt_int_op(out_len, OP_EQ, 0); tt_assert(expanded); done: buf_free(buf); tor_zlib_free(zlib_state); tor_free(contents); tor_free(expanded); tor_free(msg); }
static void test_crypto_pwbox(void *arg) { uint8_t *boxed=NULL, *decoded=NULL; size_t len, dlen; unsigned i; const char msg[] = "This bunny reminds you that you still have a " "salamander in your sylladex. She is holding the bunny Dave got you. " "It’s sort of uncanny how similar they are, aside from the knitted " "enhancements. Seriously, what are the odds?? So weird."; const char pw[] = "I'm a night owl and a wise bird too"; const unsigned flags[] = { 0, S2K_FLAG_NO_SCRYPT, S2K_FLAG_LOW_MEM, S2K_FLAG_NO_SCRYPT|S2K_FLAG_LOW_MEM, S2K_FLAG_USE_PBKDF2 }; (void)arg; for (i = 0; i < ARRAY_LENGTH(flags); ++i) { tt_int_op(0, OP_EQ, crypto_pwbox(&boxed, &len, (const uint8_t*)msg, strlen(msg), pw, strlen(pw), flags[i])); tt_assert(boxed); tt_assert(len > 128+32); tt_int_op(0, OP_EQ, crypto_unpwbox(&decoded, &dlen, boxed, len, pw, strlen(pw))); tt_assert(decoded); tt_uint_op(dlen, OP_EQ, strlen(msg)); tt_mem_op(decoded, OP_EQ, msg, dlen); tor_free(decoded); tt_int_op(UNPWBOX_BAD_SECRET, OP_EQ, crypto_unpwbox(&decoded, &dlen, boxed, len, pw, strlen(pw)-1)); boxed[len-1] ^= 1; tt_int_op(UNPWBOX_BAD_SECRET, OP_EQ, crypto_unpwbox(&decoded, &dlen, boxed, len, pw, strlen(pw))); boxed[0] = 255; tt_int_op(UNPWBOX_CORRUPTED, OP_EQ, crypto_unpwbox(&decoded, &dlen, boxed, len, pw, strlen(pw))); tor_free(boxed); } done: tor_free(boxed); tor_free(decoded); }
static void test_buffers_chunk_size(void *arg) { (void)arg; const int min = 256; const int max = 65536; tt_uint_op(preferred_chunk_size(3), OP_EQ, min); tt_uint_op(preferred_chunk_size(25), OP_EQ, min); tt_uint_op(preferred_chunk_size(0), OP_EQ, min); tt_uint_op(preferred_chunk_size(256), OP_EQ, 512); tt_uint_op(preferred_chunk_size(65400), OP_EQ, max); /* Here, we're implicitly saying that the chunk header overhead is * between 1 and 100 bytes. 24..48 would probably be more accurate. */ tt_uint_op(preferred_chunk_size(65536), OP_GT, 65536); tt_uint_op(preferred_chunk_size(65536), OP_LT, 65536+100); tt_uint_op(preferred_chunk_size(165536), OP_GT, 165536); tt_uint_op(preferred_chunk_size(165536), OP_LT, 165536+100); done: ; }
static void test_ext_or_cookie_auth_testvec(void *arg) { char *reply=NULL, *client_hash=NULL; size_t reply_len; char *mem_op_hex_tmp=NULL; const char client_nonce[] = "But when I look ahead up the whi"; (void)arg; ext_or_auth_cookie = tor_malloc_zero(32); memcpy(ext_or_auth_cookie, "Gliding wrapt in a brown mantle," , 32); ext_or_auth_cookie_is_set = 1; MOCK(crypto_rand, crypto_rand_return_tse_str); tt_int_op(0, OP_EQ, handle_client_auth_nonce(client_nonce, 32, &client_hash, &reply, &reply_len)); tt_ptr_op(reply, OP_NE, NULL ); tt_uint_op(reply_len, OP_EQ, 64); tt_mem_op(reply+32,OP_EQ, "te road There is always another ", 32); /* HMACSHA256("Gliding wrapt in a brown mantle," * "ExtORPort authentication server-to-client hash" * "But when I look ahead up the write road There is always another "); */ test_memeq_hex(reply, "ec80ed6e546d3b36fdfc22fe1315416b" "029f1ade7610d910878b62eeb7403821"); /* HMACSHA256("Gliding wrapt in a brown mantle," * "ExtORPort authentication client-to-server hash" * "But when I look ahead up the write road There is always another "); * (Both values computed using Python CLI.) */ test_memeq_hex(client_hash, "ab391732dd2ed968cd40c087d1b1f25b" "33b3cd77ff79bd80c2074bbf438119a2"); done: UNMOCK(crypto_rand); tor_free(reply); tor_free(client_hash); tor_free(mem_op_hex_tmp); }
static void test_pick_circid(void *arg) { bitarray_t *ba = NULL; channel_t *chan1, *chan2; circid_t circid; int i; (void) arg; chan1 = tor_malloc_zero(sizeof(channel_t)); chan2 = tor_malloc_zero(sizeof(channel_t)); chan2->wide_circ_ids = 1; chan1->circ_id_type = CIRC_ID_TYPE_NEITHER; tt_int_op(0, OP_EQ, get_unique_circ_id_by_chan(chan1)); /* Basic tests, with no collisions */ chan1->circ_id_type = CIRC_ID_TYPE_LOWER; for (i = 0; i < 50; ++i) { circid = get_unique_circ_id_by_chan(chan1); tt_uint_op(0, OP_LT, circid); tt_uint_op(circid, OP_LT, (1<<15)); } chan1->circ_id_type = CIRC_ID_TYPE_HIGHER; for (i = 0; i < 50; ++i) { circid = get_unique_circ_id_by_chan(chan1); tt_uint_op((1<<15), OP_LT, circid); tt_uint_op(circid, OP_LT, (1<<16)); } chan2->circ_id_type = CIRC_ID_TYPE_LOWER; for (i = 0; i < 50; ++i) { circid = get_unique_circ_id_by_chan(chan2); tt_uint_op(0, OP_LT, circid); tt_uint_op(circid, OP_LT, (1u<<31)); } chan2->circ_id_type = CIRC_ID_TYPE_HIGHER; for (i = 0; i < 50; ++i) { circid = get_unique_circ_id_by_chan(chan2); tt_uint_op((1u<<31), OP_LT, circid); } /* Now make sure that we can behave well when we are full up on circuits */ chan1->circ_id_type = CIRC_ID_TYPE_LOWER; chan2->circ_id_type = CIRC_ID_TYPE_LOWER; chan1->wide_circ_ids = chan2->wide_circ_ids = 0; ba = bitarray_init_zero((1<<15)); for (i = 0; i < (1<<15); ++i) { circid = get_unique_circ_id_by_chan(chan1); if (circid == 0) { tt_int_op(i, OP_GT, (1<<14)); break; } tt_uint_op(circid, OP_LT, (1<<15)); tt_assert(! bitarray_is_set(ba, circid)); bitarray_set(ba, circid); channel_mark_circid_unusable(chan1, circid); } tt_int_op(i, OP_LT, (1<<15)); /* Make sure that being full on chan1 does not interfere with chan2 */ for (i = 0; i < 100; ++i) { circid = get_unique_circ_id_by_chan(chan2); tt_uint_op(circid, OP_GT, 0); tt_uint_op(circid, OP_LT, (1<<15)); channel_mark_circid_unusable(chan2, circid); } done: tor_free(chan1); tor_free(chan2); bitarray_free(ba); circuit_free_all(); }
static void test_buffer_pullup(void *arg) { buf_t *buf; char *stuff, *tmp; const char *cp; size_t sz; (void)arg; stuff = tor_malloc(16384); tmp = tor_malloc(16384); buf = buf_new_with_capacity(3000); /* rounds up to next power of 2. */ tt_assert(buf); tt_int_op(buf_get_default_chunk_size(buf), OP_EQ, 4096); tt_int_op(buf_get_total_allocation(), OP_EQ, 0); /* There are a bunch of cases for pullup. One is the trivial case. Let's mess around with an empty buffer. */ buf_pullup(buf, 16); buf_get_first_chunk_data(buf, &cp, &sz); tt_ptr_op(cp, OP_EQ, NULL); tt_uint_op(sz, OP_EQ, 0); /* Let's make sure nothing got allocated */ tt_int_op(buf_get_total_allocation(), OP_EQ, 0); /* Case 1: everything puts into the first chunk with some moving. */ /* Let's add some data. */ crypto_rand(stuff, 16384); write_to_buf(stuff, 3000, buf); write_to_buf(stuff+3000, 3000, buf); buf_get_first_chunk_data(buf, &cp, &sz); tt_ptr_op(cp, OP_NE, NULL); tt_int_op(sz, OP_LE, 4096); /* Make room for 3000 bytes in the first chunk, so that the pullup-move code * can get tested. */ tt_int_op(fetch_from_buf(tmp, 3000, buf), OP_EQ, 3000); tt_mem_op(tmp,OP_EQ, stuff, 3000); buf_pullup(buf, 2048); assert_buf_ok(buf); buf_get_first_chunk_data(buf, &cp, &sz); tt_ptr_op(cp, OP_NE, NULL); tt_int_op(sz, OP_GE, 2048); tt_mem_op(cp,OP_EQ, stuff+3000, 2048); tt_int_op(3000, OP_EQ, buf_datalen(buf)); tt_int_op(fetch_from_buf(tmp, 3000, buf), OP_EQ, 0); tt_mem_op(tmp,OP_EQ, stuff+3000, 2048); buf_free(buf); /* Now try the large-chunk case. */ buf = buf_new_with_capacity(3000); /* rounds up to next power of 2. */ write_to_buf(stuff, 4000, buf); write_to_buf(stuff+4000, 4000, buf); write_to_buf(stuff+8000, 4000, buf); write_to_buf(stuff+12000, 4000, buf); tt_int_op(buf_datalen(buf), OP_EQ, 16000); buf_get_first_chunk_data(buf, &cp, &sz); tt_ptr_op(cp, OP_NE, NULL); tt_int_op(sz, OP_LE, 4096); buf_pullup(buf, 12500); assert_buf_ok(buf); buf_get_first_chunk_data(buf, &cp, &sz); tt_ptr_op(cp, OP_NE, NULL); tt_int_op(sz, OP_GE, 12500); tt_mem_op(cp,OP_EQ, stuff, 12500); tt_int_op(buf_datalen(buf), OP_EQ, 16000); fetch_from_buf(tmp, 12400, buf); tt_mem_op(tmp,OP_EQ, stuff, 12400); tt_int_op(buf_datalen(buf), OP_EQ, 3600); fetch_from_buf(tmp, 3500, buf); tt_mem_op(tmp,OP_EQ, stuff+12400, 3500); fetch_from_buf(tmp, 100, buf); tt_mem_op(tmp,OP_EQ, stuff+15900, 10); buf_free(buf); /* Make sure that the pull-up-whole-buffer case works */ buf = buf_new_with_capacity(3000); /* rounds up to next power of 2. */ write_to_buf(stuff, 4000, buf); write_to_buf(stuff+4000, 4000, buf); fetch_from_buf(tmp, 100, buf); /* dump 100 bytes from first chunk */ buf_pullup(buf, 16000); /* Way too much. */ assert_buf_ok(buf); buf_get_first_chunk_data(buf, &cp, &sz); tt_ptr_op(cp, OP_NE, NULL); tt_int_op(sz, OP_EQ, 7900); tt_mem_op(cp,OP_EQ, stuff+100, 7900); buf_free(buf); buf = NULL; tt_int_op(buf_get_total_allocation(), OP_EQ, 0); done: buf_free(buf); tor_free(stuff); tor_free(tmp); }
/** More tests for parsing different kinds of microdescriptors, and getting * invalid digests trackd from them. */ static void test_md_parse(void *arg) { (void) arg; char *mem_op_hex_tmp = NULL; smartlist_t *invalid = smartlist_new(); smartlist_t *mds = microdescs_parse_from_string(MD_PARSE_TEST_DATA, NULL, 1, SAVED_NOWHERE, invalid); tt_int_op(smartlist_len(mds), OP_EQ, 11); tt_int_op(smartlist_len(invalid), OP_EQ, 4); test_memeq_hex(smartlist_get(invalid,0), "5d76bf1c6614e885614a1e0ad074e1ab" "4ea14655ebeefb1736a71b5ed8a15a51"); test_memeq_hex(smartlist_get(invalid,1), "2fde0ee3343669c2444cd9d53cbd39c6" "a7d1fc0513513e840ca7f6e68864b36c"); test_memeq_hex(smartlist_get(invalid,2), "20d1576c5ab11bbcff0dedb1db4a3cfc" "c8bc8dd839d8cbfef92d00a1a7d7b294"); test_memeq_hex(smartlist_get(invalid,3), "074770f394c73dbde7b44412e9692add" "691a478d4727f9804b77646c95420a96"); /* Spot-check the valid ones. */ const microdesc_t *md = smartlist_get(mds, 5); test_memeq_hex(md->digest, "54bb6d733ddeb375d2456c79ae103961" "da0cae29620375ac4cf13d54da4d92b3"); tt_int_op(md->last_listed, OP_EQ, 0); tt_int_op(md->saved_location, OP_EQ, SAVED_NOWHERE); tt_int_op(md->no_save, OP_EQ, 0); tt_uint_op(md->held_in_map, OP_EQ, 0); tt_uint_op(md->held_by_nodes, OP_EQ, 0); tt_assert(md->onion_curve25519_pkey); md = smartlist_get(mds, 6); test_memeq_hex(md->digest, "53f740bd222ab37f19f604b1d3759aa6" "5eff1fbce9ac254bd0fa50d4af9b1bae"); tt_assert(! md->exit_policy); md = smartlist_get(mds, 8); test_memeq_hex(md->digest, "a0a155562d8093d8fd0feb7b93b7226e" "17f056c2142aab7a4ea8c5867a0376d5"); tt_assert(md->onion_curve25519_pkey); md = smartlist_get(mds, 10); test_memeq_hex(md->digest, "409ebd87d23925a2732bd467a92813c9" "21ca378fcb9ca193d354c51550b6d5e9"); tt_assert(tor_addr_family(&md->ipv6_addr) == AF_INET6); tt_int_op(md->ipv6_orport, OP_EQ, 9090); done: SMARTLIST_FOREACH(mds, microdesc_t *, mdsc, microdesc_free(mdsc)); smartlist_free(mds); SMARTLIST_FOREACH(invalid, char *, cp, tor_free(cp)); smartlist_free(invalid); tor_free(mem_op_hex_tmp); }
static void test_crypto_ed25519_fuzz_donna(void *arg) { const unsigned iters = 1024; uint8_t msg[1024]; unsigned i; (void)arg; tt_uint_op(iters, OP_EQ, sizeof(msg)); crypto_rand((char*) msg, sizeof(msg)); /* Fuzz Ed25519-donna vs ref10, alternating the implementation used to * generate keys/sign per iteration. */ for (i = 0; i < iters; ++i) { const int use_donna = i & 1; uint8_t blinding[32]; curve25519_keypair_t ckp; ed25519_keypair_t kp, kp_blind, kp_curve25519; ed25519_public_key_t pk, pk_blind, pk_curve25519; ed25519_signature_t sig, sig_blind; int bit = 0; crypto_rand((char*) blinding, sizeof(blinding)); /* Impl. A: * 1. Generate a keypair. * 2. Blinded the keypair. * 3. Sign a message (unblinded). * 4. Sign a message (blinded). * 5. Generate a curve25519 keypair, and convert it to Ed25519. */ ed25519_set_impl_params(use_donna); tt_int_op(0, OP_EQ, ed25519_keypair_generate(&kp, i&1)); tt_int_op(0, OP_EQ, ed25519_keypair_blind(&kp_blind, &kp, blinding)); tt_int_op(0, OP_EQ, ed25519_sign(&sig, msg, i, &kp)); tt_int_op(0, OP_EQ, ed25519_sign(&sig_blind, msg, i, &kp_blind)); tt_int_op(0, OP_EQ, curve25519_keypair_generate(&ckp, i&1)); tt_int_op(0, OP_EQ, ed25519_keypair_from_curve25519_keypair( &kp_curve25519, &bit, &ckp)); /* Impl. B: * 1. Validate the public key by rederiving it. * 2. Validate the blinded public key by rederiving it. * 3. Validate the unblinded signature (and test a invalid signature). * 4. Validate the blinded signature. * 5. Validate the public key (from Curve25519) by rederiving it. */ ed25519_set_impl_params(!use_donna); tt_int_op(0, OP_EQ, ed25519_public_key_generate(&pk, &kp.seckey)); tt_mem_op(pk.pubkey, OP_EQ, kp.pubkey.pubkey, 32); tt_int_op(0, OP_EQ, ed25519_public_blind(&pk_blind, &kp.pubkey, blinding)); tt_mem_op(pk_blind.pubkey, OP_EQ, kp_blind.pubkey.pubkey, 32); tt_int_op(0, OP_EQ, ed25519_checksig(&sig, msg, i, &pk)); sig.sig[0] ^= 15; tt_int_op(-1, OP_EQ, ed25519_checksig(&sig, msg, sizeof(msg), &pk)); tt_int_op(0, OP_EQ, ed25519_checksig(&sig_blind, msg, i, &pk_blind)); tt_int_op(0, OP_EQ, ed25519_public_key_from_curve25519_public_key( &pk_curve25519, &ckp.pubkey, bit)); tt_mem_op(pk_curve25519.pubkey, OP_EQ, kp_curve25519.pubkey.pubkey, 32); } done: ; }
static void test_pt_parsing(void *arg) { char line[200]; transport_t *transport = NULL; tor_addr_t test_addr; managed_proxy_t *mp = tor_malloc_zero(sizeof(managed_proxy_t)); (void)arg; mp->conf_state = PT_PROTO_INFANT; mp->transports = smartlist_new(); /* incomplete cmethod */ strlcpy(line,"CMETHOD trebuchet",sizeof(line)); tt_int_op(parse_cmethod_line(line, mp), OP_LT, 0); reset_mp(mp); /* wrong proxy type */ strlcpy(line,"CMETHOD trebuchet dog 127.0.0.1:1999",sizeof(line)); tt_int_op(parse_cmethod_line(line, mp), OP_LT, 0); reset_mp(mp); /* wrong addrport */ strlcpy(line,"CMETHOD trebuchet socks4 abcd",sizeof(line)); tt_int_op(parse_cmethod_line(line, mp), OP_LT, 0); reset_mp(mp); /* correct line */ strlcpy(line,"CMETHOD trebuchet socks5 127.0.0.1:1999",sizeof(line)); tt_int_op(parse_cmethod_line(line, mp), OP_EQ, 0); tt_int_op(smartlist_len(mp->transports), OP_EQ, 1); transport = smartlist_get(mp->transports, 0); /* test registered address of transport */ tor_addr_parse(&test_addr, "127.0.0.1"); tt_assert(tor_addr_eq(&test_addr, &transport->addr)); /* test registered port of transport */ tt_uint_op(transport->port, OP_EQ, 1999); /* test registered SOCKS version of transport */ tt_int_op(transport->socks_version, OP_EQ, PROXY_SOCKS5); /* test registered name of transport */ tt_str_op(transport->name,OP_EQ, "trebuchet"); reset_mp(mp); /* incomplete smethod */ strlcpy(line,"SMETHOD trebuchet",sizeof(line)); tt_int_op(parse_smethod_line(line, mp), OP_LT, 0); reset_mp(mp); /* wrong addr type */ strlcpy(line,"SMETHOD trebuchet abcd",sizeof(line)); tt_int_op(parse_smethod_line(line, mp), OP_LT, 0); reset_mp(mp); /* cowwect */ strlcpy(line,"SMETHOD trebuchy 127.0.0.2:2999",sizeof(line)); tt_int_op(parse_smethod_line(line, mp), OP_EQ, 0); tt_int_op(smartlist_len(mp->transports), OP_EQ, 1); transport = smartlist_get(mp->transports, 0); /* test registered address of transport */ tor_addr_parse(&test_addr, "127.0.0.2"); tt_assert(tor_addr_eq(&test_addr, &transport->addr)); /* test registered port of transport */ tt_uint_op(transport->port, OP_EQ, 2999); /* test registered name of transport */ tt_str_op(transport->name,OP_EQ, "trebuchy"); reset_mp(mp); /* Include some arguments. Good ones. */ strlcpy(line,"SMETHOD trebuchet 127.0.0.1:9999 " "ARGS:counterweight=3,sling=snappy", sizeof(line)); tt_int_op(parse_smethod_line(line, mp), OP_EQ, 0); tt_int_op(1, OP_EQ, smartlist_len(mp->transports)); { const transport_t *transport_ = smartlist_get(mp->transports, 0); tt_assert(transport_); tt_str_op(transport_->name, OP_EQ, "trebuchet"); tt_int_op(transport_->port, OP_EQ, 9999); tt_str_op(fmt_addr(&transport_->addr), OP_EQ, "127.0.0.1"); tt_str_op(transport_->extra_info_args, OP_EQ, "counterweight=3,sling=snappy"); } reset_mp(mp); /* unsupported version */ strlcpy(line,"VERSION 666",sizeof(line)); tt_int_op(parse_version(line, mp), OP_LT, 0); /* incomplete VERSION */ strlcpy(line,"VERSION ",sizeof(line)); tt_int_op(parse_version(line, mp), OP_LT, 0); /* correct VERSION */ strlcpy(line,"VERSION 1",sizeof(line)); tt_int_op(parse_version(line, mp), OP_EQ, 0); done: reset_mp(mp); smartlist_free(mp->transports); tor_free(mp); }
void hs_helper_desc_equal(const hs_descriptor_t *desc1, const hs_descriptor_t *desc2) { /* Plaintext data section. */ tt_int_op(desc1->plaintext_data.version, OP_EQ, desc2->plaintext_data.version); tt_uint_op(desc1->plaintext_data.lifetime_sec, OP_EQ, desc2->plaintext_data.lifetime_sec); tt_assert(tor_cert_eq(desc1->plaintext_data.signing_key_cert, desc2->plaintext_data.signing_key_cert)); tt_mem_op(desc1->plaintext_data.signing_pubkey.pubkey, OP_EQ, desc2->plaintext_data.signing_pubkey.pubkey, ED25519_PUBKEY_LEN); tt_mem_op(desc1->plaintext_data.blinded_pubkey.pubkey, OP_EQ, desc2->plaintext_data.blinded_pubkey.pubkey, ED25519_PUBKEY_LEN); tt_u64_op(desc1->plaintext_data.revision_counter, ==, desc2->plaintext_data.revision_counter); /* NOTE: We can't compare the encrypted blob because when encoding the * descriptor, the object is immutable thus we don't update it with the * encrypted blob. As contrast to the decoding process where we populate a * descriptor object. */ /* Superencrypted data section. */ tt_mem_op(desc1->superencrypted_data.auth_ephemeral_pubkey.public_key, OP_EQ, desc2->superencrypted_data.auth_ephemeral_pubkey.public_key, CURVE25519_PUBKEY_LEN); /* Auth clients. */ { tt_assert(desc1->superencrypted_data.clients); tt_assert(desc2->superencrypted_data.clients); tt_int_op(smartlist_len(desc1->superencrypted_data.clients), ==, smartlist_len(desc2->superencrypted_data.clients)); for (int i=0; i < smartlist_len(desc1->superencrypted_data.clients); i++) { hs_desc_authorized_client_t *client1 = smartlist_get(desc1->superencrypted_data.clients, i), *client2 = smartlist_get(desc2->superencrypted_data.clients, i); tt_mem_op(client1->client_id, OP_EQ, client2->client_id, sizeof(client1->client_id)); tt_mem_op(client1->iv, OP_EQ, client2->iv, sizeof(client1->iv)); tt_mem_op(client1->encrypted_cookie, OP_EQ, client2->encrypted_cookie, sizeof(client1->encrypted_cookie)); } } /* Encrypted data section. */ tt_uint_op(desc1->encrypted_data.create2_ntor, ==, desc2->encrypted_data.create2_ntor); /* Authentication type. */ tt_int_op(!!desc1->encrypted_data.intro_auth_types, ==, !!desc2->encrypted_data.intro_auth_types); if (desc1->encrypted_data.intro_auth_types && desc2->encrypted_data.intro_auth_types) { tt_int_op(smartlist_len(desc1->encrypted_data.intro_auth_types), ==, smartlist_len(desc2->encrypted_data.intro_auth_types)); for (int i = 0; i < smartlist_len(desc1->encrypted_data.intro_auth_types); i++) { tt_str_op(smartlist_get(desc1->encrypted_data.intro_auth_types, i),OP_EQ, smartlist_get(desc2->encrypted_data.intro_auth_types, i)); } }
static void test_proto_var_cell(void *arg) { (void)arg; char *mem_op_hex_tmp = NULL; char tmp[1024]; buf_t *buf = NULL; var_cell_t *cell = NULL; buf = buf_new(); memset(tmp, 0xf0, sizeof(tmp)); /* Short little commands will make us say "no cell yet." */ tt_int_op(0, OP_EQ, fetch_var_cell_from_buf(buf, &cell, 4)); tt_ptr_op(cell, OP_EQ, NULL); buf_add(buf, "\x01\x02\x02\0x2", 4); tt_int_op(0, OP_EQ, fetch_var_cell_from_buf(buf, &cell, 4)); /* An incomplete fixed-length cell makes us say "no cell yet". */ buf_add(buf, "\x03", 1); tt_int_op(0, OP_EQ, fetch_var_cell_from_buf(buf, &cell, 4)); /* A complete fixed length-cell makes us say "not a variable-length cell" */ buf_add(buf, tmp, 509); tt_int_op(0, OP_EQ, fetch_var_cell_from_buf(buf, &cell, 4)); buf_clear(buf); /* An incomplete versions cell is a variable-length cell that isn't ready * yet. */ buf_add(buf, "\x01\x02\x03\x04" /* circid */ "\x07" /* VERSIONS */ "\x00\x04" /* 4 bytes long */ "\x00" /* incomplete */, 8); tt_int_op(1, OP_EQ, fetch_var_cell_from_buf(buf, &cell, 4)); tt_ptr_op(cell, OP_EQ, NULL); /* Complete it, and it's a variable-length cell. Leave a byte on the end for * fun. */ buf_add(buf, "\x09\x00\x25\ff", 4); tt_int_op(1, OP_EQ, fetch_var_cell_from_buf(buf, &cell, 4)); tt_ptr_op(cell, OP_NE, NULL); tt_int_op(cell->command, OP_EQ, CELL_VERSIONS); tt_uint_op(cell->circ_id, OP_EQ, 0x01020304); tt_int_op(cell->payload_len, OP_EQ, 4); test_mem_op_hex(cell->payload, OP_EQ, "00090025"); var_cell_free(cell); cell = NULL; tt_int_op(buf_datalen(buf), OP_EQ, 1); buf_clear(buf); /* In link protocol 3 and earlier, circid fields were two bytes long. Let's * ensure that gets handled correctly. */ buf_add(buf, "\x23\x45\x81\x00\x06" /* command 81; 6 bytes long */ "coraje", 11); tt_int_op(1, OP_EQ, fetch_var_cell_from_buf(buf, &cell, 3)); tt_ptr_op(cell, OP_NE, NULL); tt_int_op(cell->command, OP_EQ, 129); tt_uint_op(cell->circ_id, OP_EQ, 0x2345); tt_int_op(cell->payload_len, OP_EQ, 6); tt_mem_op(cell->payload, OP_EQ, "coraje", 6); var_cell_free(cell); cell = NULL; tt_int_op(buf_datalen(buf), OP_EQ, 0); /* In link protocol 2, only VERSIONS cells counted as variable-length */ buf_add(buf, "\x23\x45\x81\x00\x06" "coraje", 11); /* As above */ tt_int_op(0, OP_EQ, fetch_var_cell_from_buf(buf, &cell, 2)); buf_clear(buf); buf_add(buf, "\x23\x45\x07\x00\x06" "futuro", 11); tt_int_op(1, OP_EQ, fetch_var_cell_from_buf(buf, &cell, 2)); tt_ptr_op(cell, OP_NE, NULL); tt_int_op(cell->command, OP_EQ, 7); tt_uint_op(cell->circ_id, OP_EQ, 0x2345); tt_int_op(cell->payload_len, OP_EQ, 6); tt_mem_op(cell->payload, OP_EQ, "futuro", 6); var_cell_free(cell); cell = NULL; done: buf_free(buf); var_cell_free(cell); tor_free(mem_op_hex_tmp); }
static void test_routerkeys_ed_certs(void *args) { (void)args; ed25519_keypair_t kp1, kp2; tor_cert_t *cert[2] = {NULL, NULL}, *nocert = NULL; tor_cert_t *parsed_cert[2] = {NULL, NULL}; time_t now = 1412094534; uint8_t *junk = NULL; char *base64 = NULL; tt_int_op(0,OP_EQ,ed25519_keypair_generate(&kp1, 0)); tt_int_op(0,OP_EQ,ed25519_keypair_generate(&kp2, 0)); for (int i = 0; i <= 1; ++i) { uint32_t flags = i ? CERT_FLAG_INCLUDE_SIGNING_KEY : 0; cert[i] = tor_cert_create(&kp1, 5, &kp2.pubkey, now, 10000, flags); tt_assert(cert[i]); tt_uint_op(cert[i]->sig_bad, OP_EQ, 0); tt_uint_op(cert[i]->sig_ok, OP_EQ, 1); tt_uint_op(cert[i]->cert_expired, OP_EQ, 0); tt_uint_op(cert[i]->cert_valid, OP_EQ, 1); tt_int_op(cert[i]->cert_type, OP_EQ, 5); tt_mem_op(cert[i]->signed_key.pubkey, OP_EQ, &kp2.pubkey.pubkey, 32); tt_mem_op(cert[i]->signing_key.pubkey, OP_EQ, &kp1.pubkey.pubkey, 32); tt_int_op(cert[i]->signing_key_included, OP_EQ, i); tt_assert(cert[i]->encoded); tt_int_op(cert[i]->encoded_len, OP_EQ, 104 + 36 * i); tt_int_op(cert[i]->encoded[0], OP_EQ, 1); tt_int_op(cert[i]->encoded[1], OP_EQ, 5); parsed_cert[i] = tor_cert_parse(cert[i]->encoded, cert[i]->encoded_len); tt_assert(parsed_cert[i]); tt_int_op(cert[i]->encoded_len, OP_EQ, parsed_cert[i]->encoded_len); tt_mem_op(cert[i]->encoded, OP_EQ, parsed_cert[i]->encoded, cert[i]->encoded_len); tt_uint_op(parsed_cert[i]->sig_bad, OP_EQ, 0); tt_uint_op(parsed_cert[i]->sig_ok, OP_EQ, 0); tt_uint_op(parsed_cert[i]->cert_expired, OP_EQ, 0); tt_uint_op(parsed_cert[i]->cert_valid, OP_EQ, 0); /* Expired */ tt_int_op(tor_cert_checksig(parsed_cert[i], &kp1.pubkey, now + 30000), OP_LT, 0); tt_uint_op(parsed_cert[i]->cert_expired, OP_EQ, 1); parsed_cert[i]->cert_expired = 0; /* Wrong key */ tt_int_op(tor_cert_checksig(parsed_cert[i], &kp2.pubkey, now), OP_LT, 0); tt_uint_op(parsed_cert[i]->sig_bad, OP_EQ, 1); parsed_cert[i]->sig_bad = 0; /* Missing key */ int ok = tor_cert_checksig(parsed_cert[i], NULL, now); tt_int_op(ok < 0, OP_EQ, i == 0); tt_uint_op(parsed_cert[i]->sig_bad, OP_EQ, 0); tt_assert(parsed_cert[i]->sig_ok == (i != 0)); tt_assert(parsed_cert[i]->cert_valid == (i != 0)); parsed_cert[i]->sig_bad = 0; parsed_cert[i]->sig_ok = 0; parsed_cert[i]->cert_valid = 0; /* Right key */ tt_int_op(tor_cert_checksig(parsed_cert[i], &kp1.pubkey, now), OP_EQ, 0); tt_uint_op(parsed_cert[i]->sig_bad, OP_EQ, 0); tt_uint_op(parsed_cert[i]->sig_ok, OP_EQ, 1); tt_uint_op(parsed_cert[i]->cert_expired, OP_EQ, 0); tt_uint_op(parsed_cert[i]->cert_valid, OP_EQ, 1); } /* Now try some junky certs. */ /* - Truncated */ nocert = tor_cert_parse(cert[0]->encoded, cert[0]->encoded_len-1); tt_ptr_op(NULL, OP_EQ, nocert); /* - First byte modified */ cert[0]->encoded[0] = 99; nocert = tor_cert_parse(cert[0]->encoded, cert[0]->encoded_len); tt_ptr_op(NULL, OP_EQ, nocert); cert[0]->encoded[0] = 1; /* - Extra byte at the end*/ junk = tor_malloc_zero(cert[0]->encoded_len + 1); memcpy(junk, cert[0]->encoded, cert[0]->encoded_len); nocert = tor_cert_parse(junk, cert[0]->encoded_len+1); tt_ptr_op(NULL, OP_EQ, nocert); /* - Multiple signing key instances */ tor_free(junk); junk = tor_malloc_zero(104 + 36 * 2); junk[0] = 1; /* version */ junk[1] = 5; /* cert type */ junk[6] = 1; /* key type */ junk[39] = 2; /* n_extensions */ junk[41] = 32; /* extlen */ junk[42] = 4; /* exttype */ junk[77] = 32; /* extlen */ junk[78] = 4; /* exttype */ nocert = tor_cert_parse(junk, 104 + 36 * 2); tt_ptr_op(NULL, OP_EQ, nocert); done: tor_cert_free(cert[0]); tor_cert_free(cert[1]); tor_cert_free(parsed_cert[0]); tor_cert_free(parsed_cert[1]); tor_cert_free(nocert); tor_free(junk); tor_free(base64); }
/** Run unit tests for IPv6 encoding/decoding/manipulation functions. */ static void test_addr_ip6_helpers(void *arg) { char buf[TOR_ADDR_BUF_LEN], bug[TOR_ADDR_BUF_LEN]; char rbuf[REVERSE_LOOKUP_NAME_BUF_LEN]; struct in6_addr a1, a2; tor_addr_t t1, t2; int r, i; uint16_t port1, port2; maskbits_t mask; const char *p1; struct sockaddr_storage sa_storage; struct sockaddr_in *sin; struct sockaddr_in6 *sin6; /* Test tor_inet_ntop and tor_inet_pton: IPv6 */ (void)arg; { const char *ip = "2001::1234"; const char *ip_ffff = "::ffff:192.168.1.2"; /* good round trip */ tt_int_op(tor_inet_pton(AF_INET6, ip, &a1),OP_EQ, 1); tt_ptr_op(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)),OP_EQ, &buf); tt_str_op(buf,OP_EQ, ip); /* good round trip - ::ffff:0:0 style */ tt_int_op(tor_inet_pton(AF_INET6, ip_ffff, &a2),OP_EQ, 1); tt_ptr_op(tor_inet_ntop(AF_INET6, &a2, buf, sizeof(buf)),OP_EQ, &buf); tt_str_op(buf,OP_EQ, ip_ffff); /* just long enough buffer (remember \0) */ tt_str_op(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)+1),OP_EQ, ip); tt_str_op(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)+1),OP_EQ, ip_ffff); /* too short buffer (remember \0) */ tt_ptr_op(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)),OP_EQ, NULL); tt_ptr_op(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)),OP_EQ, NULL); } /* ==== Converting to and from sockaddr_t. */ sin = (struct sockaddr_in *)&sa_storage; sin->sin_family = AF_INET; sin->sin_port = htons(9090); sin->sin_addr.s_addr = htonl(0x7f7f0102); /*127.127.1.2*/ tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, &port1); tt_int_op(tor_addr_family(&t1),OP_EQ, AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ, 0x7f7f0102); tt_int_op(port1, OP_EQ, 9090); memset(&sa_storage, 0, sizeof(sa_storage)); tt_int_op(sizeof(struct sockaddr_in),OP_EQ, tor_addr_to_sockaddr(&t1, 1234, (struct sockaddr *)&sa_storage, sizeof(sa_storage))); tt_int_op(1234,OP_EQ, ntohs(sin->sin_port)); tt_int_op(0x7f7f0102,OP_EQ, ntohl(sin->sin_addr.s_addr)); memset(&sa_storage, 0, sizeof(sa_storage)); sin6 = (struct sockaddr_in6 *)&sa_storage; sin6->sin6_family = AF_INET6; sin6->sin6_port = htons(7070); sin6->sin6_addr.s6_addr[0] = 128; tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin6, &port1); tt_int_op(tor_addr_family(&t1),OP_EQ, AF_INET6); tt_int_op(port1, OP_EQ, 7070); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0); tt_str_op(p1,OP_EQ, "8000::"); memset(&sa_storage, 0, sizeof(sa_storage)); tt_int_op(sizeof(struct sockaddr_in6),OP_EQ, tor_addr_to_sockaddr(&t1, 9999, (struct sockaddr *)&sa_storage, sizeof(sa_storage))); tt_int_op(AF_INET6,OP_EQ, sin6->sin6_family); tt_int_op(9999,OP_EQ, ntohs(sin6->sin6_port)); tt_int_op(0x80000000,OP_EQ, ntohl(S6_ADDR32(sin6->sin6_addr)[0])); /* ==== tor_addr_lookup: static cases. (Can't test dns without knowing we * have a good resolver. */ tt_int_op(0,OP_EQ, tor_addr_lookup("127.128.129.130", AF_UNSPEC, &t1)); tt_int_op(AF_INET,OP_EQ, tor_addr_family(&t1)); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ, 0x7f808182); tt_int_op(0,OP_EQ, tor_addr_lookup("9000::5", AF_UNSPEC, &t1)); tt_int_op(AF_INET6,OP_EQ, tor_addr_family(&t1)); tt_int_op(0x90,OP_EQ, tor_addr_to_in6_addr8(&t1)[0]); tt_assert(tor_mem_is_zero((char*)tor_addr_to_in6_addr8(&t1)+1, 14)); tt_int_op(0x05,OP_EQ, tor_addr_to_in6_addr8(&t1)[15]); /* === Test pton: valid af_inet6 */ /* Simple, valid parsing. */ r = tor_inet_pton(AF_INET6, "0102:0304:0506:0708:090A:0B0C:0D0E:0F10", &a1); tt_int_op(r, OP_EQ, 1); for (i=0;i<16;++i) { tt_int_op(i+1,OP_EQ, (int)a1.s6_addr[i]); } /* ipv4 ending. */ test_pton6_same("0102:0304:0506:0708:090A:0B0C:0D0E:0F10", "0102:0304:0506:0708:090A:0B0C:13.14.15.16"); /* shortened words. */ test_pton6_same("0001:0099:BEEF:0000:0123:FFFF:0001:0001", "1:99:BEEF:0:0123:FFFF:1:1"); /* zeros at the beginning */ test_pton6_same("0000:0000:0000:0000:0009:C0A8:0001:0001", "::9:c0a8:1:1"); test_pton6_same("0000:0000:0000:0000:0009:C0A8:0001:0001", "::9:c0a8:0.1.0.1"); /* zeros in the middle. */ test_pton6_same("fe80:0000:0000:0000:0202:1111:0001:0001", "fe80::202:1111:1:1"); /* zeros at the end. */ test_pton6_same("1000:0001:0000:0007:0000:0000:0000:0000", "1000:1:0:7::"); /* === Test ntop: af_inet6 */ test_ntop6_reduces("0:0:0:0:0:0:0:0", "::"); test_ntop6_reduces("0001:0099:BEEF:0006:0123:FFFF:0001:0001", "1:99:beef:6:123:ffff:1:1"); //test_ntop6_reduces("0:0:0:0:0:0:c0a8:0101", "::192.168.1.1"); test_ntop6_reduces("0:0:0:0:0:ffff:c0a8:0101", "::ffff:192.168.1.1"); test_ntop6_reduces("0:0:0:0:0:0:c0a8:0101", "::192.168.1.1"); test_ntop6_reduces("002:0:0000:0:3::4", "2::3:0:0:4"); test_ntop6_reduces("0:0::1:0:3", "::1:0:3"); test_ntop6_reduces("008:0::0", "8::"); test_ntop6_reduces("0:0:0:0:0:ffff::1", "::ffff:0.0.0.1"); test_ntop6_reduces("abcd:0:0:0:0:0:7f00::", "abcd::7f00:0"); test_ntop6_reduces("0000:0000:0000:0000:0009:C0A8:0001:0001", "::9:c0a8:1:1"); test_ntop6_reduces("fe80:0000:0000:0000:0202:1111:0001:0001", "fe80::202:1111:1:1"); test_ntop6_reduces("1000:0001:0000:0007:0000:0000:0000:0000", "1000:1:0:7::"); /* Bad af param */ tt_int_op(tor_inet_pton(AF_UNSPEC, 0, 0),OP_EQ, -1); /* === Test pton: invalid in6. */ test_pton6_bad("foobar."); test_pton6_bad("-1::"); test_pton6_bad("00001::"); test_pton6_bad("10000::"); test_pton6_bad("::10000"); test_pton6_bad("55555::"); test_pton6_bad("9:-60::"); test_pton6_bad("9:+60::"); test_pton6_bad("9|60::"); test_pton6_bad("0x60::"); test_pton6_bad("::0x60"); test_pton6_bad("9:0x60::"); test_pton6_bad("1:2:33333:4:0002:3::"); test_pton6_bad("1:2:3333:4:fish:3::"); test_pton6_bad("1:2:3:4:5:6:7:8:9"); test_pton6_bad("1:2:3:4:5:6:7"); test_pton6_bad("1:2:3:4:5:6:1.2.3.4.5"); test_pton6_bad("1:2:3:4:5:6:1.2.3"); test_pton6_bad("::1.2.3"); test_pton6_bad("::1.2.3.4.5"); test_pton6_bad("::ffff:0xff.0.0.0"); test_pton6_bad("::ffff:ff.0.0.0"); test_pton6_bad("::ffff:256.0.0.0"); test_pton6_bad("::ffff:-1.0.0.0"); test_pton6_bad("99"); test_pton6_bad(""); test_pton6_bad("."); test_pton6_bad(":"); test_pton6_bad("1::2::3:4"); test_pton6_bad("a:::b:c"); test_pton6_bad(":::a:b:c"); test_pton6_bad("a:b:c:::"); test_pton6_bad("1.2.3.4"); test_pton6_bad(":1.2.3.4"); test_pton6_bad(".2.3.4"); /* Regression tests for 22789. */ test_pton6_bad("0xfoo"); test_pton6_bad("0x88"); test_pton6_bad("0xyxxy"); test_pton6_bad("0XFOO"); test_pton6_bad("0X88"); test_pton6_bad("0XYXXY"); test_pton6_bad("0x"); test_pton6_bad("0X"); /* test internal checking */ test_external_ip("fbff:ffff::2:7", 0); test_internal_ip("fc01::2:7", 0); test_internal_ip("fc01::02:7", 0); test_internal_ip("fc01::002:7", 0); test_internal_ip("fc01::0002:7", 0); test_internal_ip("fdff:ffff::f:f", 0); test_external_ip("fe00::3:f", 0); test_external_ip("fe7f:ffff::2:7", 0); test_internal_ip("fe80::2:7", 0); test_internal_ip("febf:ffff::f:f", 0); test_internal_ip("fec0::2:7:7", 0); test_internal_ip("feff:ffff::e:7:7", 0); test_external_ip("ff00::e:7:7", 0); test_internal_ip("::", 0); test_internal_ip("::1", 0); test_internal_ip("::1", 1); test_internal_ip("::", 0); test_external_ip("::", 1); test_external_ip("::2", 0); test_external_ip("2001::", 0); test_external_ip("ffff::", 0); test_external_ip("::ffff:0.0.0.0", 1); test_internal_ip("::ffff:0.0.0.0", 0); test_internal_ip("::ffff:0.255.255.255", 0); test_external_ip("::ffff:1.0.0.0", 0); test_external_ip("::ffff:9.255.255.255", 0); test_internal_ip("::ffff:10.0.0.0", 0); test_internal_ip("::ffff:10.255.255.255", 0); test_external_ip("::ffff:11.0.0.0", 0); test_external_ip("::ffff:126.255.255.255", 0); test_internal_ip("::ffff:127.0.0.0", 0); test_internal_ip("::ffff:127.255.255.255", 0); test_external_ip("::ffff:128.0.0.0", 0); test_external_ip("::ffff:172.15.255.255", 0); test_internal_ip("::ffff:172.16.0.0", 0); test_internal_ip("::ffff:172.31.255.255", 0); test_external_ip("::ffff:172.32.0.0", 0); test_external_ip("::ffff:192.167.255.255", 0); test_internal_ip("::ffff:192.168.0.0", 0); test_internal_ip("::ffff:192.168.255.255", 0); test_external_ip("::ffff:192.169.0.0", 0); test_external_ip("::ffff:169.253.255.255", 0); test_internal_ip("::ffff:169.254.0.0", 0); test_internal_ip("::ffff:169.254.255.255", 0); test_external_ip("::ffff:169.255.0.0", 0); /* tor_addr_compare(tor_addr_t x2) */ test_addr_compare("ffff::", OP_EQ, "ffff::0"); test_addr_compare("0::3:2:1", OP_LT, "0::ffff:0.3.2.1"); test_addr_compare("0::2:2:1", OP_LT, "0::ffff:0.3.2.1"); test_addr_compare("0::ffff:0.3.2.1", OP_GT, "0::0:0:0"); test_addr_compare("0::ffff:5.2.2.1", OP_LT, "::ffff:6.0.0.0"); /* XXXX wrong. */ tor_addr_parse_mask_ports("[::ffff:2.3.4.5]", 0, &t1, NULL, NULL, NULL); tor_addr_parse_mask_ports("2.3.4.5", 0, &t2, NULL, NULL, NULL); tt_int_op(tor_addr_compare(&t1, &t2, CMP_SEMANTIC), OP_EQ, 0); tor_addr_parse_mask_ports("[::ffff:2.3.4.4]", 0, &t1, NULL, NULL, NULL); tor_addr_parse_mask_ports("2.3.4.5", 0, &t2, NULL, NULL, NULL); tt_int_op(tor_addr_compare(&t1, &t2, CMP_SEMANTIC), OP_LT, 0); /* test compare_masked */ test_addr_compare_masked("ffff::", OP_EQ, "ffff::0", 128); test_addr_compare_masked("ffff::", OP_EQ, "ffff::0", 64); test_addr_compare_masked("0::2:2:1", OP_LT, "0::8000:2:1", 81); test_addr_compare_masked("0::2:2:1", OP_EQ, "0::8000:2:1", 80); /* Test undecorated tor_addr_to_str */ tt_int_op(AF_INET6,OP_EQ, tor_addr_parse(&t1, "[123:45:6789::5005:11]")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0); tt_str_op(p1,OP_EQ, "123:45:6789::5005:11"); tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&t1, "18.0.0.1")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0); tt_str_op(p1,OP_EQ, "18.0.0.1"); /* Test decorated tor_addr_to_str */ tt_int_op(AF_INET6,OP_EQ, tor_addr_parse(&t1, "[123:45:6789::5005:11]")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); tt_str_op(p1,OP_EQ, "[123:45:6789::5005:11]"); tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&t1, "18.0.0.1")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); tt_str_op(p1,OP_EQ, "18.0.0.1"); /* Test buffer bounds checking of tor_addr_to_str */ tt_int_op(AF_INET6,OP_EQ, tor_addr_parse(&t1, "::")); /* 2 + \0 */ tt_ptr_op(tor_addr_to_str(buf, &t1, 2, 0),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 3, 0),OP_EQ, "::"); tt_ptr_op(tor_addr_to_str(buf, &t1, 4, 1),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 5, 1),OP_EQ, "[::]"); tt_int_op(AF_INET6,OP_EQ, tor_addr_parse(&t1, "2000::1337")); /* 10 + \0 */ tt_ptr_op(tor_addr_to_str(buf, &t1, 10, 0),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 11, 0),OP_EQ, "2000::1337"); tt_ptr_op(tor_addr_to_str(buf, &t1, 12, 1),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 13, 1),OP_EQ, "[2000::1337]"); tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&t1, "1.2.3.4")); /* 7 + \0 */ tt_ptr_op(tor_addr_to_str(buf, &t1, 7, 0),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 8, 0),OP_EQ, "1.2.3.4"); tt_int_op(AF_INET, OP_EQ, tor_addr_parse(&t1, "255.255.255.255")); /* 15 + \0 */ tt_ptr_op(tor_addr_to_str(buf, &t1, 15, 0),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 16, 0),OP_EQ, "255.255.255.255"); tt_ptr_op(tor_addr_to_str(buf, &t1, 15, 1),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 16, 1),OP_EQ, "255.255.255.255"); t1.family = AF_UNSPEC; tt_ptr_op(tor_addr_to_str(buf, &t1, sizeof(buf), 0),OP_EQ, NULL); /* Test tor_addr_parse_PTR_name */ i = tor_addr_parse_PTR_name(&t1, "Foobar.baz", AF_UNSPEC, 0); tt_int_op(0,OP_EQ, i); i = tor_addr_parse_PTR_name(&t1, "Foobar.baz", AF_UNSPEC, 1); tt_int_op(0,OP_EQ, i); i = tor_addr_parse_PTR_name(&t1, "9999999999999999999999999999.in-addr.arpa", AF_UNSPEC, 1); tt_int_op(-1,OP_EQ, i); i = tor_addr_parse_PTR_name(&t1, "1.0.168.192.in-addr.arpa", AF_UNSPEC, 1); tt_int_op(1,OP_EQ, i); tt_int_op(tor_addr_family(&t1),OP_EQ, AF_INET); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); tt_str_op(p1,OP_EQ, "192.168.0.1"); i = tor_addr_parse_PTR_name(&t1, "192.168.0.99", AF_UNSPEC, 0); tt_int_op(0,OP_EQ, i); i = tor_addr_parse_PTR_name(&t1, "192.168.0.99", AF_UNSPEC, 1); tt_int_op(1,OP_EQ, i); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); tt_str_op(p1,OP_EQ, "192.168.0.99"); memset(&t1, 0, sizeof(t1)); i = tor_addr_parse_PTR_name(&t1, "0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); tt_int_op(1,OP_EQ, i); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); tt_str_op(p1,OP_EQ, "[9dee:effe:ebe1:beef:fedc:ba98:7654:3210]"); /* Failing cases. */ i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.f.0." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f.X.0.0.0.0.9." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, "32.1.1.in-addr.arpa", AF_UNSPEC, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, ".in-addr.arpa", AF_UNSPEC, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, "1.2.3.4.5.in-addr.arpa", AF_UNSPEC, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, "1.2.3.4.5.in-addr.arpa", AF_INET6, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.0." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_INET, 0); tt_int_op(i,OP_EQ, -1); /* === Test tor_addr_to_PTR_name */ /* Stage IPv4 addr */ memset(&sa_storage, 0, sizeof(sa_storage)); sin = (struct sockaddr_in *)&sa_storage; sin->sin_family = AF_INET; sin->sin_addr.s_addr = htonl(0x7f010203); /* 127.1.2.3 */ tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, NULL); /* Check IPv4 PTR - too short buffer */ tt_int_op(tor_addr_to_PTR_name(rbuf, 1, &t1),OP_EQ, -1); tt_int_op(tor_addr_to_PTR_name(rbuf, strlen("3.2.1.127.in-addr.arpa") - 1, &t1),OP_EQ, -1); /* Check IPv4 PTR - valid addr */ tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),OP_EQ, strlen("3.2.1.127.in-addr.arpa")); tt_str_op(rbuf,OP_EQ, "3.2.1.127.in-addr.arpa"); /* Invalid addr family */ t1.family = AF_UNSPEC; tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),OP_EQ, -1); /* Stage IPv6 addr */ memset(&sa_storage, 0, sizeof(sa_storage)); sin6 = (struct sockaddr_in6 *)&sa_storage; sin6->sin6_family = AF_INET6; sin6->sin6_addr.s6_addr[0] = 0x80; /* 8000::abcd */ sin6->sin6_addr.s6_addr[14] = 0xab; sin6->sin6_addr.s6_addr[15] = 0xcd; tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin6, NULL); { const char* addr_PTR = "d.c.b.a.0.0.0.0.0.0.0.0.0.0.0.0." "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.ip6.arpa"; /* Check IPv6 PTR - too short buffer */ tt_int_op(tor_addr_to_PTR_name(rbuf, 0, &t1),OP_EQ, -1); tt_int_op(tor_addr_to_PTR_name(rbuf, strlen(addr_PTR) - 1, &t1),OP_EQ, -1); /* Check IPv6 PTR - valid addr */ tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),OP_EQ, strlen(addr_PTR)); tt_str_op(rbuf,OP_EQ, addr_PTR); } /* XXXX turn this into a separate function; it's not all IPv6. */ /* test tor_addr_parse_mask_ports */ test_addr_mask_ports_parse("[::f]/17:47-95", AF_INET6, 0, 0, 0, 0x0000000f, 17, 47, 95); tt_str_op(p1,OP_EQ, "::f"); //test_addr_parse("[::fefe:4.1.1.7/120]:999-1000"); //test_addr_parse_check("::fefe:401:107", 120, 999, 1000); test_addr_mask_ports_parse("[::ffff:4.1.1.7]/120:443", AF_INET6, 0, 0, 0x0000ffff, 0x04010107, 120, 443, 443); tt_str_op(p1,OP_EQ, "::ffff:4.1.1.7"); test_addr_mask_ports_parse("[abcd:2::44a:0]:2-65000", AF_INET6, 0xabcd0002, 0, 0, 0x044a0000, 128, 2, 65000); tt_str_op(p1,OP_EQ, "abcd:2::44a:0"); /* Try some long addresses. */ r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:1111]", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, AF_INET6); r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:11111]", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:1111:1]", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports( "[ffff:1111:1111:1111:1111:1111:1111:ffff:" "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:" "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:" "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); /* Try some failing cases. */ r=tor_addr_parse_mask_ports("[fefef::]/112", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[fefe::/112", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[fefe::", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[fefe::X]", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("efef::/112", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f::]",0,&t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[::f:f:f:f:f:f:f:f]",0,&t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f:f]",0,&t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f::]/fred",0,&t1,&mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f::]/255.255.0.0", 0,&t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); /* This one will get rejected because it isn't a pure prefix. */ r=tor_addr_parse_mask_ports("1.1.2.3/255.255.64.0",0,&t1, &mask,NULL,NULL); tt_int_op(r, OP_EQ, -1); /* Test for V4-mapped address with mask < 96. (arguably not valid) */ r=tor_addr_parse_mask_ports("[::ffff:1.1.2.2/33]",0,&t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("1.1.2.2/33",0,&t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); /* Try extended wildcard addresses with out TAPMP_EXTENDED_STAR*/ r=tor_addr_parse_mask_ports("*4",0,&t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("*6",0,&t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); tt_int_op(r, OP_EQ, -1); /* Try a mask with a wildcard. */ r=tor_addr_parse_mask_ports("*/16",0,&t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("*4/16",TAPMP_EXTENDED_STAR, &t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("*6/30",TAPMP_EXTENDED_STAR, &t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); /* Basic mask tests*/ r=tor_addr_parse_mask_ports("1.1.2.2/31",0,&t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, AF_INET); tt_int_op(mask,OP_EQ,31); tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0x01010202); r=tor_addr_parse_mask_ports("3.4.16.032:1-2",0,&t1, &mask, &port1, &port2); tt_int_op(r, OP_EQ, AF_INET); tt_int_op(mask,OP_EQ,32); tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0x03041020); tt_uint_op(port1, OP_EQ, 1); tt_uint_op(port2, OP_EQ, 2); r=tor_addr_parse_mask_ports("1.1.2.3/255.255.128.0",0,&t1, &mask,NULL,NULL); tt_int_op(r, OP_EQ, AF_INET); tt_int_op(mask,OP_EQ,17); tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0x01010203); r=tor_addr_parse_mask_ports("[efef::]/112",0,&t1, &mask, &port1, &port2); tt_int_op(r, OP_EQ, AF_INET6); tt_uint_op(port1, OP_EQ, 1); tt_uint_op(port2, OP_EQ, 65535); /* Try regular wildcard behavior without TAPMP_EXTENDED_STAR */ r=tor_addr_parse_mask_ports("*:80-443",0,&t1,&mask,&port1,&port2); tt_int_op(r,OP_EQ,AF_INET); /* Old users of this always get inet */ tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0); tt_int_op(mask,OP_EQ,0); tt_int_op(port1,OP_EQ,80); tt_int_op(port2,OP_EQ,443); /* Now try wildcards *with* TAPMP_EXTENDED_STAR */ r=tor_addr_parse_mask_ports("*:8000-9000",TAPMP_EXTENDED_STAR, &t1,&mask,&port1,&port2); tt_int_op(r,OP_EQ,AF_UNSPEC); tt_int_op(tor_addr_family(&t1),OP_EQ,AF_UNSPEC); tt_int_op(mask,OP_EQ,0); tt_int_op(port1,OP_EQ,8000); tt_int_op(port2,OP_EQ,9000); r=tor_addr_parse_mask_ports("*4:6667",TAPMP_EXTENDED_STAR, &t1,&mask,&port1,&port2); tt_int_op(r,OP_EQ,AF_INET); tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0); tt_int_op(mask,OP_EQ,0); tt_int_op(port1,OP_EQ,6667); tt_int_op(port2,OP_EQ,6667); r=tor_addr_parse_mask_ports("*6",TAPMP_EXTENDED_STAR, &t1,&mask,&port1,&port2); tt_int_op(r,OP_EQ,AF_INET6); tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET6); tt_assert(tor_mem_is_zero((const char*)tor_addr_to_in6_addr32(&t1), 16)); tt_int_op(mask,OP_EQ,0); tt_int_op(port1,OP_EQ,1); tt_int_op(port2,OP_EQ,65535); /* make sure inet address lengths >= max */ tt_int_op(INET_NTOA_BUF_LEN, OP_GE, sizeof("255.255.255.255")); tt_int_op(TOR_ADDR_BUF_LEN, OP_GE, sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")); tt_assert(sizeof(tor_addr_t) >= sizeof(struct in6_addr)); /* get interface addresses */ r = get_interface_address6(LOG_DEBUG, AF_INET, &t1); tt_int_op(r, OP_LE, 0); // "it worked or it didn't" i = get_interface_address6(LOG_DEBUG, AF_INET6, &t2); tt_int_op(i, OP_LE, 0); // "it worked or it didn't" TT_BLATHER(("v4 address: %s (family=%d)", fmt_addr(&t1), tor_addr_family(&t1))); TT_BLATHER(("v6 address: %s (family=%d)", fmt_addr(&t2), tor_addr_family(&t2))); done: ; }