1 /* Copyright 2001,2002,2003 Roger Dingledine, Matej Pfajfar. */
2 /* See LICENSE for licensing information */
16 #include "../common/test.h"
19 dump_hex(char *s
, int len
)
21 static const char TABLE
[] = "0123456789ABCDEF";
26 nyb
= (((int) d
[i
]) >> (j
*4)) & 0x0f;
27 assert(0<=nyb
&& nyb
<=15);
37 sprintf(buf
, "/tmp/tor_test");
43 if (r
&& errno
!= EEXIST
)
44 fprintf(stderr
, "Can't create directory %s", buf
);
49 #define MAX_BUF_SIZE 1024*1024
61 if (!(buf
= buf_new()))
64 test_eq(buf_capacity(buf
), 512*1024);
65 test_eq(buf_datalen(buf
), 0);
70 s
= open("/tmp/tor_test/data", O_WRONLY
|O_CREAT
|O_TRUNC
, 0600);
77 s
= open("/tmp/tor_test/data", O_RDONLY
, 0);
79 i
= read_to_buf(s
, 10, buf
, &eof
);
80 test_eq(buf_capacity(buf
), 512*1024);
81 test_eq(buf_datalen(buf
), 10);
84 test_memeq(str
, (char*)_buf_peek_raw_buffer(buf
), 10);
86 /* Test reading 0 bytes. */
87 i
= read_to_buf(s
, 0, buf
, &eof
);
88 test_eq(buf_capacity(buf
), 512*1024);
89 test_eq(buf_datalen(buf
), 10);
93 /* Now test when buffer is filled exactly. */
94 buf2
= buf_new_with_capacity(6);
95 i
= read_to_buf(s
, 6, buf2
, &eof
);
96 test_eq(buf_capacity(buf2
), 6);
97 test_eq(buf_datalen(buf2
), 6);
100 test_memeq(str
+10, (char*)_buf_peek_raw_buffer(buf2
), 6);
103 /* Now test when buffer is filled with more data to read. */
104 buf2
= buf_new_with_capacity(32);
105 i
= read_to_buf(s
, 128, buf2
, &eof
);
106 test_eq(buf_capacity(buf2
), 128);
107 test_eq(buf_datalen(buf2
), 32);
112 /* Now read to eof. */
113 test_assert(buf_capacity(buf
) > 256);
114 i
= read_to_buf(s
, 1024, buf
, &eof
);
115 test_eq(i
, (256-32-10-6));
116 test_eq(buf_capacity(buf
), MAX_BUF_SIZE
);
117 test_eq(buf_datalen(buf
), 256-6-32);
118 test_memeq(str
, (char*)_buf_peek_raw_buffer(buf
), 10); /* XXX Check rest. */
121 i
= read_to_buf(s
, 1024, buf
, &eof
);
123 test_eq(buf_capacity(buf
), MAX_BUF_SIZE
);
124 test_eq(buf_datalen(buf
), 256-6-32);
134 s
= open("/tmp/tor_test/data", O_RDONLY
, 0);
136 i
= read_to_buf(s
, 1024, buf
, &eof
);
140 test_eq(((int)'d') + 1, find_on_inbuf("abcd", 4, buf
));
141 test_eq(-1, find_on_inbuf("xyzzy", 5, buf
));
142 /* Make sure we don't look off the end of the buffef */
143 ((char*)_buf_peek_raw_buffer(buf
))[256] = 'A';
144 ((char*)_buf_peek_raw_buffer(buf
))[257] = 'X';
145 test_eq(-1, find_on_inbuf("\xff" "A", 2, buf
));
146 test_eq(-1, find_on_inbuf("AX", 2, buf
));
147 /* Make sure we use the string length */
148 test_eq(((int)'d')+1, find_on_inbuf("abcdX", 4, buf
));
153 memset(str2
, 255, 256);
154 test_eq(246, fetch_from_buf(str2
, 10, buf
));
155 test_memeq(str2
, str
, 10);
156 test_memeq(str
+10,(char*)_buf_peek_raw_buffer(buf
),246);
157 test_eq(buf_datalen(buf
),246);
159 test_eq(0, fetch_from_buf(str2
, 246, buf
));
160 test_memeq(str2
, str
+10, 246);
161 test_eq(buf_capacity(buf
),MAX_BUF_SIZE
);
162 test_eq(buf_datalen(buf
),0);
167 memset((char *)_buf_peek_raw_buffer(buf
), (int)'-', 256);
168 i
= write_to_buf("Hello world", 11, buf
);
170 test_eq(buf_datalen(buf
), 11);
171 test_memeq((char*)_buf_peek_raw_buffer(buf
), "Hello world", 11);
172 i
= write_to_buf("XYZZY", 5, buf
);
174 test_eq(buf_datalen(buf
), 16);
175 test_memeq((char*)_buf_peek_raw_buffer(buf
), "Hello worldXYZZY", 16);
176 /* Test when buffer is overfull. */
179 test_eq(-1, write_to_buf("This string will not fit.", 25,
180 &buf
, &buflen
, &buf_datalen
));
181 test_eq(buf_datalen
, 16);
182 test_memeq(buf
, "Hello worldXYZZY--", 18);
183 buflen
= MAX_BUF_SIZE
;
189 /* XXXX Needs tests. */
197 crypto_dh_env_t
*dh1
, *dh2
;
198 char p1
[CRYPTO_DH_SIZE
];
199 char p2
[CRYPTO_DH_SIZE
];
200 char s1
[CRYPTO_DH_SIZE
];
201 char s2
[CRYPTO_DH_SIZE
];
204 dh1
= crypto_dh_new();
205 dh2
= crypto_dh_new();
206 test_eq(crypto_dh_get_bytes(dh1
), CRYPTO_DH_SIZE
);
207 test_eq(crypto_dh_get_bytes(dh2
), CRYPTO_DH_SIZE
);
209 memset(p1
, 0, CRYPTO_DH_SIZE
);
210 memset(p2
, 0, CRYPTO_DH_SIZE
);
211 test_memeq(p1
, p2
, CRYPTO_DH_SIZE
);
212 test_assert(! crypto_dh_get_public(dh1
, p1
, CRYPTO_DH_SIZE
));
213 test_memneq(p1
, p2
, CRYPTO_DH_SIZE
);
214 test_assert(! crypto_dh_get_public(dh2
, p2
, CRYPTO_DH_SIZE
));
215 test_memneq(p1
, p2
, CRYPTO_DH_SIZE
);
217 memset(s1
, 0, CRYPTO_DH_SIZE
);
218 memset(s2
, 0xFF, CRYPTO_DH_SIZE
);
219 s1len
= crypto_dh_compute_secret(dh1
, p2
, CRYPTO_DH_SIZE
, s1
, 50);
220 s2len
= crypto_dh_compute_secret(dh2
, p1
, CRYPTO_DH_SIZE
, s2
, 50);
221 test_assert(s1len
> 0);
222 test_eq(s1len
, s2len
);
223 test_memeq(s1
, s2
, s1len
);
232 crypto_cipher_env_t
*env1
, *env2
;
233 crypto_pk_env_t
*pk1
, *pk2
;
234 char *data1
, *data2
, *data3
, *cp
;
237 int str_ciphers
[] = { CRYPTO_CIPHER_IDENTITY
,
241 CRYPTO_CIPHER_AES_CTR
,
244 data1
= tor_malloc(1024);
245 data2
= tor_malloc(1024);
246 data3
= tor_malloc(1024);
247 test_assert(data1
&& data2
&& data3
);
250 test_assert(! crypto_seed_rng());
251 crypto_rand(100, data1
);
252 crypto_rand(100, data2
);
253 test_memneq(data1
,data2
,100);
255 /* Try out identity ciphers. */
256 env1
= crypto_new_cipher_env(CRYPTO_CIPHER_IDENTITY
);
258 test_eq(crypto_cipher_generate_key(env1
), 0);
259 test_eq(crypto_cipher_set_iv(env1
, ""), 0);
260 test_eq(crypto_cipher_encrypt_init_cipher(env1
), 0);
261 for(i
= 0; i
< 1024; ++i
) {
262 data1
[i
] = (char) i
*73;
264 crypto_cipher_encrypt(env1
, data1
, 1024, data2
);
265 test_memeq(data1
, data2
, 1024);
266 crypto_free_cipher_env(env1
);
268 /* Now, test encryption and decryption with stream ciphers. */
270 for(i
= 1023; i
>0; i
-= 35)
271 strncat(data1
, "Now is the time for all good onions", i
);
272 for(i
=0; str_ciphers
[i
] >= 0; ++i
) {
273 /* For each cipher... */
274 memset(data2
, 0, 1024);
275 memset(data3
, 0, 1024);
276 env1
= crypto_new_cipher_env(str_ciphers
[i
]);
278 env2
= crypto_new_cipher_env(str_ciphers
[i
]);
280 j
= crypto_cipher_generate_key(env1
);
281 if (str_ciphers
[i
] != CRYPTO_CIPHER_IDENTITY
) {
282 crypto_cipher_set_key(env2
, crypto_cipher_get_key(env1
));
284 crypto_cipher_set_iv(env1
, "12345678901234567890");
285 crypto_cipher_set_iv(env2
, "12345678901234567890");
286 crypto_cipher_encrypt_init_cipher(env1
);
287 crypto_cipher_decrypt_init_cipher(env2
);
289 /* Try encrypting 512 chars. */
290 crypto_cipher_encrypt(env1
, data1
, 512, data2
);
291 crypto_cipher_decrypt(env2
, data2
, 512, data3
);
292 test_memeq(data1
, data3
, 512);
293 if (str_ciphers
[i
] == CRYPTO_CIPHER_IDENTITY
) {
294 test_memeq(data1
, data2
, 512);
296 test_memneq(data1
, data2
, 512);
298 /* Now encrypt 1 at a time, and get 1 at a time. */
299 for (j
= 512; j
< 560; ++j
) {
300 crypto_cipher_encrypt(env1
, data1
+j
, 1, data2
+j
);
302 for (j
= 512; j
< 560; ++j
) {
303 crypto_cipher_decrypt(env2
, data2
+j
, 1, data3
+j
);
305 test_memeq(data1
, data3
, 560);
306 /* Now encrypt 3 at a time, and get 5 at a time. */
307 for (j
= 560; j
< 1024-5; j
+= 3) {
308 crypto_cipher_encrypt(env1
, data1
+j
, 3, data2
+j
);
310 for (j
= 560; j
< 1024-5; j
+= 5) {
311 crypto_cipher_decrypt(env2
, data2
+j
, 5, data3
+j
);
313 test_memeq(data1
, data3
, 1024-5);
314 /* Now make sure that when we encrypt with different chunk sizes, we get
316 crypto_free_cipher_env(env2
);
318 memset(data3
, 0, 1024);
319 env2
= crypto_new_cipher_env(str_ciphers
[i
]);
321 if (str_ciphers
[i
] != CRYPTO_CIPHER_IDENTITY
) {
322 crypto_cipher_set_key(env2
, crypto_cipher_get_key(env1
));
324 crypto_cipher_set_iv(env2
, "12345678901234567890");
325 crypto_cipher_encrypt_init_cipher(env2
);
326 for (j
= 0; j
< 1024-16; j
+= 17) {
327 crypto_cipher_encrypt(env2
, data1
+j
, 17, data3
+j
);
329 for (j
= 0; j
< 1024-16; ++j
) {
330 if (data2
[j
] != data3
[j
]) {
331 printf("%d: %d\t%d\n", j
, (int) data2
[j
], (int) data3
[j
]);
334 test_memeq(data2
, data3
, 1024-16);
335 crypto_free_cipher_env(env1
);
336 crypto_free_cipher_env(env2
);
339 /* Test vectors for stream ciphers. */
340 /* XXXX Look up some test vectors for the ciphers and make sure we match. */
342 /* Test SHA-1 with a test vector from the specification. */
343 i
= crypto_SHA_digest("abc", 3, data1
);
345 "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78"
346 "\x50\xC2\x6C\x9C\xD0\xD8\x9D", 20);
348 /* Public-key ciphers */
349 pk1
= crypto_new_pk_env(CRYPTO_PK_RSA
);
350 pk2
= crypto_new_pk_env(CRYPTO_PK_RSA
);
351 test_assert(pk1
&& pk2
);
352 test_assert(! crypto_pk_generate_key(pk1
));
353 test_assert(! crypto_pk_write_public_key_to_string(pk1
, &cp
, &i
));
354 test_assert(! crypto_pk_read_public_key_from_string(pk2
, cp
, i
));
355 test_eq(0, crypto_pk_cmp_keys(pk1
, pk2
));
357 test_eq(128, crypto_pk_keysize(pk1
));
358 test_eq(128, crypto_pk_keysize(pk2
));
360 test_eq(128, crypto_pk_public_encrypt(pk2
, "Hello whirled.", 15, data1
,
361 RSA_PKCS1_OAEP_PADDING
));
362 test_eq(128, crypto_pk_public_encrypt(pk1
, "Hello whirled.", 15, data2
,
363 RSA_PKCS1_OAEP_PADDING
));
364 /* oaep padding should make encryption not match */
365 test_memneq(data1
, data2
, 128);
366 test_eq(15, crypto_pk_private_decrypt(pk1
, data1
, 128, data3
,
367 RSA_PKCS1_OAEP_PADDING
));
368 test_streq(data3
, "Hello whirled.");
369 memset(data3
, 0, 1024);
370 test_eq(15, crypto_pk_private_decrypt(pk1
, data2
, 128, data3
,
371 RSA_PKCS1_OAEP_PADDING
));
372 test_streq(data3
, "Hello whirled.");
373 /* Can't decrypt with public key. */
374 test_eq(-1, crypto_pk_private_decrypt(pk2
, data2
, 128, data3
,
375 RSA_PKCS1_OAEP_PADDING
));
376 /* Try again with bad padding */
377 memcpy(data2
+1, "XYZZY", 5); /* This has fails ~ once-in-2^40 */
378 test_eq(-1, crypto_pk_private_decrypt(pk1
, data2
, 128, data3
,
379 RSA_PKCS1_OAEP_PADDING
));
381 /* File operations: save and load private key */
382 f
= fopen("/tmp/tor_test/pkey1", "wb");
383 test_assert(! crypto_pk_write_private_key_to_file(pk1
, f
));
385 f
= fopen("/tmp/tor_test/pkey1", "rb");
386 test_assert(! crypto_pk_read_private_key_from_file(pk2
, f
));
388 test_eq(15, crypto_pk_private_decrypt(pk2
, data1
, 128, data3
,
389 RSA_PKCS1_OAEP_PADDING
));
390 test_assert(! crypto_pk_read_private_key_from_filename(pk2
,
391 "/tmp/tor_test/pkey1"));
392 test_eq(15, crypto_pk_private_decrypt(pk2
, data1
, 128, data3
,
393 RSA_PKCS1_OAEP_PADDING
));
395 /* Now try signing. */
396 strcpy(data1
, "Ossifrage");
397 test_eq(128, crypto_pk_private_sign(pk1
, data1
, 10, data2
));
398 test_eq(10, crypto_pk_public_checksig(pk1
, data2
, 128, data3
));
399 test_streq(data3
, "Ossifrage");
400 /*XXXX test failed signing*/
402 crypto_free_pk_env(pk1
);
403 crypto_free_pk_env(pk2
);
406 strcpy(data1
, "Test string that contains 35 chars.");
407 strcat(data1
, " 2nd string that contains 35 chars.");
409 i
= base64_encode(data2
, 1024, data1
, 71);
410 j
= base64_decode(data3
, 1024, data2
, i
);
411 test_streq(data3
, data1
);
413 test_assert(data2
[i
] == '\0');
424 struct timeval start
, end
;
428 start
.tv_usec
= 5000;
433 test_eq(0L, tv_udiff(&start
, &end
));
437 test_eq(2000L, tv_udiff(&start
, &end
));
441 test_eq(1002000L, tv_udiff(&start
, &end
));
445 test_eq(995000L, tv_udiff(&start
, &end
));
449 test_eq(0L, tv_udiff(&start
, &end
));
451 /* The test values here are confirmed to be correct on a platform
452 * with a working timegm. */
453 a_time
.tm_year
= 2003-1900;
459 test_eq((time_t) 1062224095UL, tor_timegm(&a_time
));
460 a_time
.tm_year
= 2004-1900; /* Try a leap year, after feb. */
461 test_eq((time_t) 1093846495UL, tor_timegm(&a_time
));
462 a_time
.tm_mon
= 1; /* Try a leap year, in feb. */
464 test_eq((time_t) 1076393695UL, tor_timegm(&a_time
));
471 names
= parse_nickname_list(" foo bar baz quux ", &num
);
473 test_streq(names
[0],"foo");
474 test_streq(names
[1],"bar");
475 test_streq(names
[2],"baz");
476 test_streq(names
[3],"quux");
483 test_onion_handshake() {
485 crypto_dh_env_t
*c_dh
= NULL
;
486 char c_buf
[DH_ONIONSKIN_LEN
];
490 char s_buf
[DH_KEY_LEN
];
494 crypto_pk_env_t
*pk
= NULL
;
496 pk
= crypto_new_pk_env(CRYPTO_PK_RSA
);
497 test_assert(! crypto_pk_generate_key(pk
));
499 /* client handshake 1. */
500 memset(c_buf
, 0, DH_ONIONSKIN_LEN
);
501 test_assert(! onion_skin_create(pk
, &c_dh
, c_buf
));
503 /* server handshake */
504 memset(s_buf
, 0, DH_KEY_LEN
);
505 memset(s_keys
, 0, 40);
506 test_assert(! onion_skin_server_handshake(c_buf
, pk
, s_buf
, s_keys
, 40));
508 /* client handshake 2 */
509 memset(c_keys
, 0, 40);
510 test_assert(! onion_skin_client_handshake(c_dh
, s_buf
, c_keys
, 40));
512 crypto_dh_free(c_dh
);
514 if (memcmp(c_keys
, s_keys
, 40)) {
518 test_memeq(c_keys
, s_keys
, 40);
519 memset(s_buf
, 0, 40);
520 test_memneq(c_keys
, s_buf
, 40);
521 crypto_free_pk_env(pk
);
525 int compare_recommended_versions(char *myversion
, char *start
);
530 char buf
[8192], buf2
[8192];
531 char *pk1_str
= NULL
, *pk2_str
= NULL
, *pk3_str
= NULL
, *cp
;
532 int pk1_str_len
, pk2_str_len
, pk3_str_len
;
534 crypto_pk_env_t
*pk1
= NULL
, *pk2
= NULL
, *pk3
= NULL
;
535 routerinfo_t
*rp1
= NULL
, *rp2
= NULL
;
536 struct exit_policy_t ex1
, ex2
;
537 routerlist_t
*dir1
= NULL
, *dir2
= NULL
;
539 test_assert( (pk1
= crypto_new_pk_env(CRYPTO_PK_RSA
)) );
540 test_assert( (pk2
= crypto_new_pk_env(CRYPTO_PK_RSA
)) );
541 test_assert( (pk3
= crypto_new_pk_env(CRYPTO_PK_RSA
)) );
542 test_assert(! crypto_pk_generate_key(pk1
));
543 test_assert(! crypto_pk_generate_key(pk2
));
544 test_assert(! crypto_pk_generate_key(pk3
));
546 r1
.address
= "testaddr1.foo.bar";
547 r1
.addr
= 0xc0a80001u
; /* 192.168.0.1 */
550 r1
.socks_port
= 9002;
553 r1
.identity_pkey
= pk2
;
556 r1
.exit_policy
= NULL
;
557 r1
.nickname
= "Magri";
559 ex1
.policy_type
= EXIT_POLICY_ACCEPT
;
565 ex2
.policy_type
= EXIT_POLICY_REJECT
;
567 ex2
.msk
= 0xFF000000u
;
570 r2
.address
= "tor.tor.tor";
571 r2
.addr
= 0x0a030201u
; /* 10.3.2.1 */
577 r2
.identity_pkey
= pk1
;
580 r2
.exit_policy
= &ex1
;
582 test_assert(!crypto_pk_write_public_key_to_string(pk1
, &pk1_str
,
584 test_assert(!crypto_pk_write_public_key_to_string(pk2
, &pk2_str
,
586 test_assert(!crypto_pk_write_public_key_to_string(pk3
, &pk3_str
,
589 memset(buf
, 0, 2048);
590 log_set_severity(LOG_WARN
);
591 test_assert(router_dump_router_to_string(buf
, 2048, &r1
, pk2
)>0);
593 strcpy(buf2
, "router Magri testaddr1.foo.bar 9000 9002 9003 1000\n"
594 "platform Tor "VERSION
" on ");
595 strcat(buf2
, get_uname());
597 "published 1970-01-01 00:00:00\n"
599 strcat(buf2
, pk1_str
);
600 strcat(buf2
, "link-key\n");
601 strcat(buf2
, pk3_str
);
602 strcat(buf2
, "signing-key\n");
603 strcat(buf2
, pk2_str
);
604 strcat(buf2
, "router-signature\n");
605 buf
[strlen(buf2
)] = '\0'; /* Don't compare the sig; it's never the same twice*/
607 test_streq(buf
, buf2
);
609 test_assert(router_dump_router_to_string(buf
, 2048, &r1
, pk2
)>0);
611 rp1
= router_get_entry_from_string(&cp
);
613 test_streq(rp1
->address
, r1
.address
);
614 test_eq(rp1
->or_port
, r1
.or_port
);
615 test_eq(rp1
->socks_port
, r1
.socks_port
);
616 test_eq(rp1
->dir_port
, r1
.dir_port
);
617 test_eq(rp1
->bandwidth
, r1
.bandwidth
);
618 test_assert(crypto_pk_cmp_keys(rp1
->onion_pkey
, pk1
) == 0);
619 test_assert(crypto_pk_cmp_keys(rp1
->link_pkey
, pk3
) == 0);
620 test_assert(crypto_pk_cmp_keys(rp1
->identity_pkey
, pk2
) == 0);
621 test_assert(rp1
->exit_policy
== NULL
);
624 /* XXX Once we have exit policies, test this again. XXX */
625 strcpy(buf2
, "router tor.tor.tor 9005 0 0 3000\n");
626 strcat(buf2
, pk2_str
);
627 strcat(buf2
, "signing-key\n");
628 strcat(buf2
, pk1_str
);
629 strcat(buf2
, "accept *:80\nreject 18.*:24\n\n");
630 test_assert(router_dump_router_to_string(buf
, 2048, &r2
, pk2
)>0);
631 test_streq(buf
, buf2
);
634 rp2
= router_get_entry_from_string(&cp
);
636 test_streq(rp2
->address
, r2
.address
);
637 test_eq(rp2
->or_port
, r2
.or_port
);
638 test_eq(rp2
->socks_port
, r2
.socks_port
);
639 test_eq(rp2
->dir_port
, r2
.dir_port
);
640 test_eq(rp2
->bandwidth
, r2
.bandwidth
);
641 test_assert(crypto_pk_cmp_keys(rp2
->onion_pkey
, pk2
) == 0);
642 test_assert(crypto_pk_cmp_keys(rp2
->identity_pkey
, pk1
) == 0);
643 test_eq(rp2
->exit_policy
->policy_type
, EXIT_POLICY_ACCEPT
);
644 test_streq(rp2
->exit_policy
->string
, "accept *:80");
645 test_streq(rp2
->exit_policy
->address
, "*");
646 test_streq(rp2
->exit_policy
->port
, "80");
647 test_eq(rp2
->exit_policy
->next
->policy_type
, EXIT_POLICY_REJECT
);
648 test_streq(rp2
->exit_policy
->next
->string
, "reject 18.*:24");
649 test_streq(rp2
->exit_policy
->next
->address
, "18.*");
650 test_streq(rp2
->exit_policy
->next
->port
, "24");
651 test_assert(rp2
->exit_policy
->next
->next
== NULL
);
655 /* XXX To re-enable this test, we need to separate directory generation
656 * XXX from the directory backend again. Do this the next time we have
657 * XXX directory trouble. */
658 /* Okay, now for the directories. */
659 dir1
= (directory_t
*) tor_malloc(sizeof(directory_t
));
661 dir1
->routers
= (routerinfo_t
**) tor_malloc(sizeof(routerinfo_t
*)*2);
662 dir1
->routers
[0] = &r1
;
663 dir1
->routers
[1] = &r2
;
664 test_assert(! dump_signed_directory_to_string_impl(buf
, 4096, dir1
, pk1
));
667 test_assert(! router_get_dir_from_string_impl(buf
, &dir2
, pk1
));
668 test_eq(2, dir2
->n_routers
);
673 if (pk1
) crypto_free_pk_env(pk1
);
674 if (pk2
) crypto_free_pk_env(pk2
);
675 if (rp1
) routerinfo_free(rp1
);
676 if (rp2
) routerinfo_free(rp2
);
677 tor_free(dir1
); /* And more !*/
678 tor_free(dir2
); /* And more !*/
680 /* make sure compare_recommended_versions() works */
681 test_eq(0, compare_recommended_versions("abc", "abc"));
682 test_eq(0, compare_recommended_versions("abc", "ab,abd,abde,abc,abcde"));
683 test_eq(0, compare_recommended_versions("abc", "ab,abd,abde,abcde,abc"));
684 test_eq(0, compare_recommended_versions("abc", "abc,abd,abde,abc,abcde"));
685 test_eq(0, compare_recommended_versions("a", "a,ab,abd,abde,abc,abcde"));
686 test_eq(-1, compare_recommended_versions("a", "ab,abd,abde,abc,abcde"));
687 test_eq(-1, compare_recommended_versions("abb", "ab,abd,abde,abc,abcde"));
688 test_eq(-1, compare_recommended_versions("a", ""));
692 main(int c
, char**v
){
694 or_options_t options
; /* command-line and config-file options */
696 if(getconfig(c
,v
,&options
))
699 log_set_severity(LOG_ERR
); /* make logging quieter */
704 puts("========================== Buffers =========================");
706 puts("\n========================== Crypto ==========================");
709 puts("\n========================= Util ============================");
711 puts("\n========================= Onion Skins =====================");
713 test_onion_handshake();
714 puts("\n========================= Directory Formats ===============");