test.c
上传用户:awang829
上传日期:2019-07-14
资源大小:2356k
文件大小:163k
- /* Copyright (c) 2001-2004, Roger Dingledine.
- * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2009, The Tor Project, Inc. */
- /* See LICENSE for licensing information */
- /* Ordinarily defined in tor_main.c; this bit is just here to provide one
- * since we're not linking to tor_main.c */
- const char tor_svn_revision[] = "";
- /**
- * file test.c
- * brief Unit tests for many pieces of the lower level Tor modules.
- **/
- #include "orconfig.h"
- #include <stdio.h>
- #ifdef HAVE_FCNTL_H
- #include <fcntl.h>
- #endif
- #ifdef MS_WINDOWS
- /* For mkdir() */
- #include <direct.h>
- #else
- #include <dirent.h>
- #endif
- /* These macros pull in declarations for some functions and structures that
- * are typically file-private. */
- #define BUFFERS_PRIVATE
- #define CONFIG_PRIVATE
- #define CONTROL_PRIVATE
- #define CRYPTO_PRIVATE
- #define DIRSERV_PRIVATE
- #define DIRVOTE_PRIVATE
- #define GEOIP_PRIVATE
- #define MEMPOOL_PRIVATE
- #define ROUTER_PRIVATE
- #include "or.h"
- #include "test.h"
- #include "torgzip.h"
- #include "mempool.h"
- #include "memarea.h"
- #ifdef USE_DMALLOC
- #include <dmalloc.h>
- #include <openssl/crypto.h>
- #endif
- /** Set to true if any unit test has failed. Mostly, this is set by the macros
- * in test.h */
- int have_failed = 0;
- /** Temporary directory (set up by setup_directory) under which we store all
- * our files during testing. */
- static char temp_dir[256];
- /** Select and create the temporary directory we'll use to run our unit tests.
- * Store it in <b>temp_dir</b>. Exit immediately if we can't create it.
- * idempotent. */
- static void
- setup_directory(void)
- {
- static int is_setup = 0;
- int r;
- if (is_setup) return;
- #ifdef MS_WINDOWS
- // XXXX
- tor_snprintf(temp_dir, sizeof(temp_dir),
- "c:\windows\temp\tor_test_%d", (int)getpid());
- r = mkdir(temp_dir);
- #else
- tor_snprintf(temp_dir, sizeof(temp_dir), "/tmp/tor_test_%d", (int) getpid());
- r = mkdir(temp_dir, 0700);
- #endif
- if (r) {
- fprintf(stderr, "Can't create directory %s:", temp_dir);
- perror("");
- exit(1);
- }
- is_setup = 1;
- }
- /** Return a filename relative to our testing temporary directory */
- static const char *
- get_fname(const char *name)
- {
- static char buf[1024];
- setup_directory();
- tor_snprintf(buf,sizeof(buf),"%s/%s",temp_dir,name);
- return buf;
- }
- /** Remove all files stored under the temporary directory, and the directory
- * itself. */
- static void
- remove_directory(void)
- {
- smartlist_t *elements = tor_listdir(temp_dir);
- if (elements) {
- SMARTLIST_FOREACH(elements, const char *, cp,
- {
- size_t len = strlen(cp)+strlen(temp_dir)+16;
- char *tmp = tor_malloc(len);
- tor_snprintf(tmp, len, "%s"PATH_SEPARATOR"%s", temp_dir, cp);
- unlink(tmp);
- tor_free(tmp);
- });
- SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
- smartlist_free(elements);
- }
- rmdir(temp_dir);
- }
- /** Define this if unit tests spend too much time generating public keys*/
- #undef CACHE_GENERATED_KEYS
- static crypto_pk_env_t *pregen_keys[5] = {NULL, NULL, NULL, NULL, NULL};
- #define N_PREGEN_KEYS ((int)(sizeof(pregen_keys)/sizeof(pregen_keys[0])))
- /** Generate and return a new keypair for use in unit tests. If we're using
- * the key cache optimization, we might reuse keys: we only guarantee that
- * keys made with distinct values for <b>idx</b> are different. The value of
- * <b>idx</b> must be at least 0, and less than N_PREGEN_KEYS. */
- static crypto_pk_env_t *
- pk_generate(int idx)
- {
- #ifdef CACHE_GENERATED_KEYS
- tor_assert(idx < N_PREGEN_KEYS);
- if (! pregen_keys[idx]) {
- pregen_keys[idx] = crypto_new_pk_env();
- tor_assert(!crypto_pk_generate_key(pregen_keys[idx]));
- }
- return crypto_pk_dup_key(pregen_keys[idx]);
- #else
- crypto_pk_env_t *result;
- (void) idx;
- result = crypto_new_pk_env();
- tor_assert(!crypto_pk_generate_key(result));
- return result;
- #endif
- }
- /** Free all storage used for the cached key optimization. */
- static void
- free_pregenerated_keys(void)
- {
- unsigned idx;
- for (idx = 0; idx < N_PREGEN_KEYS; ++idx) {
- if (pregen_keys[idx]) {
- crypto_free_pk_env(pregen_keys[idx]);
- pregen_keys[idx] = NULL;
- }
- }
- }
- /** Run unit tests for buffers.c */
- static void
- test_buffers(void)
- {
- char str[256];
- char str2[256];
- buf_t *buf = NULL, *buf2 = NULL;
- const char *cp;
- int j;
- size_t r;
- /****
- * buf_new
- ****/
- if (!(buf = buf_new()))
- test_fail();
- //test_eq(buf_capacity(buf), 4096);
- test_eq(buf_datalen(buf), 0);
- /****
- * General pointer frobbing
- */
- for (j=0;j<256;++j) {
- str[j] = (char)j;
- }
- write_to_buf(str, 256, buf);
- write_to_buf(str, 256, buf);
- test_eq(buf_datalen(buf), 512);
- fetch_from_buf(str2, 200, buf);
- test_memeq(str, str2, 200);
- test_eq(buf_datalen(buf), 312);
- memset(str2, 0, sizeof(str2));
- fetch_from_buf(str2, 256, buf);
- test_memeq(str+200, str2, 56);
- test_memeq(str, str2+56, 200);
- test_eq(buf_datalen(buf), 56);
- memset(str2, 0, sizeof(str2));
- /* Okay, now we should be 512 bytes into the 4096-byte buffer. If we add
- * another 3584 bytes, we hit the end. */
- for (j=0;j<15;++j) {
- write_to_buf(str, 256, buf);
- }
- assert_buf_ok(buf);
- test_eq(buf_datalen(buf), 3896);
- fetch_from_buf(str2, 56, buf);
- test_eq(buf_datalen(buf), 3840);
- test_memeq(str+200, str2, 56);
- for (j=0;j<15;++j) {
- memset(str2, 0, sizeof(str2));
- fetch_from_buf(str2, 256, buf);
- test_memeq(str, str2, 256);
- }
- test_eq(buf_datalen(buf), 0);
- buf_free(buf);
- buf = NULL;
- /* Okay, now make sure growing can work. */
- buf = buf_new_with_capacity(16);
- //test_eq(buf_capacity(buf), 16);
- write_to_buf(str+1, 255, buf);
- //test_eq(buf_capacity(buf), 256);
- fetch_from_buf(str2, 254, buf);
- test_memeq(str+1, str2, 254);
- //test_eq(buf_capacity(buf), 256);
- assert_buf_ok(buf);
- write_to_buf(str, 32, buf);
- //test_eq(buf_capacity(buf), 256);
- assert_buf_ok(buf);
- write_to_buf(str, 256, buf);
- assert_buf_ok(buf);
- //test_eq(buf_capacity(buf), 512);
- test_eq(buf_datalen(buf), 33+256);
- fetch_from_buf(str2, 33, buf);
- test_eq(*str2, str[255]);
- test_memeq(str2+1, str, 32);
- //test_eq(buf_capacity(buf), 512);
- test_eq(buf_datalen(buf), 256);
- fetch_from_buf(str2, 256, buf);
- test_memeq(str, str2, 256);
- /* now try shrinking: case 1. */
- buf_free(buf);
- buf = buf_new_with_capacity(33668);
- for (j=0;j<67;++j) {
- write_to_buf(str,255, buf);
- }
- //test_eq(buf_capacity(buf), 33668);
- test_eq(buf_datalen(buf), 17085);
- for (j=0; j < 40; ++j) {
- fetch_from_buf(str2, 255,buf);
- test_memeq(str2, str, 255);
- }
- /* now try shrinking: case 2. */
- buf_free(buf);
- buf = buf_new_with_capacity(33668);
- for (j=0;j<67;++j) {
- write_to_buf(str,255, buf);
- }
- for (j=0; j < 20; ++j) {
- fetch_from_buf(str2, 255,buf);
- test_memeq(str2, str, 255);
- }
- for (j=0;j<80;++j) {
- write_to_buf(str,255, buf);
- }
- //test_eq(buf_capacity(buf),33668);
- for (j=0; j < 120; ++j) {
- fetch_from_buf(str2, 255,buf);
- test_memeq(str2, str, 255);
- }
- /* Move from buf to buf. */
- buf_free(buf);
- buf = buf_new_with_capacity(4096);
- buf2 = buf_new_with_capacity(4096);
- for (j=0;j<100;++j)
- write_to_buf(str, 255, buf);
- test_eq(buf_datalen(buf), 25500);
- for (j=0;j<100;++j) {
- r = 10;
- move_buf_to_buf(buf2, buf, &r);
- test_eq(r, 0);
- }
- test_eq(buf_datalen(buf), 24500);
- test_eq(buf_datalen(buf2), 1000);
- for (j=0;j<3;++j) {
- fetch_from_buf(str2, 255, buf2);
- test_memeq(str2, str, 255);
- }
- r = 8192; /*big move*/
- move_buf_to_buf(buf2, buf, &r);
- test_eq(r, 0);
- r = 30000; /* incomplete move */
- move_buf_to_buf(buf2, buf, &r);
- test_eq(r, 13692);
- for (j=0;j<97;++j) {
- fetch_from_buf(str2, 255, buf2);
- test_memeq(str2, str, 255);
- }
- buf_free(buf);
- buf_free(buf2);
- buf = buf2 = NULL;
- buf = buf_new_with_capacity(5);
- cp = "Testing. This is a moderately long Testing string.";
- for (j = 0; cp[j]; j++)
- write_to_buf(cp+j, 1, buf);
- test_eq(0, buf_find_string_offset(buf, "Testing", 7));
- test_eq(1, buf_find_string_offset(buf, "esting", 6));
- test_eq(1, buf_find_string_offset(buf, "est", 3));
- test_eq(39, buf_find_string_offset(buf, "ing str", 7));
- test_eq(35, buf_find_string_offset(buf, "Testing str", 11));
- test_eq(32, buf_find_string_offset(buf, "ng ", 3));
- test_eq(43, buf_find_string_offset(buf, "string.", 7));
- test_eq(-1, buf_find_string_offset(buf, "shrdlu", 6));
- test_eq(-1, buf_find_string_offset(buf, "Testing thing", 13));
- test_eq(-1, buf_find_string_offset(buf, "ngx", 3));
- buf_free(buf);
- buf = NULL;
- #if 0
- {
- int s;
- int eof;
- int i;
- buf_t *buf2;
- /****
- * read_to_buf
- ****/
- s = open(get_fname("data"), O_WRONLY|O_CREAT|O_TRUNC, 0600);
- write(s, str, 256);
- close(s);
- s = open(get_fname("data"), O_RDONLY, 0);
- eof = 0;
- errno = 0; /* XXXX */
- i = read_to_buf(s, 10, buf, &eof);
- printf("%sn", strerror(errno));
- test_eq(i, 10);
- test_eq(eof, 0);
- //test_eq(buf_capacity(buf), 4096);
- test_eq(buf_datalen(buf), 10);
- test_memeq(str, (char*)_buf_peek_raw_buffer(buf), 10);
- /* Test reading 0 bytes. */
- i = read_to_buf(s, 0, buf, &eof);
- //test_eq(buf_capacity(buf), 512*1024);
- test_eq(buf_datalen(buf), 10);
- test_eq(eof, 0);
- test_eq(i, 0);
- /* Now test when buffer is filled exactly. */
- buf2 = buf_new_with_capacity(6);
- i = read_to_buf(s, 6, buf2, &eof);
- //test_eq(buf_capacity(buf2), 6);
- test_eq(buf_datalen(buf2), 6);
- test_eq(eof, 0);
- test_eq(i, 6);
- test_memeq(str+10, (char*)_buf_peek_raw_buffer(buf2), 6);
- buf_free(buf2);
- buf2 = NULL;
- /* Now test when buffer is filled with more data to read. */
- buf2 = buf_new_with_capacity(32);
- i = read_to_buf(s, 128, buf2, &eof);
- //test_eq(buf_capacity(buf2), 128);
- test_eq(buf_datalen(buf2), 32);
- test_eq(eof, 0);
- test_eq(i, 32);
- buf_free(buf2);
- buf2 = NULL;
- /* Now read to eof. */
- test_assert(buf_capacity(buf) > 256);
- i = read_to_buf(s, 1024, buf, &eof);
- test_eq(i, (256-32-10-6));
- test_eq(buf_capacity(buf), MAX_BUF_SIZE);
- test_eq(buf_datalen(buf), 256-6-32);
- test_memeq(str, (char*)_buf_peek_raw_buffer(buf), 10); /* XXX Check rest. */
- test_eq(eof, 0);
- i = read_to_buf(s, 1024, buf, &eof);
- test_eq(i, 0);
- test_eq(buf_capacity(buf), MAX_BUF_SIZE);
- test_eq(buf_datalen(buf), 256-6-32);
- test_eq(eof, 1);
- }
- #endif
- done:
- if (buf)
- buf_free(buf);
- if (buf2)
- buf_free(buf2);
- }
- /** Run unit tests for Diffie-Hellman functionality. */
- static void
- test_crypto_dh(void)
- {
- crypto_dh_env_t *dh1 = crypto_dh_new();
- crypto_dh_env_t *dh2 = crypto_dh_new();
- char p1[DH_BYTES];
- char p2[DH_BYTES];
- char s1[DH_BYTES];
- char s2[DH_BYTES];
- ssize_t s1len, s2len;
- test_eq(crypto_dh_get_bytes(dh1), DH_BYTES);
- test_eq(crypto_dh_get_bytes(dh2), DH_BYTES);
- memset(p1, 0, DH_BYTES);
- memset(p2, 0, DH_BYTES);
- test_memeq(p1, p2, DH_BYTES);
- test_assert(! crypto_dh_get_public(dh1, p1, DH_BYTES));
- test_memneq(p1, p2, DH_BYTES);
- test_assert(! crypto_dh_get_public(dh2, p2, DH_BYTES));
- test_memneq(p1, p2, DH_BYTES);
- memset(s1, 0, DH_BYTES);
- memset(s2, 0xFF, DH_BYTES);
- s1len = crypto_dh_compute_secret(dh1, p2, DH_BYTES, s1, 50);
- s2len = crypto_dh_compute_secret(dh2, p1, DH_BYTES, s2, 50);
- test_assert(s1len > 0);
- test_eq(s1len, s2len);
- test_memeq(s1, s2, s1len);
- {
- /* XXXX Now fabricate some bad values and make sure they get caught,
- * Check 0, 1, N-1, >= N, etc.
- */
- }
- done:
- crypto_dh_free(dh1);
- crypto_dh_free(dh2);
- }
- /** Run unit tests for our random number generation function and its wrappers.
- */
- static void
- test_crypto_rng(void)
- {
- int i, j, allok;
- char data1[100], data2[100];
- /* Try out RNG. */
- test_assert(! crypto_seed_rng(0));
- crypto_rand(data1, 100);
- crypto_rand(data2, 100);
- test_memneq(data1,data2,100);
- allok = 1;
- for (i = 0; i < 100; ++i) {
- uint64_t big;
- char *host;
- j = crypto_rand_int(100);
- if (i < 0 || i >= 100)
- allok = 0;
- big = crypto_rand_uint64(U64_LITERAL(1)<<40);
- if (big >= (U64_LITERAL(1)<<40))
- allok = 0;
- big = crypto_rand_uint64(U64_LITERAL(5));
- if (big >= 5)
- allok = 0;
- host = crypto_random_hostname(3,8,"www.",".onion");
- if (strcmpstart(host,"www.") ||
- strcmpend(host,".onion") ||
- strlen(host) < 13 ||
- strlen(host) > 18)
- allok = 0;
- tor_free(host);
- }
- test_assert(allok);
- done:
- ;
- }
- /** Run unit tests for our AES functionality */
- static void
- test_crypto_aes(void)
- {
- char *data1 = NULL, *data2 = NULL, *data3 = NULL;
- crypto_cipher_env_t *env1 = NULL, *env2 = NULL;
- int i, j;
- data1 = tor_malloc(1024);
- data2 = tor_malloc(1024);
- data3 = tor_malloc(1024);
- /* Now, test encryption and decryption with stream cipher. */
- data1[0]=' ';
- for (i = 1023; i>0; i -= 35)
- strncat(data1, "Now is the time for all good onions", i);
- memset(data2, 0, 1024);
- memset(data3, 0, 1024);
- env1 = crypto_new_cipher_env();
- test_neq(env1, 0);
- env2 = crypto_new_cipher_env();
- test_neq(env2, 0);
- j = crypto_cipher_generate_key(env1);
- crypto_cipher_set_key(env2, crypto_cipher_get_key(env1));
- crypto_cipher_encrypt_init_cipher(env1);
- crypto_cipher_decrypt_init_cipher(env2);
- /* Try encrypting 512 chars. */
- crypto_cipher_encrypt(env1, data2, data1, 512);
- crypto_cipher_decrypt(env2, data3, data2, 512);
- test_memeq(data1, data3, 512);
- test_memneq(data1, data2, 512);
- /* Now encrypt 1 at a time, and get 1 at a time. */
- for (j = 512; j < 560; ++j) {
- crypto_cipher_encrypt(env1, data2+j, data1+j, 1);
- }
- for (j = 512; j < 560; ++j) {
- crypto_cipher_decrypt(env2, data3+j, data2+j, 1);
- }
- test_memeq(data1, data3, 560);
- /* Now encrypt 3 at a time, and get 5 at a time. */
- for (j = 560; j < 1024-5; j += 3) {
- crypto_cipher_encrypt(env1, data2+j, data1+j, 3);
- }
- for (j = 560; j < 1024-5; j += 5) {
- crypto_cipher_decrypt(env2, data3+j, data2+j, 5);
- }
- test_memeq(data1, data3, 1024-5);
- /* Now make sure that when we encrypt with different chunk sizes, we get
- the same results. */
- crypto_free_cipher_env(env2);
- env2 = NULL;
- memset(data3, 0, 1024);
- env2 = crypto_new_cipher_env();
- test_neq(env2, 0);
- crypto_cipher_set_key(env2, crypto_cipher_get_key(env1));
- crypto_cipher_encrypt_init_cipher(env2);
- for (j = 0; j < 1024-16; j += 17) {
- crypto_cipher_encrypt(env2, data3+j, data1+j, 17);
- }
- for (j= 0; j < 1024-16; ++j) {
- if (data2[j] != data3[j]) {
- printf("%d: %dt%dn", j, (int) data2[j], (int) data3[j]);
- }
- }
- test_memeq(data2, data3, 1024-16);
- crypto_free_cipher_env(env1);
- env1 = NULL;
- crypto_free_cipher_env(env2);
- env2 = NULL;
- /* NIST test vector for aes. */
- env1 = crypto_new_cipher_env(); /* IV starts at 0 */
- crypto_cipher_set_key(env1, "x80x00x00x00x00x00x00x00"
- "x00x00x00x00x00x00x00x00");
- crypto_cipher_encrypt_init_cipher(env1);
- crypto_cipher_encrypt(env1, data1,
- "x00x00x00x00x00x00x00x00"
- "x00x00x00x00x00x00x00x00", 16);
- test_memeq_hex(data1, "0EDD33D3C621E546455BD8BA1418BEC8");
- /* Now test rollover. All these values are originally from a python
- * script. */
- crypto_cipher_set_iv(env1, "x00x00x00x00x00x00x00x00"
- "xffxffxffxffxffxffxffxff");
- memset(data2, 0, 1024);
- crypto_cipher_encrypt(env1, data1, data2, 32);
- test_memeq_hex(data1, "335fe6da56f843199066c14a00a40231"
- "cdd0b917dbc7186908a6bfb5ffd574d3");
- crypto_cipher_set_iv(env1, "x00x00x00x00xffxffxffxff"
- "xffxffxffxffxffxffxffxff");
- memset(data2, 0, 1024);
- crypto_cipher_encrypt(env1, data1, data2, 32);
- test_memeq_hex(data1, "e627c6423fa2d77832a02b2794094b73"
- "3e63c721df790d2c6469cc1953a3ffac");
- crypto_cipher_set_iv(env1, "xffxffxffxffxffxffxffxff"
- "xffxffxffxffxffxffxffxff");
- memset(data2, 0, 1024);
- crypto_cipher_encrypt(env1, data1, data2, 32);
- test_memeq_hex(data1, "2aed2bff0de54f9328efd070bf48f70a"
- "0EDD33D3C621E546455BD8BA1418BEC8");
- /* Now check rollover on inplace cipher. */
- crypto_cipher_set_iv(env1, "xffxffxffxffxffxffxffxff"
- "xffxffxffxffxffxffxffxff");
- crypto_cipher_crypt_inplace(env1, data2, 64);
- test_memeq_hex(data2, "2aed2bff0de54f9328efd070bf48f70a"
- "0EDD33D3C621E546455BD8BA1418BEC8"
- "93e2c5243d6839eac58503919192f7ae"
- "1908e67cafa08d508816659c2e693191");
- crypto_cipher_set_iv(env1, "xffxffxffxffxffxffxffxff"
- "xffxffxffxffxffxffxffxff");
- crypto_cipher_crypt_inplace(env1, data2, 64);
- test_assert(tor_mem_is_zero(data2, 64));
- done:
- if (env1)
- crypto_free_cipher_env(env1);
- if (env2)
- crypto_free_cipher_env(env2);
- tor_free(data1);
- tor_free(data2);
- tor_free(data3);
- }
- /** Run unit tests for our SHA-1 functionality */
- static void
- test_crypto_sha(void)
- {
- crypto_digest_env_t *d1 = NULL, *d2 = NULL;
- int i;
- char key[80];
- char digest[20];
- char data[50];
- char d_out1[DIGEST_LEN], d_out2[DIGEST_LEN];
- /* Test SHA-1 with a test vector from the specification. */
- i = crypto_digest(data, "abc", 3);
- test_memeq_hex(data, "A9993E364706816ABA3E25717850C26C9CD0D89D");
- /* Test HMAC-SHA-1 with test cases from RFC2202. */
- /* Case 1. */
- memset(key, 0x0b, 20);
- crypto_hmac_sha1(digest, key, 20, "Hi There", 8);
- test_streq(hex_str(digest, 20),
- "B617318655057264E28BC0B6FB378C8EF146BE00");
- /* Case 2. */
- crypto_hmac_sha1(digest, "Jefe", 4, "what do ya want for nothing?", 28);
- test_streq(hex_str(digest, 20),
- "EFFCDF6AE5EB2FA2D27416D5F184DF9C259A7C79");
- /* Case 4. */
- base16_decode(key, 25,
- "0102030405060708090a0b0c0d0e0f10111213141516171819", 50);
- memset(data, 0xcd, 50);
- crypto_hmac_sha1(digest, key, 25, data, 50);
- test_streq(hex_str(digest, 20),
- "4C9007F4026250C6BC8414F9BF50C86C2D7235DA");
- /* Case . */
- memset(key, 0xaa, 80);
- crypto_hmac_sha1(digest, key, 80,
- "Test Using Larger Than Block-Size Key - Hash Key First",
- 54);
- test_streq(hex_str(digest, 20),
- "AA4AE5E15272D00E95705637CE8A3B55ED402112");
- /* Incremental digest code. */
- d1 = crypto_new_digest_env();
- test_assert(d1);
- crypto_digest_add_bytes(d1, "abcdef", 6);
- d2 = crypto_digest_dup(d1);
- test_assert(d2);
- crypto_digest_add_bytes(d2, "ghijkl", 6);
- crypto_digest_get_digest(d2, d_out1, sizeof(d_out1));
- crypto_digest(d_out2, "abcdefghijkl", 12);
- test_memeq(d_out1, d_out2, DIGEST_LEN);
- crypto_digest_assign(d2, d1);
- crypto_digest_add_bytes(d2, "mno", 3);
- crypto_digest_get_digest(d2, d_out1, sizeof(d_out1));
- crypto_digest(d_out2, "abcdefmno", 9);
- test_memeq(d_out1, d_out2, DIGEST_LEN);
- crypto_digest_get_digest(d1, d_out1, sizeof(d_out1));
- crypto_digest(d_out2, "abcdef", 6);
- test_memeq(d_out1, d_out2, DIGEST_LEN);
- done:
- if (d1)
- crypto_free_digest_env(d1);
- if (d2)
- crypto_free_digest_env(d2);
- }
- /** Run unit tests for our public key crypto functions */
- static void
- test_crypto_pk(void)
- {
- crypto_pk_env_t *pk1 = NULL, *pk2 = NULL;
- char *encoded = NULL;
- char data1[1024], data2[1024], data3[1024];
- size_t size;
- int i, j, p, len;
- /* Public-key ciphers */
- pk1 = pk_generate(0);
- pk2 = crypto_new_pk_env();
- test_assert(pk1 && pk2);
- test_assert(! crypto_pk_write_public_key_to_string(pk1, &encoded, &size));
- test_assert(! crypto_pk_read_public_key_from_string(pk2, encoded, size));
- test_eq(0, crypto_pk_cmp_keys(pk1, pk2));
- test_eq(128, crypto_pk_keysize(pk1));
- test_eq(128, crypto_pk_keysize(pk2));
- test_eq(128, crypto_pk_public_encrypt(pk2, data1, "Hello whirled.", 15,
- PK_PKCS1_OAEP_PADDING));
- test_eq(128, crypto_pk_public_encrypt(pk1, data2, "Hello whirled.", 15,
- PK_PKCS1_OAEP_PADDING));
- /* oaep padding should make encryption not match */
- test_memneq(data1, data2, 128);
- test_eq(15, crypto_pk_private_decrypt(pk1, data3, data1, 128,
- PK_PKCS1_OAEP_PADDING,1));
- test_streq(data3, "Hello whirled.");
- memset(data3, 0, 1024);
- test_eq(15, crypto_pk_private_decrypt(pk1, data3, data2, 128,
- PK_PKCS1_OAEP_PADDING,1));
- test_streq(data3, "Hello whirled.");
- /* Can't decrypt with public key. */
- test_eq(-1, crypto_pk_private_decrypt(pk2, data3, data2, 128,
- PK_PKCS1_OAEP_PADDING,1));
- /* Try again with bad padding */
- memcpy(data2+1, "XYZZY", 5); /* This has fails ~ once-in-2^40 */
- test_eq(-1, crypto_pk_private_decrypt(pk1, data3, data2, 128,
- PK_PKCS1_OAEP_PADDING,1));
- /* File operations: save and load private key */
- test_assert(! crypto_pk_write_private_key_to_filename(pk1,
- get_fname("pkey1")));
- /* failing case for read: can't read. */
- test_assert(crypto_pk_read_private_key_from_filename(pk2,
- get_fname("xyzzy")) < 0);
- write_str_to_file(get_fname("xyzzy"), "foobar", 6);
- /* Failing case for read: no key. */
- test_assert(crypto_pk_read_private_key_from_filename(pk2,
- get_fname("xyzzy")) < 0);
- test_assert(! crypto_pk_read_private_key_from_filename(pk2,
- get_fname("pkey1")));
- test_eq(15, crypto_pk_private_decrypt(pk2, data3, data1, 128,
- PK_PKCS1_OAEP_PADDING,1));
- /* Now try signing. */
- strlcpy(data1, "Ossifrage", 1024);
- test_eq(128, crypto_pk_private_sign(pk1, data2, data1, 10));
- test_eq(10, crypto_pk_public_checksig(pk1, data3, data2, 128));
- test_streq(data3, "Ossifrage");
- /* Try signing digests. */
- test_eq(128, crypto_pk_private_sign_digest(pk1, data2, data1, 10));
- test_eq(20, crypto_pk_public_checksig(pk1, data3, data2, 128));
- test_eq(0, crypto_pk_public_checksig_digest(pk1, data1, 10, data2, 128));
- test_eq(-1, crypto_pk_public_checksig_digest(pk1, data1, 11, data2, 128));
- /*XXXX test failed signing*/
- /* Try encoding */
- crypto_free_pk_env(pk2);
- pk2 = NULL;
- i = crypto_pk_asn1_encode(pk1, data1, 1024);
- test_assert(i>0);
- pk2 = crypto_pk_asn1_decode(data1, i);
- test_assert(crypto_pk_cmp_keys(pk1,pk2) == 0);
- /* Try with hybrid encryption wrappers. */
- crypto_rand(data1, 1024);
- for (i = 0; i < 3; ++i) {
- for (j = 85; j < 140; ++j) {
- memset(data2,0,1024);
- memset(data3,0,1024);
- if (i == 0 && j < 129)
- continue;
- p = (i==0)?PK_NO_PADDING:
- (i==1)?PK_PKCS1_PADDING:PK_PKCS1_OAEP_PADDING;
- len = crypto_pk_public_hybrid_encrypt(pk1,data2,data1,j,p,0);
- test_assert(len>=0);
- len = crypto_pk_private_hybrid_decrypt(pk1,data3,data2,len,p,1);
- test_eq(len,j);
- test_memeq(data1,data3,j);
- }
- }
- /* Try copy_full */
- crypto_free_pk_env(pk2);
- pk2 = crypto_pk_copy_full(pk1);
- test_assert(pk2 != NULL);
- test_neq_ptr(pk1, pk2);
- test_assert(crypto_pk_cmp_keys(pk1,pk2) == 0);
- done:
- if (pk1)
- crypto_free_pk_env(pk1);
- if (pk2)
- crypto_free_pk_env(pk2);
- tor_free(encoded);
- }
- /** Run unit tests for misc crypto functionality. */
- static void
- test_crypto(void)
- {
- char *data1 = NULL, *data2 = NULL, *data3 = NULL;
- int i, j, idx;
- data1 = tor_malloc(1024);
- data2 = tor_malloc(1024);
- data3 = tor_malloc(1024);
- test_assert(data1 && data2 && data3);
- /* Base64 tests */
- memset(data1, 6, 1024);
- for (idx = 0; idx < 10; ++idx) {
- i = base64_encode(data2, 1024, data1, idx);
- test_assert(i >= 0);
- j = base64_decode(data3, 1024, data2, i);
- test_eq(j,idx);
- test_memeq(data3, data1, idx);
- }
- strlcpy(data1, "Test string that contains 35 chars.", 1024);
- strlcat(data1, " 2nd string that contains 35 chars.", 1024);
- i = base64_encode(data2, 1024, data1, 71);
- j = base64_decode(data3, 1024, data2, i);
- test_eq(j, 71);
- test_streq(data3, data1);
- test_assert(data2[i] == ' ');
- crypto_rand(data1, DIGEST_LEN);
- memset(data2, 100, 1024);
- digest_to_base64(data2, data1);
- test_eq(BASE64_DIGEST_LEN, strlen(data2));
- test_eq(100, data2[BASE64_DIGEST_LEN+2]);
- memset(data3, 99, 1024);
- test_eq(digest_from_base64(data3, data2), 0);
- test_memeq(data1, data3, DIGEST_LEN);
- test_eq(99, data3[DIGEST_LEN+1]);
- test_assert(digest_from_base64(data3, "###") < 0);
- /* Base32 tests */
- strlcpy(data1, "5chrs", 1024);
- /* bit pattern is: [35 63 68 72 73] ->
- * [00110101 01100011 01101000 01110010 01110011]
- * By 5s: [00110 10101 10001 10110 10000 11100 10011 10011]
- */
- base32_encode(data2, 9, data1, 5);
- test_streq(data2, "gvrwq4tt");
- strlcpy(data1, "xFFxF5x6Dx44xAEx0Dx5CxC9x62xC4", 1024);
- base32_encode(data2, 30, data1, 10);
- test_streq(data2, "772w2rfobvomsywe");
- /* Base16 tests */
- strlcpy(data1, "6chrsxff", 1024);
- base16_encode(data2, 13, data1, 6);
- test_streq(data2, "3663687273FF");
- strlcpy(data1, "f0d678affc000100", 1024);
- i = base16_decode(data2, 8, data1, 16);
- test_eq(i,0);
- test_memeq(data2, "xf0xd6x78xafxfcx00x01x00",8);
- /* now try some failing base16 decodes */
- test_eq(-1, base16_decode(data2, 8, data1, 15)); /* odd input len */
- test_eq(-1, base16_decode(data2, 7, data1, 16)); /* dest too short */
- strlcpy(data1, "f0dz!8affc000100", 1024);
- test_eq(-1, base16_decode(data2, 8, data1, 16));
- tor_free(data1);
- tor_free(data2);
- tor_free(data3);
- /* Add spaces to fingerprint */
- {
- data1 = tor_strdup("ABCD1234ABCD56780000ABCD1234ABCD56780000");
- test_eq(strlen(data1), 40);
- data2 = tor_malloc(FINGERPRINT_LEN+1);
- add_spaces_to_fp(data2, FINGERPRINT_LEN+1, data1);
- test_streq(data2, "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 0000");
- tor_free(data1);
- tor_free(data2);
- }
- /* Check fingerprint */
- {
- test_assert(crypto_pk_check_fingerprint_syntax(
- "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 0000"));
- test_assert(!crypto_pk_check_fingerprint_syntax(
- "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 000"));
- test_assert(!crypto_pk_check_fingerprint_syntax(
- "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 00000"));
- test_assert(!crypto_pk_check_fingerprint_syntax(
- "ABCD 1234 ABCD 5678 0000 ABCD1234 ABCD 5678 0000"));
- test_assert(!crypto_pk_check_fingerprint_syntax(
- "ABCD 1234 ABCD 5678 0000 ABCD1234 ABCD 5678 00000"));
- test_assert(!crypto_pk_check_fingerprint_syntax(
- "ACD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 00000"));
- }
- done:
- tor_free(data1);
- tor_free(data2);
- tor_free(data3);
- }
- /** Run unit tests for our secret-to-key passphrase hashing functionality. */
- static void
- test_crypto_s2k(void)
- {
- char buf[29];
- char buf2[29];
- char *buf3 = NULL;
- int i;
- memset(buf, 0, sizeof(buf));
- memset(buf2, 0, sizeof(buf2));
- buf3 = tor_malloc(65536);
- memset(buf3, 0, 65536);
- secret_to_key(buf+9, 20, "", 0, buf);
- crypto_digest(buf2+9, buf3, 1024);
- test_memeq(buf, buf2, 29);
- memcpy(buf,"vrbacrda",8);
- memcpy(buf2,"vrbacrda",8);
- buf[8] = 96;
- buf2[8] = 96;
- secret_to_key(buf+9, 20, "12345678", 8, buf);
- for (i = 0; i < 65536; i += 16) {
- memcpy(buf3+i, "vrbacrda12345678", 16);
- }
- crypto_digest(buf2+9, buf3, 65536);
- test_memeq(buf, buf2, 29);
- done:
- tor_free(buf3);
- }
- /** Helper: return a tristate based on comparing the strings in *<b>a</b> and
- * *<b>b</b>. */
- static int
- _compare_strs(const void **a, const void **b)
- {
- const char *s1 = *a, *s2 = *b;
- return strcmp(s1, s2);
- }
- /** Helper: return a tristate based on comparing the strings in *<b>a</b> and
- * *<b>b</b>, excluding a's first character, and ignoring case. */
- static int
- _compare_without_first_ch(const void *a, const void **b)
- {
- const char *s1 = a, *s2 = *b;
- return strcasecmp(s1+1, s2);
- }
- /** Test basic utility functionality. */
- static void
- test_util(void)
- {
- struct timeval start, end;
- struct tm a_time;
- char timestr[RFC1123_TIME_LEN+1];
- char buf[1024];
- time_t t_res;
- int i;
- uint32_t u32;
- uint16_t u16;
- char *cp, *k, *v;
- const char *str;
- start.tv_sec = 5;
- start.tv_usec = 5000;
- end.tv_sec = 5;
- end.tv_usec = 5000;
- test_eq(0L, tv_udiff(&start, &end));
- end.tv_usec = 7000;
- test_eq(2000L, tv_udiff(&start, &end));
- end.tv_sec = 6;
- test_eq(1002000L, tv_udiff(&start, &end));
- end.tv_usec = 0;
- test_eq(995000L, tv_udiff(&start, &end));
- end.tv_sec = 4;
- test_eq(-1005000L, tv_udiff(&start, &end));
- end.tv_usec = 999990;
- start.tv_sec = 1;
- start.tv_usec = 500;
- /* The test values here are confirmed to be correct on a platform
- * with a working timegm. */
- a_time.tm_year = 2003-1900;
- a_time.tm_mon = 7;
- a_time.tm_mday = 30;
- a_time.tm_hour = 6;
- a_time.tm_min = 14;
- a_time.tm_sec = 55;
- test_eq((time_t) 1062224095UL, tor_timegm(&a_time));
- a_time.tm_year = 2004-1900; /* Try a leap year, after feb. */
- test_eq((time_t) 1093846495UL, tor_timegm(&a_time));
- a_time.tm_mon = 1; /* Try a leap year, in feb. */
- a_time.tm_mday = 10;
- test_eq((time_t) 1076393695UL, tor_timegm(&a_time));
- format_rfc1123_time(timestr, 0);
- test_streq("Thu, 01 Jan 1970 00:00:00 GMT", timestr);
- format_rfc1123_time(timestr, (time_t)1091580502UL);
- test_streq("Wed, 04 Aug 2004 00:48:22 GMT", timestr);
- t_res = 0;
- i = parse_rfc1123_time(timestr, &t_res);
- test_eq(i,0);
- test_eq(t_res, (time_t)1091580502UL);
- test_eq(-1, parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res));
- tor_gettimeofday(&start);
- /* Tests for corner cases of strl operations */
- test_eq(5, strlcpy(buf, "Hello", 0));
- strlcpy(buf, "Hello", sizeof(buf));
- test_eq(10, strlcat(buf, "Hello", 5));
- /* Test tor_strstrip() */
- strlcpy(buf, "Testing 1 2 3", sizeof(buf));
- tor_strstrip(buf, ",!");
- test_streq(buf, "Testing 1 2 3");
- strlcpy(buf, "!Testing 1 2 3?", sizeof(buf));
- tor_strstrip(buf, "!? ");
- test_streq(buf, "Testing123");
- /* Test parse_addr_port */
- cp = NULL; u32 = 3; u16 = 3;
- test_assert(!parse_addr_port(LOG_WARN, "1.2.3.4", &cp, &u32, &u16));
- test_streq(cp, "1.2.3.4");
- test_eq(u32, 0x01020304u);
- test_eq(u16, 0);
- tor_free(cp);
- test_assert(!parse_addr_port(LOG_WARN, "4.3.2.1:99", &cp, &u32, &u16));
- test_streq(cp, "4.3.2.1");
- test_eq(u32, 0x04030201u);
- test_eq(u16, 99);
- tor_free(cp);
- test_assert(!parse_addr_port(LOG_WARN, "nonexistent.address:4040",
- &cp, NULL, &u16));
- test_streq(cp, "nonexistent.address");
- test_eq(u16, 4040);
- tor_free(cp);
- test_assert(!parse_addr_port(LOG_WARN, "localhost:9999", &cp, &u32, &u16));
- test_streq(cp, "localhost");
- test_eq(u32, 0x7f000001u);
- test_eq(u16, 9999);
- tor_free(cp);
- u32 = 3;
- test_assert(!parse_addr_port(LOG_WARN, "localhost", NULL, &u32, &u16));
- test_eq(cp, NULL);
- test_eq(u32, 0x7f000001u);
- test_eq(u16, 0);
- tor_free(cp);
- test_eq(0, addr_mask_get_bits(0x0u));
- test_eq(32, addr_mask_get_bits(0xFFFFFFFFu));
- test_eq(16, addr_mask_get_bits(0xFFFF0000u));
- test_eq(31, addr_mask_get_bits(0xFFFFFFFEu));
- test_eq(1, addr_mask_get_bits(0x80000000u));
- /* Test tor_parse_long. */
- test_eq(10L, tor_parse_long("10",10,0,100,NULL,NULL));
- test_eq(0L, tor_parse_long("10",10,50,100,NULL,NULL));
- test_eq(-50L, tor_parse_long("-50",10,-100,100,NULL,NULL));
- /* Test tor_parse_ulong */
- test_eq(10UL, tor_parse_ulong("10",10,0,100,NULL,NULL));
- test_eq(0UL, tor_parse_ulong("10",10,50,100,NULL,NULL));
- /* Test tor_parse_uint64. */
- test_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i, &cp));
- test_assert(i == 1);
- test_streq(cp, " x");
- test_assert(U64_LITERAL(12345678901) ==
- tor_parse_uint64("12345678901",10,0,UINT64_MAX, &i, &cp));
- test_assert(i == 1);
- test_streq(cp, "");
- test_assert(U64_LITERAL(0) ==
- tor_parse_uint64("12345678901",10,500,INT32_MAX, &i, &cp));
- test_assert(i == 0);
- /* Test failing snprintf cases */
- test_eq(-1, tor_snprintf(buf, 0, "Foo"));
- test_eq(-1, tor_snprintf(buf, 2, "Foo"));
- /* Test printf with uint64 */
- tor_snprintf(buf, sizeof(buf), "x!"U64_FORMAT"!x",
- U64_PRINTF_ARG(U64_LITERAL(12345678901)));
- test_streq(buf, "x!12345678901!x");
- /* Test parse_config_line_from_str */
- strlcpy(buf, "k vn" " key value with spaces n" "keykey valn"
- "k2n"
- "k3 n" "n" " n" "#commentn"
- "k4#an" "k5#abcn" "k6 val #with commentn"
- "kseven "a quoted 'string"n"
- "k8 "a \x71uoted\n\"str\\ing\t\001\01\1\""n"
- , sizeof(buf));
- str = buf;
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k");
- test_streq(v, "v");
- tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "key value with"));
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "key");
- test_streq(v, "value with spaces");
- tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "keykey"));
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "keykey");
- test_streq(v, "val");
- tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "k2n"));
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k2");
- test_streq(v, "");
- tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "k3 n"));
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k3");
- test_streq(v, "");
- tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "#comment"));
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k4");
- test_streq(v, "");
- tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "k5#abc"));
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k5");
- test_streq(v, "");
- tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "k6"));
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k6");
- test_streq(v, "val");
- tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "kseven"));
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "kseven");
- test_streq(v, "a quoted 'string");
- tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "k8 "));
- str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k8");
- test_streq(v, "a quotedn"str\ingtx01x01x01"");
- tor_free(k); tor_free(v);
- test_streq(str, "");
- /* Test for strcmpstart and strcmpend. */
- test_assert(strcmpstart("abcdef", "abcdef")==0);
- test_assert(strcmpstart("abcdef", "abc")==0);
- test_assert(strcmpstart("abcdef", "abd")<0);
- test_assert(strcmpstart("abcdef", "abb")>0);
- test_assert(strcmpstart("ab", "abb")<0);
- test_assert(strcmpend("abcdef", "abcdef")==0);
- test_assert(strcmpend("abcdef", "def")==0);
- test_assert(strcmpend("abcdef", "deg")<0);
- test_assert(strcmpend("abcdef", "dee")>0);
- test_assert(strcmpend("ab", "abb")<0);
- test_assert(strcasecmpend("AbcDEF", "abcdef")==0);
- test_assert(strcasecmpend("abcdef", "dEF")==0);
- test_assert(strcasecmpend("abcDEf", "deg")<0);
- test_assert(strcasecmpend("abcdef", "DEE")>0);
- test_assert(strcasecmpend("ab", "abB")<0);
- /* Test mem_is_zero */
- memset(buf,0,128);
- buf[128] = 'x';
- test_assert(tor_digest_is_zero(buf));
- test_assert(tor_mem_is_zero(buf, 10));
- test_assert(tor_mem_is_zero(buf, 20));
- test_assert(tor_mem_is_zero(buf, 128));
- test_assert(!tor_mem_is_zero(buf, 129));
- buf[60] = (char)255;
- test_assert(!tor_mem_is_zero(buf, 128));
- buf[0] = (char)1;
- test_assert(!tor_mem_is_zero(buf, 10));
- /* Test inet_ntop */
- {
- char tmpbuf[TOR_ADDR_BUF_LEN];
- const char *ip = "176.192.208.224";
- struct in_addr in;
- tor_inet_pton(AF_INET, ip, &in);
- tor_inet_ntop(AF_INET, &in, tmpbuf, sizeof(tmpbuf));
- test_streq(tmpbuf, ip);
- }
- /* Test 'escaped' */
- test_streq("""", escaped(""));
- test_streq(""abcd"", escaped("abcd"));
- test_streq(""\\\n\r\t\"\'"", escaped("\nrt"'"));
- test_streq(""z\001abc\277d"", escaped("z 01abc277d"));
- test_assert(NULL == escaped(NULL));
- /* Test strndup and memdup */
- {
- const char *s = "abcdefghijklmnopqrstuvwxyz";
- cp = tor_strndup(s, 30);
- test_streq(cp, s); /* same string, */
- test_neq(cp, s); /* but different pointers. */
- tor_free(cp);
- cp = tor_strndup(s, 5);
- test_streq(cp, "abcde");
- tor_free(cp);
- s = "a b c d e ";
- cp = tor_memdup(s,10);
- test_memeq(cp, s, 10); /* same ram, */
- test_neq(cp, s); /* but different pointers. */
- tor_free(cp);
- }
- /* Test str-foo functions */
- cp = tor_strdup("abcdef");
- test_assert(tor_strisnonupper(cp));
- cp[3] = 'D';
- test_assert(!tor_strisnonupper(cp));
- tor_strupper(cp);
- test_streq(cp, "ABCDEF");
- test_assert(tor_strisprint(cp));
- cp[3] = 3;
- test_assert(!tor_strisprint(cp));
- tor_free(cp);
- /* Test eat_whitespace. */
- {
- const char *s = " n a";
- test_eq_ptr(eat_whitespace(s), s+4);
- s = "abcd";
- test_eq_ptr(eat_whitespace(s), s);
- s = "#xyznab";
- test_eq_ptr(eat_whitespace(s), s+5);
- }
- /* Test memmem and memstr */
- {
- const char *haystack = "abcde";
- tor_assert(!tor_memmem(haystack, 5, "ef", 2));
- test_eq_ptr(tor_memmem(haystack, 5, "cd", 2), haystack + 2);
- test_eq_ptr(tor_memmem(haystack, 5, "cde", 3), haystack + 2);
- haystack = "ababcad";
- test_eq_ptr(tor_memmem(haystack, 7, "abc", 3), haystack + 2);
- test_eq_ptr(tor_memstr(haystack, 7, "abc"), haystack + 2);
- test_assert(!tor_memstr(haystack, 7, "fe"));
- test_assert(!tor_memstr(haystack, 7, "longerthantheoriginal"));
- }
- /* Test wrap_string */
- {
- smartlist_t *sl = smartlist_create();
- wrap_string(sl, "This is a test of string wrapping functionality: woot.",
- 10, "", "");
- cp = smartlist_join_strings(sl, "", 0, NULL);
- test_streq(cp,
- "This is antest ofnstringnwrappingnfunctionalnity: woot.n");
- tor_free(cp);
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_clear(sl);
- wrap_string(sl, "This is a test of string wrapping functionality: woot.",
- 16, "### ", "# ");
- cp = smartlist_join_strings(sl, "", 0, NULL);
- test_streq(cp,
- "### This is an# test of stringn# wrappingn# functionality:n"
- "# woot.n");
- tor_free(cp);
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_free(sl);
- }
- /* now make sure time works. */
- tor_gettimeofday(&end);
- /* We might've timewarped a little. */
- test_assert(tv_udiff(&start, &end) >= -5000);
- /* Test tor_log2(). */
- test_eq(tor_log2(64), 6);
- test_eq(tor_log2(65), 6);
- test_eq(tor_log2(63), 5);
- test_eq(tor_log2(1), 0);
- test_eq(tor_log2(2), 1);
- test_eq(tor_log2(3), 1);
- test_eq(tor_log2(4), 2);
- test_eq(tor_log2(5), 2);
- test_eq(tor_log2(U64_LITERAL(40000000000000000)), 55);
- test_eq(tor_log2(UINT64_MAX), 63);
- /* Test round_to_power_of_2 */
- test_eq(round_to_power_of_2(120), 128);
- test_eq(round_to_power_of_2(128), 128);
- test_eq(round_to_power_of_2(130), 128);
- test_eq(round_to_power_of_2(U64_LITERAL(40000000000000000)),
- U64_LITERAL(1)<<55);
- test_eq(round_to_power_of_2(0), 2);
- done:
- ;
- }
- /** Helper: assert that IPv6 addresses <b>a</b> and <b>b</b> are the same. On
- * failure, reports an error, describing the addresses as <b>e1</b> and
- * <b>e2</b>, and reporting the line number as <b>line</b>. */
- static void
- _test_eq_ip6(struct in6_addr *a, struct in6_addr *b, const char *e1,
- const char *e2, int line)
- {
- int i;
- int ok = 1;
- for (i = 0; i < 16; ++i) {
- if (a->s6_addr[i] != b->s6_addr[i]) {
- ok = 0;
- break;
- }
- }
- if (ok) {
- printf("."); fflush(stdout);
- } else {
- char buf1[128], *cp1;
- char buf2[128], *cp2;
- have_failed = 1;
- cp1 = buf1; cp2 = buf2;
- for (i=0; i<16; ++i) {
- tor_snprintf(cp1, sizeof(buf1)-(cp1-buf1), "%02x", a->s6_addr[i]);
- tor_snprintf(cp2, sizeof(buf2)-(cp2-buf2), "%02x", b->s6_addr[i]);
- cp1 += 2; cp2 += 2;
- if ((i%2)==1 && i != 15) {
- *cp1++ = ':';
- *cp2++ = ':';
- }
- }
- *cp1 = *cp2 = ' ';
- printf("Line %d: assertion failed: (%s == %s)n"
- " %s != %sn", line, e1, e2, buf1, buf2);
- fflush(stdout);
- }
- }
- /** Helper: Assert that two strings both decode as IPv6 addresses with
- * tor_inet_pton(), and both decode to the same address. */
- #define test_pton6_same(a,b) STMT_BEGIN
- test_eq(tor_inet_pton(AF_INET6, a, &a1), 1);
- test_eq(tor_inet_pton(AF_INET6, b, &a2), 1);
- _test_eq_ip6(&a1,&a2,#a,#b,__LINE__);
- STMT_END
- /** Helper: Assert that <b>a</b> is recognized as a bad IPv6 address by
- * tor_inet_pton(). */
- #define test_pton6_bad(a)
- test_eq(0, tor_inet_pton(AF_INET6, a, &a1))
- /** Helper: assert that <b>a</b>, when parsed by tor_inet_pton() and displayed
- * with tor_inet_ntop(), yields <b>b</b>. Also assert that <b>b</b> parses to
- * the same value as <b>a</b>. */
- #define test_ntop6_reduces(a,b) STMT_BEGIN
- test_eq(tor_inet_pton(AF_INET6, a, &a1), 1);
- test_streq(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)), b);
- test_eq(tor_inet_pton(AF_INET6, b, &a2), 1);
- _test_eq_ip6(&a1, &a2, a, b, __LINE__);
- STMT_END
- /** Helper: assert that <b>a</b> parses by tor_inet_pton() into a address that
- * passes tor_addr_is_internal() with <b>for_listening</b>. */
- #define test_internal_ip(a,for_listening) STMT_BEGIN
- test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1);
- t1.family = AF_INET6;
- if (!tor_addr_is_internal(&t1, for_listening))
- test_fail_msg( a "was not internal.");
- STMT_END
- /** Helper: assert that <b>a</b> parses by tor_inet_pton() into a address that
- * does not pass tor_addr_is_internal() with <b>for_listening</b>. */
- #define test_external_ip(a,for_listening) STMT_BEGIN
- test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1);
- t1.family = AF_INET6;
- if (tor_addr_is_internal(&t1, for_listening))
- test_fail_msg(a "was not external.");
- STMT_END
- /** Helper: Assert that <b>a</b> and <b>b</b>, when parsed by
- * tor_inet_pton(), give addresses that compare in the order defined by
- * <b>op</b> with tor_addr_compare(). */
- #define test_addr_compare(a, op, b) STMT_BEGIN
- test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1);
- test_eq(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), 1);
- t1.family = t2.family = AF_INET6;
- r = tor_addr_compare(&t1,&t2,CMP_SEMANTIC);
- if (!(r op 0))
- test_fail_msg("failed: tor_addr_compare("a","b") "#op" 0");
- STMT_END
- /** Helper: Assert that <b>a</b> and <b>b</b>, when parsed by
- * tor_inet_pton(), give addresses that compare in the order defined by
- * <b>op</b> with tor_addr_compare_masked() with <b>m</b> masked. */
- #define test_addr_compare_masked(a, op, b, m) STMT_BEGIN
- test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1);
- test_eq(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), 1);
- t1.family = t2.family = AF_INET6;
- r = tor_addr_compare_masked(&t1,&t2,m,CMP_SEMANTIC);
- if (!(r op 0))
- test_fail_msg("failed: tor_addr_compare_masked("a","b","#m") "#op" 0");
- STMT_END
- /** Helper: assert that <b>xx</b> is parseable as a masked IPv6 address with
- * ports by tor_parse_mask_addr_ports(), with family <b>f</b>, IP address
- * as 4 32-bit words <b>ip1...ip4</b>, mask bits as <b>mm</b>, and port range
- * as <b>pt1..pt2</b>. */
- #define test_addr_mask_ports_parse(xx, f, ip1, ip2, ip3, ip4, mm, pt1, pt2)
- STMT_BEGIN
- test_eq(tor_addr_parse_mask_ports(xx, &t1, &mask, &port1, &port2), f);
- p1=tor_inet_ntop(AF_INET6, &t1.addr.in6_addr, bug, sizeof(bug));
- test_eq(htonl(ip1), tor_addr_to_in6_addr32(&t1)[0]);
- test_eq(htonl(ip2), tor_addr_to_in6_addr32(&t1)[1]);
- test_eq(htonl(ip3), tor_addr_to_in6_addr32(&t1)[2]);
- test_eq(htonl(ip4), tor_addr_to_in6_addr32(&t1)[3]);
- test_eq(mask, mm);
- test_eq(port1, pt1);
- test_eq(port2, pt2);
- STMT_END
- /** Run unit tests for IPv6 encoding/decoding/manipulation functions. */
- static void
- test_util_ip6_helpers(void)
- {
- char buf[TOR_ADDR_BUF_LEN], bug[TOR_ADDR_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;
- // struct in_addr b1, b2;
- /* Test tor_inet_ntop and tor_inet_pton: IPv6 */
- /* ==== Converting to and from sockaddr_t. */
- sin = (struct sockaddr_in *)&sa_storage;
- sin->sin_family = AF_INET;
- sin->sin_port = 9090;
- sin->sin_addr.s_addr = htonl(0x7f7f0102); /*127.127.1.2*/
- tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, NULL);
- test_eq(tor_addr_family(&t1), AF_INET);
- test_eq(tor_addr_to_ipv4h(&t1), 0x7f7f0102);
- memset(&sa_storage, 0, sizeof(sa_storage));
- test_eq(sizeof(struct sockaddr_in),
- tor_addr_to_sockaddr(&t1, 1234, (struct sockaddr *)&sa_storage,
- sizeof(sa_storage)));
- test_eq(1234, ntohs(sin->sin_port));
- test_eq(0x7f7f0102, 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, NULL);
- test_eq(tor_addr_family(&t1), AF_INET6);
- p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0);
- test_streq(p1, "8000::");
- memset(&sa_storage, 0, sizeof(sa_storage));
- test_eq(sizeof(struct sockaddr_in6),
- tor_addr_to_sockaddr(&t1, 9999, (struct sockaddr *)&sa_storage,
- sizeof(sa_storage)));
- test_eq(AF_INET6, sin6->sin6_family);
- test_eq(9999, ntohs(sin6->sin6_port));
- test_eq(0x80000000, ntohl(S6_ADDR32(sin6->sin6_addr)[0]));
- /* ==== tor_addr_lookup: static cases. (Can't test dns without knowing we
- * have a good resolver. */
- test_eq(0, tor_addr_lookup("127.128.129.130", AF_UNSPEC, &t1));
- test_eq(AF_INET, tor_addr_family(&t1));
- test_eq(tor_addr_to_ipv4h(&t1), 0x7f808182);
- test_eq(0, tor_addr_lookup("9000::5", AF_UNSPEC, &t1));
- test_eq(AF_INET6, tor_addr_family(&t1));
- test_eq(0x90, tor_addr_to_in6_addr8(&t1)[0]);
- test_assert(tor_mem_is_zero((char*)tor_addr_to_in6_addr8(&t1)+1, 14));
- test_eq(0x05, 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);
- test_assert(r==1);
- for (i=0;i<16;++i) { test_eq(i+1, (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("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::");
- /* === Test pton: invalid in6. */
- test_pton6_bad("foobar.");
- test_pton6_bad("55555::");
- test_pton6_bad("9:-60::");
- test_pton6_bad("1:2:33333:4:0002:3::");
- //test_pton6_bad("1:2:3333:4:00002:3::");// BAD, but glibc doesn't say so.
- 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("99");
- 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 internal checking */
- test_external_ip("fbff:ffff::2:7", 0);
- test_internal_ip("fc01::2: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);
- test_assert(is_internal_IP(0x7f000001, 0));
- /* tor_addr_compare(tor_addr_t x2) */
- test_addr_compare("ffff::", ==, "ffff::0");
- test_addr_compare("0::3:2:1", <, "0::ffff:0.3.2.1");
- test_addr_compare("0::2:2:1", <, "0::ffff:0.3.2.1");
- test_addr_compare("0::ffff:0.3.2.1", >, "0::0:0:0");
- test_addr_compare("0::ffff:5.2.2.1", <, "::ffff:6.0.0.0"); /* XXXX wrong. */
- tor_addr_parse_mask_ports("[::ffff:2.3.4.5]", &t1, NULL, NULL, NULL);
- tor_addr_parse_mask_ports("2.3.4.5", &t2, NULL, NULL, NULL);
- test_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) == 0);
- tor_addr_parse_mask_ports("[::ffff:2.3.4.4]", &t1, NULL, NULL, NULL);
- tor_addr_parse_mask_ports("2.3.4.5", &t2, NULL, NULL, NULL);
- test_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) < 0);
- /* test compare_masked */
- test_addr_compare_masked("ffff::", ==, "ffff::0", 128);
- test_addr_compare_masked("ffff::", ==, "ffff::0", 64);
- test_addr_compare_masked("0::2:2:1", <, "0::8000:2:1", 81);
- test_addr_compare_masked("0::2:2:1", ==, "0::8000:2:1", 80);
- /* Test decorated addr_to_string. */
- test_eq(AF_INET6, tor_addr_from_str(&t1, "[123:45:6789::5005:11]"));
- p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
- test_streq(p1, "[123:45:6789::5005:11]");
- test_eq(AF_INET, tor_addr_from_str(&t1, "18.0.0.1"));
- p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
- test_streq(p1, "18.0.0.1");
- /* Test tor_addr_parse_reverse_lookup_name */
- i = tor_addr_parse_reverse_lookup_name(&t1, "Foobar.baz", AF_UNSPEC, 0);
- test_eq(0, i);
- i = tor_addr_parse_reverse_lookup_name(&t1, "Foobar.baz", AF_UNSPEC, 1);
- test_eq(0, i);
- i = tor_addr_parse_reverse_lookup_name(&t1, "1.0.168.192.in-addr.arpa",
- AF_UNSPEC, 1);
- test_eq(1, i);
- test_eq(tor_addr_family(&t1), AF_INET);
- p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
- test_streq(p1, "192.168.0.1");
- i = tor_addr_parse_reverse_lookup_name(&t1, "192.168.0.99", AF_UNSPEC, 0);
- test_eq(0, i);
- i = tor_addr_parse_reverse_lookup_name(&t1, "192.168.0.99", AF_UNSPEC, 1);
- test_eq(1, i);
- p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
- test_streq(p1, "192.168.0.99");
- memset(&t1, 0, sizeof(t1));
- i = tor_addr_parse_reverse_lookup_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);
- test_eq(1, i);
- p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
- test_streq(p1, "[9dee:effe:ebe1:beef:fedc:ba98:7654:3210]");
- /* Failing cases. */
- i = tor_addr_parse_reverse_lookup_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);
- test_eq(i, -1);
- i = tor_addr_parse_reverse_lookup_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);
- test_eq(i, -1);
- i = tor_addr_parse_reverse_lookup_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);
- test_eq(i, -1);
- i = tor_addr_parse_reverse_lookup_name(&t1, "32.1.1.in-addr.arpa",
- AF_UNSPEC, 0);
- test_eq(i, -1);
- i = tor_addr_parse_reverse_lookup_name(&t1, ".in-addr.arpa",
- AF_UNSPEC, 0);
- test_eq(i, -1);
- i = tor_addr_parse_reverse_lookup_name(&t1, "1.2.3.4.5.in-addr.arpa",
- AF_UNSPEC, 0);
- test_eq(i, -1);
- i = tor_addr_parse_reverse_lookup_name(&t1, "1.2.3.4.5.in-addr.arpa",
- AF_INET6, 0);
- test_eq(i, -1);
- i = tor_addr_parse_reverse_lookup_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);
- test_eq(i, -1);
- /* test tor_addr_parse_mask_ports */
- test_addr_mask_ports_parse("[::f]/17:47-95", AF_INET6,
- 0, 0, 0, 0x0000000f, 17, 47, 95);
- //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);
- test_addr_mask_ports_parse("[abcd:2::44a:0]:2-65000", AF_INET6,
- 0xabcd0002, 0, 0, 0x044a0000, 128, 2, 65000);
- r=tor_addr_parse_mask_ports("[fefef::]/112", &t1, NULL, NULL, NULL);
- test_assert(r == -1);
- r=tor_addr_parse_mask_ports("efef::/112", &t1, NULL, NULL, NULL);
- test_assert(r == -1);
- r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f::]", &t1, NULL, NULL, NULL);
- test_assert(r == -1);
- r=tor_addr_parse_mask_ports("[::f:f:f:f:f:f:f:f]", &t1, NULL, NULL, NULL);
- test_assert(r == -1);
- r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f:f]", &t1, NULL, NULL, NULL);
- test_assert(r == -1);
- /* Test for V4-mapped address with mask < 96. (arguably not valid) */
- r=tor_addr_parse_mask_ports("[::ffff:1.1.2.2/33]", &t1, &mask, NULL, NULL);
- test_assert(r == -1);
- r=tor_addr_parse_mask_ports("1.1.2.2/33", &t1, &mask, NULL, NULL);
- test_assert(r == -1);
- r=tor_addr_parse_mask_ports("1.1.2.2/31", &t1, &mask, NULL, NULL);
- test_assert(r == AF_INET);
- r=tor_addr_parse_mask_ports("[efef::]/112", &t1, &mask, &port1, &port2);
- test_assert(r == AF_INET6);
- test_assert(port1 == 1);
- test_assert(port2 == 65535);
- /* make sure inet address lengths >= max */
- test_assert(INET_NTOA_BUF_LEN >= sizeof("255.255.255.255"));
- test_assert(TOR_ADDR_BUF_LEN >=
- sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"));
- test_assert(sizeof(tor_addr_t) >= sizeof(struct in6_addr));
- /* get interface addresses */
- r = get_interface_address6(LOG_DEBUG, AF_INET, &t1);
- i = get_interface_address6(LOG_DEBUG, AF_INET6, &t2);
- #if 0
- tor_inet_ntop(AF_INET, &t1.sa.sin_addr, buf, sizeof(buf));
- printf("nv4 address: %s (family=%i)", buf, IN_FAMILY(&t1));
- tor_inet_ntop(AF_INET6, &t2.sa6.sin6_addr, buf, sizeof(buf));
- printf("nv6 address: %s (family=%i)", buf, IN_FAMILY(&t2));
- #endif
- done:
- ;
- }
- /** Run unit tests for basic dynamic-sized array functionality. */
- static void
- test_util_smartlist_basic(void)
- {
- smartlist_t *sl;
- /* XXXX test sort_digests, uniq_strings, uniq_digests */
- /* Test smartlist add, del_keeporder, insert, get. */
- sl = smartlist_create();
- smartlist_add(sl, (void*)1);
- smartlist_add(sl, (void*)2);
- smartlist_add(sl, (void*)3);
- smartlist_add(sl, (void*)4);
- smartlist_del_keeporder(sl, 1);
- smartlist_insert(sl, 1, (void*)22);
- smartlist_insert(sl, 0, (void*)0);
- smartlist_insert(sl, 5, (void*)555);
- test_eq_ptr((void*)0, smartlist_get(sl,0));
- test_eq_ptr((void*)1, smartlist_get(sl,1));
- test_eq_ptr((void*)22, smartlist_get(sl,2));
- test_eq_ptr((void*)3, smartlist_get(sl,3));
- test_eq_ptr((void*)4, smartlist_get(sl,4));
- test_eq_ptr((void*)555, smartlist_get(sl,5));
- /* Try deleting in the middle. */
- smartlist_del(sl, 1);
- test_eq_ptr((void*)555, smartlist_get(sl, 1));
- /* Try deleting at the end. */
- smartlist_del(sl, 4);
- test_eq(4, smartlist_len(sl));
- /* test isin. */
- test_assert(smartlist_isin(sl, (void*)3));
- test_assert(!smartlist_isin(sl, (void*)99));
- done:
- smartlist_free(sl);
- }
- /** Run unit tests for smartlist-of-strings functionality. */
- static void
- test_util_smartlist_strings(void)
- {
- smartlist_t *sl = smartlist_create();
- char *cp=NULL, *cp_alloc=NULL;
- size_t sz;
- /* Test split and join */
- test_eq(0, smartlist_len(sl));
- smartlist_split_string(sl, "abc", ":", 0, 0);
- test_eq(1, smartlist_len(sl));
- test_streq("abc", smartlist_get(sl, 0));
- smartlist_split_string(sl, "a::bc::", "::", 0, 0);
- test_eq(4, smartlist_len(sl));
- test_streq("a", smartlist_get(sl, 1));
- test_streq("bc", smartlist_get(sl, 2));
- test_streq("", smartlist_get(sl, 3));
- cp_alloc = smartlist_join_strings(sl, "", 0, NULL);
- test_streq(cp_alloc, "abcabc");
- tor_free(cp_alloc);
- cp_alloc = smartlist_join_strings(sl, "!", 0, NULL);
- test_streq(cp_alloc, "abc!a!bc!");
- tor_free(cp_alloc);
- cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL);
- test_streq(cp_alloc, "abcXYaXYbcXY");
- tor_free(cp_alloc);
- cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL);
- test_streq(cp_alloc, "abcXYaXYbcXYXY");
- tor_free(cp_alloc);
- cp_alloc = smartlist_join_strings(sl, "", 1, NULL);
- test_streq(cp_alloc, "abcabc");
- tor_free(cp_alloc);
- smartlist_split_string(sl, "/def/ /ghijk", "/", 0, 0);
- test_eq(8, smartlist_len(sl));
- test_streq("", smartlist_get(sl, 4));
- test_streq("def", smartlist_get(sl, 5));
- test_streq(" ", smartlist_get(sl, 6));
- test_streq("ghijk", smartlist_get(sl, 7));
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_clear(sl);
- smartlist_split_string(sl, "a,bbd,cdef", ",", SPLIT_SKIP_SPACE, 0);
- test_eq(3, smartlist_len(sl));
- test_streq("a", smartlist_get(sl,0));
- test_streq("bbd", smartlist_get(sl,1));
- test_streq("cdef", smartlist_get(sl,2));
- smartlist_split_string(sl, " z <> zhasd <> <> bnud<> ", "<>",
- SPLIT_SKIP_SPACE, 0);
- test_eq(8, smartlist_len(sl));
- test_streq("z", smartlist_get(sl,3));
- test_streq("zhasd", smartlist_get(sl,4));
- test_streq("", smartlist_get(sl,5));
- test_streq("bnud", smartlist_get(sl,6));
- test_streq("", smartlist_get(sl,7));
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_clear(sl);
- smartlist_split_string(sl, " abtc td ef ", NULL,
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- test_eq(4, smartlist_len(sl));
- test_streq("ab", smartlist_get(sl,0));
- test_streq("c", smartlist_get(sl,1));
- test_streq("d", smartlist_get(sl,2));
- test_streq("ef", smartlist_get(sl,3));
- smartlist_split_string(sl, "ghitj", NULL,
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- test_eq(6, smartlist_len(sl));
- test_streq("ghi", smartlist_get(sl,4));
- test_streq("j", smartlist_get(sl,5));
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_clear(sl);
- cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL);
- test_streq(cp_alloc, "");
- tor_free(cp_alloc);
- cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL);
- test_streq(cp_alloc, "XY");
- tor_free(cp_alloc);
- smartlist_split_string(sl, " z <> zhasd <> <> bnud<> ", "<>",
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- test_eq(3, smartlist_len(sl));
- test_streq("z", smartlist_get(sl, 0));
- test_streq("zhasd", smartlist_get(sl, 1));
- test_streq("bnud", smartlist_get(sl, 2));
- smartlist_split_string(sl, " z <> zhasd <> <> bnud<> ", "<>",
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
- test_eq(5, smartlist_len(sl));
- test_streq("z", smartlist_get(sl, 3));
- test_streq("zhasd <> <> bnud<>", smartlist_get(sl, 4));
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_clear(sl);
- smartlist_split_string(sl, "abcdn", "n",
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- test_eq(1, smartlist_len(sl));
- test_streq("abcd", smartlist_get(sl, 0));
- smartlist_split_string(sl, "efgh", "n",
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- test_eq(2, smartlist_len(sl));
- test_streq("efgh", smartlist_get(sl, 1));
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_clear(sl);
- /* Test swapping, shuffling, and sorting. */
- smartlist_split_string(sl, "the,onion,router,by,arma,and,nickm", ",", 0, 0);
- test_eq(7, smartlist_len(sl));
- smartlist_sort(sl, _compare_strs);
- cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
- test_streq(cp_alloc,"and,arma,by,nickm,onion,router,the");
- tor_free(cp_alloc);
- smartlist_swap(sl, 1, 5);
- cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
- test_streq(cp_alloc,"and,router,by,nickm,onion,arma,the");
- tor_free(cp_alloc);
- smartlist_shuffle(sl);
- test_eq(7, smartlist_len(sl));
- test_assert(smartlist_string_isin(sl, "and"));
- test_assert(smartlist_string_isin(sl, "router"));
- test_assert(smartlist_string_isin(sl, "by"));
- test_assert(smartlist_string_isin(sl, "nickm"));
- test_assert(smartlist_string_isin(sl, "onion"));
- test_assert(smartlist_string_isin(sl, "arma"));
- test_assert(smartlist_string_isin(sl, "the"));
- /* Test bsearch. */
- smartlist_sort(sl, _compare_strs);
- test_streq("nickm", smartlist_bsearch(sl, "zNicKM",
- _compare_without_first_ch));
- test_streq("and", smartlist_bsearch(sl, " AND", _compare_without_first_ch));
- test_eq_ptr(NULL, smartlist_bsearch(sl, " ANz", _compare_without_first_ch));
- /* Test bsearch_idx */
- {
- int f;
- test_eq(0, smartlist_bsearch_idx(sl," aaa",_compare_without_first_ch,&f));
- test_eq(f, 0);
- test_eq(0, smartlist_bsearch_idx(sl," and",_compare_without_first_ch,&f));
- test_eq(f, 1);
- test_eq(1, smartlist_bsearch_idx(sl," arm",_compare_without_first_ch,&f));
- test_eq(f, 0);
- test_eq(1, smartlist_bsearch_idx(sl," arma",_compare_without_first_ch,&f));
- test_eq(f, 1);
- test_eq(2, smartlist_bsearch_idx(sl," armb",_compare_without_first_ch,&f));
- test_eq(f, 0);
- test_eq(7, smartlist_bsearch_idx(sl," zzzz",_compare_without_first_ch,&f));
- test_eq(f, 0);
- }
- /* Test reverse() and pop_last() */
- smartlist_reverse(sl);
- cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
- test_streq(cp_alloc,"the,router,onion,nickm,by,arma,and");
- tor_free(cp_alloc);
- cp_alloc = smartlist_pop_last(sl);
- test_streq(cp_alloc, "and");
- tor_free(cp_alloc);
- test_eq(smartlist_len(sl), 6);
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_clear(sl);
- cp_alloc = smartlist_pop_last(sl);
- test_eq(cp_alloc, NULL);
- /* Test uniq() */
- smartlist_split_string(sl,
- "50,noon,radar,a,man,a,plan,a,canal,panama,radar,noon,50",
- ",", 0, 0);
- smartlist_sort(sl, _compare_strs);
- smartlist_uniq(sl, _compare_strs, _tor_free);
- cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
- test_streq(cp_alloc, "50,a,canal,man,noon,panama,plan,radar");
- tor_free(cp_alloc);
- /* Test string_isin and isin_case and num_isin */
- test_assert(smartlist_string_isin(sl, "noon"));
- test_assert(!smartlist_string_isin(sl, "noonoon"));
- test_assert(smartlist_string_isin_case(sl, "nOOn"));
- test_assert(!smartlist_string_isin_case(sl, "nooNooN"));
- test_assert(smartlist_string_num_isin(sl, 50));
- test_assert(!smartlist_string_num_isin(sl, 60));
- /* Test smartlist_choose */
- {
- int i;
- int allsame = 1;
- int allin = 1;
- void *first = smartlist_choose(sl);
- test_assert(smartlist_isin(sl, first));
- for (i = 0; i < 100; ++i) {
- void *second = smartlist_choose(sl);
- if (second != first)
- allsame = 0;
- if (!smartlist_isin(sl, second))
- allin = 0;
- }
- test_assert(!allsame);
- test_assert(allin);
- }
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_clear(sl);
- /* Test string_remove and remove and join_strings2 */
- smartlist_split_string(sl,
- "Some say the Earth will end in ice and some in fire",
- " ", 0, 0);
- cp = smartlist_get(sl, 4);
- test_streq(cp, "will");
- smartlist_add(sl, cp);
- smartlist_remove(sl, cp);
- tor_free(cp);
- cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
- test_streq(cp_alloc, "Some,say,the,Earth,fire,end,in,ice,and,some,in");
- tor_free(cp_alloc);
- smartlist_string_remove(sl, "in");
- cp_alloc = smartlist_join_strings2(sl, "+XX", 1, 0, &sz);
- test_streq(cp_alloc, "Some+say+the+Earth+fire+end+some+ice+and");
- test_eq((int)sz, 40);
- done:
- SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
- smartlist_free(sl);
- tor_free(cp_alloc);
- }
- /** Run unit tests for smartlist set manipulation functions. */
- static void
- test_util_smartlist_overlap(void)
- {
- smartlist_t *sl = smartlist_create();
- smartlist_t *ints = smartlist_create();
- smartlist_t *odds = smartlist_create();
- smartlist_t *evens = smartlist_create();
- smartlist_t *primes = smartlist_create();
- int i;
- for (i=1; i < 10; i += 2)
- smartlist_add(odds, (void*)(uintptr_t)i);
- for (i=0; i < 10; i += 2)
- smartlist_add(evens, (void*)(uintptr_t)i);
- /* add_all */
- smartlist_add_all(ints, odds);
- smartlist_add_all(ints, evens);
- test_eq(smartlist_len(ints), 10);
- smartlist_add(primes, (void*)2);
- smartlist_add(primes, (void*)3);
- smartlist_add(primes, (void*)5);
- smartlist_add(primes, (void*)7);
- /* overlap */
- test_assert(smartlist_overlap(ints, odds));
- test_assert(smartlist_overlap(odds, primes));
- test_assert(smartlist_overlap(evens, primes));
- test_assert(!smartlist_overlap(odds, evens));
- /* intersect */
- smartlist_add_all(sl, odds);
- smartlist_intersect(sl, primes);
- test_eq(smartlist_len(sl), 3);
- test_assert(smartlist_isin(sl, (void*)3));
- test_assert(smartlist_isin(sl, (void*)5));
- test_assert(smartlist_isin(sl, (void*)7));
- /* subtract */
- smartlist_add_all(sl, primes);
- smartlist_subtract(sl, odds);
- test_eq(smartlist_len(sl), 1);
- test_assert(smartlist_isin(sl, (void*)2));
- done:
- smartlist_free(odds);
- smartlist_free(evens);
- smartlist_free(ints);
- smartlist_free(primes);
- smartlist_free(sl);
- }
- /** Run unit tests for smartlist-of-digests functions. */
- static void
- test_util_smartlist_digests(void)
- {
- smartlist_t *sl = smartlist_create();
- /* digest_isin. */
- smartlist_add(sl, tor_memdup("AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN));
- smartlist_add(sl, tor_memdup("