2017-03-15 21:13:17 +01:00
|
|
|
/* Copyright (c) 2013-2017, The Tor Project, Inc. */
|
2013-07-18 21:51:29 +02:00
|
|
|
/* See LICENSE for licensing information */
|
|
|
|
|
|
|
|
#define CONNECTION_PRIVATE
|
2013-07-18 22:23:48 +02:00
|
|
|
#define EXT_ORPORT_PRIVATE
|
2013-08-01 19:19:07 +02:00
|
|
|
#define MAIN_PRIVATE
|
2013-07-18 21:51:29 +02:00
|
|
|
#include "or.h"
|
2013-07-18 22:23:48 +02:00
|
|
|
#include "buffers.h"
|
2013-07-18 21:51:29 +02:00
|
|
|
#include "connection.h"
|
2013-08-01 23:29:10 +02:00
|
|
|
#include "connection_or.h"
|
2013-08-01 22:24:20 +02:00
|
|
|
#include "config.h"
|
2013-08-01 19:19:07 +02:00
|
|
|
#include "control.h"
|
2013-07-18 21:51:29 +02:00
|
|
|
#include "ext_orport.h"
|
2013-08-01 19:19:07 +02:00
|
|
|
#include "main.h"
|
2013-07-18 21:51:29 +02:00
|
|
|
#include "test.h"
|
|
|
|
|
|
|
|
/* Test connection_or_remove_from_ext_or_id_map and
|
|
|
|
* connection_or_set_ext_or_identifier */
|
|
|
|
static void
|
|
|
|
test_ext_or_id_map(void *arg)
|
|
|
|
{
|
|
|
|
or_connection_t *c1 = NULL, *c2 = NULL, *c3 = NULL;
|
|
|
|
char *idp = NULL, *idp2 = NULL;
|
|
|
|
(void)arg;
|
|
|
|
|
|
|
|
/* pre-initialization */
|
2014-11-12 19:42:01 +01:00
|
|
|
tt_ptr_op(NULL, OP_EQ,
|
|
|
|
connection_or_get_by_ext_or_id("xxxxxxxxxxxxxxxxxxxx"));
|
2013-07-18 21:51:29 +02:00
|
|
|
|
|
|
|
c1 = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
|
|
|
|
c2 = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
|
|
|
|
c3 = or_connection_new(CONN_TYPE_OR, AF_INET);
|
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_ptr_op(c1->ext_or_conn_id, OP_NE, NULL);
|
|
|
|
tt_ptr_op(c2->ext_or_conn_id, OP_NE, NULL);
|
|
|
|
tt_ptr_op(c3->ext_or_conn_id, OP_EQ, NULL);
|
2013-07-18 21:51:29 +02:00
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_ptr_op(c1, OP_EQ, connection_or_get_by_ext_or_id(c1->ext_or_conn_id));
|
|
|
|
tt_ptr_op(c2, OP_EQ, connection_or_get_by_ext_or_id(c2->ext_or_conn_id));
|
2014-11-12 19:42:01 +01:00
|
|
|
tt_ptr_op(NULL, OP_EQ,
|
|
|
|
connection_or_get_by_ext_or_id("xxxxxxxxxxxxxxxxxxxx"));
|
2013-07-18 21:51:29 +02:00
|
|
|
|
|
|
|
idp = tor_memdup(c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN);
|
|
|
|
|
|
|
|
/* Give c2 a new ID. */
|
|
|
|
connection_or_set_ext_or_identifier(c2);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(idp, OP_NE, c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN);
|
2013-07-18 21:51:29 +02:00
|
|
|
idp2 = tor_memdup(c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN);
|
|
|
|
tt_assert(!tor_digest_is_zero(idp2));
|
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_ptr_op(NULL, OP_EQ, connection_or_get_by_ext_or_id(idp));
|
|
|
|
tt_ptr_op(c2, OP_EQ, connection_or_get_by_ext_or_id(idp2));
|
2013-07-18 21:51:29 +02:00
|
|
|
|
|
|
|
/* Now remove it. */
|
|
|
|
connection_or_remove_from_ext_or_id_map(c2);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_ptr_op(NULL, OP_EQ, connection_or_get_by_ext_or_id(idp));
|
|
|
|
tt_ptr_op(NULL, OP_EQ, connection_or_get_by_ext_or_id(idp2));
|
2013-07-18 21:51:29 +02:00
|
|
|
|
|
|
|
done:
|
|
|
|
if (c1)
|
|
|
|
connection_free_(TO_CONN(c1));
|
|
|
|
if (c2)
|
|
|
|
connection_free_(TO_CONN(c2));
|
|
|
|
if (c3)
|
|
|
|
connection_free_(TO_CONN(c3));
|
|
|
|
tor_free(idp);
|
|
|
|
tor_free(idp2);
|
|
|
|
connection_or_clear_ext_or_id_map();
|
|
|
|
}
|
|
|
|
|
2013-07-18 22:23:48 +02:00
|
|
|
/* Simple connection_write_to_buf_impl_ replacement that unconditionally
|
|
|
|
* writes to outbuf. */
|
|
|
|
static void
|
|
|
|
connection_write_to_buf_impl_replacement(const char *string, size_t len,
|
2017-04-27 03:36:02 +02:00
|
|
|
connection_t *conn, int compressed)
|
2013-07-18 22:23:48 +02:00
|
|
|
{
|
2017-04-27 03:36:02 +02:00
|
|
|
(void) compressed;
|
2013-07-18 22:23:48 +02:00
|
|
|
|
|
|
|
tor_assert(string);
|
|
|
|
tor_assert(conn);
|
|
|
|
write_to_buf(string, len, conn->outbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
buf_get_contents(buf_t *buf, size_t *sz_out)
|
|
|
|
{
|
|
|
|
char *out;
|
|
|
|
*sz_out = buf_datalen(buf);
|
|
|
|
if (*sz_out >= ULONG_MAX)
|
|
|
|
return NULL; /* C'mon, really? */
|
|
|
|
out = tor_malloc(*sz_out + 1);
|
|
|
|
if (fetch_from_buf(out, (unsigned long)*sz_out, buf) != 0) {
|
|
|
|
tor_free(out);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
out[*sz_out] = '\0'; /* Hopefully gratuitous. */
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_ext_or_write_command(void *arg)
|
|
|
|
{
|
|
|
|
or_connection_t *c1;
|
|
|
|
char *cp = NULL;
|
|
|
|
char *buf = NULL;
|
|
|
|
size_t sz;
|
|
|
|
|
|
|
|
(void) arg;
|
|
|
|
MOCK(connection_write_to_buf_impl_,
|
|
|
|
connection_write_to_buf_impl_replacement);
|
|
|
|
|
|
|
|
c1 = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
|
|
|
|
tt_assert(c1);
|
|
|
|
|
|
|
|
/* Length too long */
|
|
|
|
tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 100, "X", 100000),
|
2014-11-12 19:28:07 +01:00
|
|
|
OP_LT, 0);
|
2013-07-18 22:23:48 +02:00
|
|
|
|
|
|
|
/* Empty command */
|
|
|
|
tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 0x99, NULL, 0),
|
2014-11-12 19:28:07 +01:00
|
|
|
OP_EQ, 0);
|
2013-07-18 22:23:48 +02:00
|
|
|
cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(sz, OP_EQ, 4);
|
|
|
|
tt_mem_op(cp, OP_EQ, "\x00\x99\x00\x00", 4);
|
2013-07-18 22:23:48 +02:00
|
|
|
tor_free(cp);
|
|
|
|
|
|
|
|
/* Medium command. */
|
|
|
|
tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 0x99,
|
2014-11-12 19:28:07 +01:00
|
|
|
"Wai\0Hello", 9), OP_EQ, 0);
|
2013-07-18 22:23:48 +02:00
|
|
|
cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(sz, OP_EQ, 13);
|
|
|
|
tt_mem_op(cp, OP_EQ, "\x00\x99\x00\x09Wai\x00Hello", 13);
|
2013-07-18 22:23:48 +02:00
|
|
|
tor_free(cp);
|
|
|
|
|
|
|
|
/* Long command */
|
|
|
|
buf = tor_malloc(65535);
|
|
|
|
memset(buf, 'x', 65535);
|
|
|
|
tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 0xf00d,
|
2014-11-12 19:28:07 +01:00
|
|
|
buf, 65535), OP_EQ, 0);
|
2013-07-18 22:23:48 +02:00
|
|
|
cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(sz, OP_EQ, 65539);
|
|
|
|
tt_mem_op(cp, OP_EQ, "\xf0\x0d\xff\xff", 4);
|
|
|
|
tt_mem_op(cp+4, OP_EQ, buf, 65535);
|
2013-07-18 22:23:48 +02:00
|
|
|
tor_free(cp);
|
|
|
|
|
|
|
|
done:
|
|
|
|
if (c1)
|
|
|
|
connection_free_(TO_CONN(c1));
|
|
|
|
tor_free(cp);
|
|
|
|
tor_free(buf);
|
|
|
|
UNMOCK(connection_write_to_buf_impl_);
|
|
|
|
}
|
|
|
|
|
2013-08-14 17:00:08 +02:00
|
|
|
static int
|
|
|
|
write_bytes_to_file_fail(const char *fname, const char *str, size_t len,
|
|
|
|
int bin)
|
|
|
|
{
|
|
|
|
(void) fname;
|
|
|
|
(void) str;
|
|
|
|
(void) len;
|
|
|
|
(void) bin;
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-08-01 22:24:20 +02:00
|
|
|
static void
|
|
|
|
test_ext_or_init_auth(void *arg)
|
|
|
|
{
|
|
|
|
or_options_t *options = get_options_mutable();
|
|
|
|
const char *fn;
|
|
|
|
char *cp = NULL;
|
|
|
|
struct stat st;
|
|
|
|
char cookie0[32];
|
|
|
|
(void)arg;
|
|
|
|
|
|
|
|
/* Check default filename location */
|
2014-04-26 20:48:30 +02:00
|
|
|
tor_free(options->DataDirectory);
|
2013-08-01 22:24:20 +02:00
|
|
|
options->DataDirectory = tor_strdup("foo");
|
|
|
|
cp = get_ext_or_auth_cookie_file_name();
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_str_op(cp, OP_EQ, "foo"PATH_SEPARATOR"extended_orport_auth_cookie");
|
2013-08-01 22:24:20 +02:00
|
|
|
tor_free(cp);
|
|
|
|
|
|
|
|
/* Shouldn't be initialized already, or our tests will be a bit
|
|
|
|
* meaningless */
|
2013-06-04 19:00:28 +02:00
|
|
|
ext_or_auth_cookie = tor_malloc_zero(32);
|
Use coccinelle scripts to clean up our unit tests
This should get rid of most of the users of the old test_*
functions. Some are in macros and will need manual cleanup, though.
This patch is for 13119, and was automatically generated with these
scripts. The perl scripts are there because coccinelle hates
operators as macro arguments.
------------------------------
s/==,/_X_EQ_,/g;
s/!=,/_X_NE_,/g;
s/<,/_X_LT_,/g;
s/>,/_X_GT_,/g;
s/>=,/_X_GEQ_,/g;
s/<=,/_X_LEQ_,/g;
------------------------------
@@
expression a;
identifier func;
@@
func (...) {
<...
-test_fail_msg
+TT_DIE
(
+(
a
+)
)
...>
}
@@
identifier func;
@@
func (...) {
<...
-test_fail()
+TT_DIE(("Assertion failed."))
...>
}
@@
expression a;
identifier func;
@@
func (...) {
<...
-test_assert
+tt_assert
(a)
...>
}
@@
expression a, b;
identifier func;
@@
func (...) {
<...
-test_eq
+tt_int_op
(a,
+_X_EQ_,
b)
...>
}
@@
expression a, b;
identifier func;
@@
func (...) {
<...
-test_neq
+tt_int_op
(a,
+_X_NEQ_,
b)
...>
}
@@
expression a, b;
identifier func;
@@
func (...) {
<...
-test_streq
+tt_str_op
(a,
+_X_EQ_,
b)
...>
}
@@
expression a, b;
identifier func;
@@
func (...) {
<...
-test_strneq
+tt_str_op
(a,
+_X_NEQ_,
b)
...>
}
@@
expression a, b;
identifier func;
@@
func (...) {
<...
-test_eq_ptr
+tt_ptr_op
(a,
+_X_EQ_,
b)
...>
}
@@
expression a, b;
identifier func;
@@
func() {
<...
-test_neq_ptr
+tt_ptr_op
(a,
+_X_NEQ_,
b)
...>
}
@@
expression a, b, len;
identifier func;
@@
func (...) {
<...
-test_memeq
+tt_mem_op
(a,
+_X_EQ_,
b, len)
...>
}
@@
expression a, b, len;
identifier func;
@@
func (...) {
<...
-test_memneq
+tt_mem_op
(a,
+_X_NEQ_,
b, len)
...>
}
------------------------------
@@
char a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a == b
+a, _X_EQ_, b
)
...>
}
@@
int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a == b
+a, _X_EQ_, b
)
...>
}
@@
long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a == b
+a, _X_EQ_, b
)
...>
}
@@
unsigned int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a == b
+a, _X_EQ_, b
)
...>
}
@@
unsigned long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a == b
+a, _X_EQ_, b
)
...>
}
@@
char a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a != b
+a, _X_NEQ_, b
)
...>
}
@@
int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a != b
+a, _X_NEQ_, b
)
...>
}
@@
long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a != b
+a, _X_NEQ_, b
)
...>
}
@@
unsigned int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a != b
+a, _X_NEQ_, b
)
...>
}
@@
unsigned long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a != b
+a, _X_NEQ_, b
)
...>
}
@@
char a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a >= b
+a, _X_GEQ_, b
)
...>
}
@@
int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a >= b
+a, _X_GEQ_, b
)
...>
}
@@
long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a >= b
+a, _X_GEQ_, b
)
...>
}
@@
unsigned int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a >= b
+a, _X_GEQ_, b
)
...>
}
@@
unsigned long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a >= b
+a, _X_GEQ_, b
)
...>
}
@@
char a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a <= b
+a, _X_LEQ_, b
)
...>
}
@@
int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a <= b
+a, _X_LEQ_, b
)
...>
}
@@
long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a <= b
+a, _X_LEQ_, b
)
...>
}
@@
unsigned int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a <= b
+a, _X_LEQ_, b
)
...>
}
@@
unsigned long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a <= b
+a, _X_LEQ_, b
)
...>
}
@@
char a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a > b
+a, _X_GT_, b
)
...>
}
@@
int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a > b
+a, _X_GT_, b
)
...>
}
@@
long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a > b
+a, _X_GT_, b
)
...>
}
@@
unsigned int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a > b
+a, _X_GT_, b
)
...>
}
@@
unsigned long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a > b
+a, _X_GT_, b
)
...>
}
@@
char a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a < b
+a, _X_LT_, b
)
...>
}
@@
int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a < b
+a, _X_LT_, b
)
...>
}
@@
long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a < b
+a, _X_LT_, b
)
...>
}
@@
unsigned int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a < b
+a, _X_LT_, b
)
...>
}
@@
unsigned long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a < b
+a, _X_LT_, b
)
...>
}
------------------------------
s/_X_NEQ_/!=/g;
s/_X_NE_/!=/g;
s/_X_EQ_/==/g;
s/_X_GT_/>/g;
s/_X_LT_/</g;
s/_X_GEQ_/>=/g;
s/_X_LEQ_/<=/g;
s/test_mem_op\(/tt_mem_op\(/g;
2014-09-16 03:18:21 +02:00
|
|
|
tt_assert(tor_mem_is_zero((char*)ext_or_auth_cookie, 32));
|
2013-08-01 22:24:20 +02:00
|
|
|
|
|
|
|
/* Now make sure we use a temporary file */
|
|
|
|
fn = get_fname("ext_cookie_file");
|
|
|
|
options->ExtORPortCookieAuthFile = tor_strdup(fn);
|
|
|
|
cp = get_ext_or_auth_cookie_file_name();
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_str_op(cp, OP_EQ, fn);
|
2013-08-01 22:24:20 +02:00
|
|
|
tor_free(cp);
|
|
|
|
|
2013-08-14 17:00:08 +02:00
|
|
|
/* Test the initialization function with a broken
|
|
|
|
write_bytes_to_file(). See if the problem is handled properly. */
|
|
|
|
MOCK(write_bytes_to_file, write_bytes_to_file_fail);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(-1, OP_EQ, init_ext_or_cookie_authentication(1));
|
|
|
|
tt_int_op(ext_or_auth_cookie_is_set, OP_EQ, 0);
|
2013-08-14 17:00:08 +02:00
|
|
|
UNMOCK(write_bytes_to_file);
|
|
|
|
|
|
|
|
/* Now do the actual initialization. */
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, init_ext_or_cookie_authentication(1));
|
|
|
|
tt_int_op(ext_or_auth_cookie_is_set, OP_EQ, 1);
|
2013-08-01 22:24:20 +02:00
|
|
|
cp = read_file_to_str(fn, RFTS_BIN, &st);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_ptr_op(cp, OP_NE, NULL);
|
|
|
|
tt_u64_op((uint64_t)st.st_size, OP_EQ, 64);
|
|
|
|
tt_mem_op(cp,OP_EQ, "! Extended ORPort Auth Cookie !\x0a", 32);
|
|
|
|
tt_mem_op(cp+32,OP_EQ, ext_or_auth_cookie, 32);
|
2013-08-01 22:24:20 +02:00
|
|
|
memcpy(cookie0, ext_or_auth_cookie, 32);
|
Use coccinelle scripts to clean up our unit tests
This should get rid of most of the users of the old test_*
functions. Some are in macros and will need manual cleanup, though.
This patch is for 13119, and was automatically generated with these
scripts. The perl scripts are there because coccinelle hates
operators as macro arguments.
------------------------------
s/==,/_X_EQ_,/g;
s/!=,/_X_NE_,/g;
s/<,/_X_LT_,/g;
s/>,/_X_GT_,/g;
s/>=,/_X_GEQ_,/g;
s/<=,/_X_LEQ_,/g;
------------------------------
@@
expression a;
identifier func;
@@
func (...) {
<...
-test_fail_msg
+TT_DIE
(
+(
a
+)
)
...>
}
@@
identifier func;
@@
func (...) {
<...
-test_fail()
+TT_DIE(("Assertion failed."))
...>
}
@@
expression a;
identifier func;
@@
func (...) {
<...
-test_assert
+tt_assert
(a)
...>
}
@@
expression a, b;
identifier func;
@@
func (...) {
<...
-test_eq
+tt_int_op
(a,
+_X_EQ_,
b)
...>
}
@@
expression a, b;
identifier func;
@@
func (...) {
<...
-test_neq
+tt_int_op
(a,
+_X_NEQ_,
b)
...>
}
@@
expression a, b;
identifier func;
@@
func (...) {
<...
-test_streq
+tt_str_op
(a,
+_X_EQ_,
b)
...>
}
@@
expression a, b;
identifier func;
@@
func (...) {
<...
-test_strneq
+tt_str_op
(a,
+_X_NEQ_,
b)
...>
}
@@
expression a, b;
identifier func;
@@
func (...) {
<...
-test_eq_ptr
+tt_ptr_op
(a,
+_X_EQ_,
b)
...>
}
@@
expression a, b;
identifier func;
@@
func() {
<...
-test_neq_ptr
+tt_ptr_op
(a,
+_X_NEQ_,
b)
...>
}
@@
expression a, b, len;
identifier func;
@@
func (...) {
<...
-test_memeq
+tt_mem_op
(a,
+_X_EQ_,
b, len)
...>
}
@@
expression a, b, len;
identifier func;
@@
func (...) {
<...
-test_memneq
+tt_mem_op
(a,
+_X_NEQ_,
b, len)
...>
}
------------------------------
@@
char a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a == b
+a, _X_EQ_, b
)
...>
}
@@
int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a == b
+a, _X_EQ_, b
)
...>
}
@@
long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a == b
+a, _X_EQ_, b
)
...>
}
@@
unsigned int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a == b
+a, _X_EQ_, b
)
...>
}
@@
unsigned long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a == b
+a, _X_EQ_, b
)
...>
}
@@
char a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a != b
+a, _X_NEQ_, b
)
...>
}
@@
int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a != b
+a, _X_NEQ_, b
)
...>
}
@@
long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a != b
+a, _X_NEQ_, b
)
...>
}
@@
unsigned int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a != b
+a, _X_NEQ_, b
)
...>
}
@@
unsigned long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a != b
+a, _X_NEQ_, b
)
...>
}
@@
char a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a >= b
+a, _X_GEQ_, b
)
...>
}
@@
int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a >= b
+a, _X_GEQ_, b
)
...>
}
@@
long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a >= b
+a, _X_GEQ_, b
)
...>
}
@@
unsigned int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a >= b
+a, _X_GEQ_, b
)
...>
}
@@
unsigned long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a >= b
+a, _X_GEQ_, b
)
...>
}
@@
char a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a <= b
+a, _X_LEQ_, b
)
...>
}
@@
int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a <= b
+a, _X_LEQ_, b
)
...>
}
@@
long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a <= b
+a, _X_LEQ_, b
)
...>
}
@@
unsigned int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a <= b
+a, _X_LEQ_, b
)
...>
}
@@
unsigned long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a <= b
+a, _X_LEQ_, b
)
...>
}
@@
char a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a > b
+a, _X_GT_, b
)
...>
}
@@
int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a > b
+a, _X_GT_, b
)
...>
}
@@
long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a > b
+a, _X_GT_, b
)
...>
}
@@
unsigned int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a > b
+a, _X_GT_, b
)
...>
}
@@
unsigned long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a > b
+a, _X_GT_, b
)
...>
}
@@
char a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a < b
+a, _X_LT_, b
)
...>
}
@@
int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a < b
+a, _X_LT_, b
)
...>
}
@@
long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a < b
+a, _X_LT_, b
)
...>
}
@@
unsigned int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a < b
+a, _X_LT_, b
)
...>
}
@@
unsigned long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a < b
+a, _X_LT_, b
)
...>
}
------------------------------
s/_X_NEQ_/!=/g;
s/_X_NE_/!=/g;
s/_X_EQ_/==/g;
s/_X_GT_/>/g;
s/_X_LT_/</g;
s/_X_GEQ_/>=/g;
s/_X_LEQ_/<=/g;
s/test_mem_op\(/tt_mem_op\(/g;
2014-09-16 03:18:21 +02:00
|
|
|
tt_assert(!tor_mem_is_zero((char*)ext_or_auth_cookie, 32));
|
2013-08-01 22:24:20 +02:00
|
|
|
|
|
|
|
/* Operation should be idempotent. */
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, init_ext_or_cookie_authentication(1));
|
|
|
|
tt_mem_op(cookie0,OP_EQ, ext_or_auth_cookie, 32);
|
2013-08-01 22:24:20 +02:00
|
|
|
|
|
|
|
done:
|
|
|
|
tor_free(cp);
|
2013-08-14 17:00:08 +02:00
|
|
|
ext_orport_free_all();
|
2013-08-01 22:24:20 +02:00
|
|
|
}
|
|
|
|
|
2013-08-01 17:44:52 +02:00
|
|
|
static void
|
|
|
|
test_ext_or_cookie_auth(void *arg)
|
|
|
|
{
|
2013-08-01 18:13:09 +02:00
|
|
|
char *reply=NULL, *reply2=NULL, *client_hash=NULL, *client_hash2=NULL;
|
2013-08-01 17:44:52 +02:00
|
|
|
size_t reply_len=0;
|
|
|
|
char hmac1[32], hmac2[32];
|
|
|
|
|
|
|
|
const char client_nonce[32] =
|
|
|
|
"Who is the third who walks alway";
|
|
|
|
char server_hash_input[] =
|
|
|
|
"ExtORPort authentication server-to-client hash"
|
|
|
|
"Who is the third who walks alway"
|
|
|
|
"................................";
|
|
|
|
char client_hash_input[] =
|
|
|
|
"ExtORPort authentication client-to-server hash"
|
|
|
|
"Who is the third who walks alway"
|
|
|
|
"................................";
|
|
|
|
|
|
|
|
(void)arg;
|
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(strlen(client_hash_input), OP_EQ, 46+32+32);
|
|
|
|
tt_int_op(strlen(server_hash_input), OP_EQ, 46+32+32);
|
2013-08-01 17:44:52 +02:00
|
|
|
|
2013-06-04 19:00:28 +02:00
|
|
|
ext_or_auth_cookie = tor_malloc_zero(32);
|
2013-08-01 17:44:52 +02:00
|
|
|
memcpy(ext_or_auth_cookie, "s beside you? When I count, ther", 32);
|
|
|
|
ext_or_auth_cookie_is_set = 1;
|
|
|
|
|
|
|
|
/* For this authentication, the client sends 32 random bytes (ClientNonce)
|
|
|
|
* The server replies with 32 byte ServerHash and 32 byte ServerNonce,
|
|
|
|
* where ServerHash is:
|
|
|
|
* HMAC-SHA256(CookieString,
|
|
|
|
* "ExtORPort authentication server-to-client hash" | ClientNonce |
|
|
|
|
* ServerNonce)"
|
|
|
|
* The client must reply with 32-byte ClientHash, which we compute as:
|
|
|
|
* ClientHash is computed as:
|
|
|
|
* HMAC-SHA256(CookieString,
|
|
|
|
* "ExtORPort authentication client-to-server hash" | ClientNonce |
|
|
|
|
* ServerNonce)
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Wrong length */
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(-1, OP_EQ,
|
2013-08-01 17:44:52 +02:00
|
|
|
handle_client_auth_nonce(client_nonce, 33, &client_hash, &reply,
|
|
|
|
&reply_len));
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(-1, OP_EQ,
|
2013-08-01 17:44:52 +02:00
|
|
|
handle_client_auth_nonce(client_nonce, 31, &client_hash, &reply,
|
|
|
|
&reply_len));
|
|
|
|
|
|
|
|
/* Now let's try this for real! */
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ,
|
2013-08-01 17:44:52 +02:00
|
|
|
handle_client_auth_nonce(client_nonce, 32, &client_hash, &reply,
|
|
|
|
&reply_len));
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(reply_len, OP_EQ, 64);
|
|
|
|
tt_ptr_op(reply, OP_NE, NULL);
|
|
|
|
tt_ptr_op(client_hash, OP_NE, NULL);
|
2013-08-01 17:44:52 +02:00
|
|
|
/* Fill in the server nonce into the hash inputs... */
|
|
|
|
memcpy(server_hash_input+46+32, reply+32, 32);
|
|
|
|
memcpy(client_hash_input+46+32, reply+32, 32);
|
|
|
|
/* Check the HMACs are correct... */
|
2013-06-04 19:00:28 +02:00
|
|
|
crypto_hmac_sha256(hmac1, (char*)ext_or_auth_cookie, 32, server_hash_input,
|
2013-08-01 17:44:52 +02:00
|
|
|
46+32+32);
|
2013-06-04 19:00:28 +02:00
|
|
|
crypto_hmac_sha256(hmac2, (char*)ext_or_auth_cookie, 32, client_hash_input,
|
2013-08-01 17:44:52 +02:00
|
|
|
46+32+32);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(hmac1,OP_EQ, reply, 32);
|
|
|
|
tt_mem_op(hmac2,OP_EQ, client_hash, 32);
|
2013-08-01 17:44:52 +02:00
|
|
|
|
2013-08-01 18:13:09 +02:00
|
|
|
/* Now do it again and make sure that the results are *different* */
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ,
|
2013-08-01 18:13:09 +02:00
|
|
|
handle_client_auth_nonce(client_nonce, 32, &client_hash2, &reply2,
|
|
|
|
&reply_len));
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(reply2,OP_NE, reply, reply_len);
|
|
|
|
tt_mem_op(client_hash2,OP_NE, client_hash, 32);
|
2013-08-01 18:13:09 +02:00
|
|
|
/* But that this one checks out too. */
|
|
|
|
memcpy(server_hash_input+46+32, reply2+32, 32);
|
|
|
|
memcpy(client_hash_input+46+32, reply2+32, 32);
|
|
|
|
/* Check the HMACs are correct... */
|
2013-06-04 19:00:28 +02:00
|
|
|
crypto_hmac_sha256(hmac1, (char*)ext_or_auth_cookie, 32, server_hash_input,
|
2013-08-01 18:13:09 +02:00
|
|
|
46+32+32);
|
2013-06-04 19:00:28 +02:00
|
|
|
crypto_hmac_sha256(hmac2, (char*)ext_or_auth_cookie, 32, client_hash_input,
|
2013-08-01 18:13:09 +02:00
|
|
|
46+32+32);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(hmac1,OP_EQ, reply2, 32);
|
|
|
|
tt_mem_op(hmac2,OP_EQ, client_hash2, 32);
|
2013-08-01 18:13:09 +02:00
|
|
|
|
|
|
|
done:
|
|
|
|
tor_free(reply);
|
|
|
|
tor_free(client_hash);
|
|
|
|
tor_free(reply2);
|
|
|
|
tor_free(client_hash2);
|
|
|
|
}
|
|
|
|
|
2015-11-25 16:42:00 +01:00
|
|
|
static void
|
2013-08-01 18:13:09 +02:00
|
|
|
crypto_rand_return_tse_str(char *to, size_t n)
|
|
|
|
{
|
|
|
|
if (n != 32) {
|
|
|
|
TT_FAIL(("Asked for %d bytes, not 32", (int)n));
|
2015-11-25 16:42:00 +01:00
|
|
|
return;
|
2013-08-01 18:13:09 +02:00
|
|
|
}
|
|
|
|
memcpy(to, "te road There is always another ", 32);
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2013-06-04 19:00:28 +02:00
|
|
|
ext_or_auth_cookie = tor_malloc_zero(32);
|
2013-08-01 18:13:09 +02:00
|
|
|
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);
|
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ,
|
2013-08-01 18:13:09 +02:00
|
|
|
handle_client_auth_nonce(client_nonce, 32, &client_hash, &reply,
|
|
|
|
&reply_len));
|
2014-11-12 19:28:07 +01:00
|
|
|
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);
|
2013-08-01 18:13:09 +02:00
|
|
|
/* 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");
|
|
|
|
|
2013-08-01 17:44:52 +02:00
|
|
|
done:
|
2013-08-01 18:13:09 +02:00
|
|
|
UNMOCK(crypto_rand);
|
2013-08-01 17:44:52 +02:00
|
|
|
tor_free(reply);
|
|
|
|
tor_free(client_hash);
|
2013-08-01 18:13:09 +02:00
|
|
|
tor_free(mem_op_hex_tmp);
|
2013-08-01 17:44:52 +02:00
|
|
|
}
|
|
|
|
|
2013-08-01 19:19:07 +02:00
|
|
|
static void
|
2014-03-10 23:52:07 +01:00
|
|
|
ignore_bootstrap_problem(const char *warn, int reason,
|
2014-03-27 20:58:43 +01:00
|
|
|
or_connection_t *conn)
|
2013-08-01 19:19:07 +02:00
|
|
|
{
|
|
|
|
(void)warn;
|
|
|
|
(void)reason;
|
2014-03-10 23:52:07 +01:00
|
|
|
(void)conn;
|
2013-08-01 19:19:07 +02:00
|
|
|
}
|
|
|
|
|
2013-08-01 23:29:10 +02:00
|
|
|
static int is_reading = 1;
|
|
|
|
static int handshake_start_called = 0;
|
|
|
|
|
|
|
|
static void
|
|
|
|
note_read_stopped(connection_t *conn)
|
|
|
|
{
|
|
|
|
(void)conn;
|
|
|
|
is_reading=0;
|
|
|
|
}
|
|
|
|
static void
|
|
|
|
note_read_started(connection_t *conn)
|
|
|
|
{
|
|
|
|
(void)conn;
|
|
|
|
is_reading=1;
|
|
|
|
}
|
|
|
|
static int
|
|
|
|
handshake_start(or_connection_t *conn, int receiving)
|
|
|
|
{
|
|
|
|
if (!conn || !receiving)
|
|
|
|
TT_FAIL(("Bad arguments to handshake_start"));
|
|
|
|
handshake_start_called = 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-08-01 19:19:07 +02:00
|
|
|
#define WRITE(s,n) \
|
|
|
|
do { \
|
|
|
|
write_to_buf((s), (n), TO_CONN(conn)->inbuf); \
|
|
|
|
} while (0)
|
|
|
|
#define CONTAINS(s,n) \
|
|
|
|
do { \
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op((n), OP_LE, sizeof(b)); \
|
|
|
|
tt_int_op(buf_datalen(TO_CONN(conn)->outbuf), OP_EQ, (n)); \
|
2013-08-01 19:19:07 +02:00
|
|
|
if ((n)) { \
|
|
|
|
fetch_from_buf(b, (n), TO_CONN(conn)->outbuf); \
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(b, OP_EQ, (s), (n)); \
|
2013-08-01 19:19:07 +02:00
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
2013-08-14 16:18:50 +02:00
|
|
|
/* Helper: Do a successful Extended ORPort authentication handshake. */
|
|
|
|
static void
|
|
|
|
do_ext_or_handshake(or_connection_t *conn)
|
|
|
|
{
|
|
|
|
char b[256];
|
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, connection_ext_or_start_auth(conn));
|
2013-08-14 16:18:50 +02:00
|
|
|
CONTAINS("\x01\x00", 2);
|
|
|
|
WRITE("\x01", 1);
|
|
|
|
WRITE("But when I look ahead up the whi", 32);
|
|
|
|
MOCK(crypto_rand, crypto_rand_return_tse_str);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
2013-08-14 16:18:50 +02:00
|
|
|
UNMOCK(crypto_rand);
|
2014-11-12 19:42:01 +01:00
|
|
|
tt_int_op(TO_CONN(conn)->state, OP_EQ,
|
|
|
|
EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH);
|
2013-08-14 16:18:50 +02:00
|
|
|
CONTAINS("\xec\x80\xed\x6e\x54\x6d\x3b\x36\xfd\xfc\x22\xfe\x13\x15\x41\x6b"
|
|
|
|
"\x02\x9f\x1a\xde\x76\x10\xd9\x10\x87\x8b\x62\xee\xb7\x40\x38\x21"
|
|
|
|
"te road There is always another ", 64);
|
|
|
|
/* Send the right response this time. */
|
|
|
|
WRITE("\xab\x39\x17\x32\xdd\x2e\xd9\x68\xcd\x40\xc0\x87\xd1\xb1\xf2\x5b"
|
|
|
|
"\x33\xb3\xcd\x77\xff\x79\xbd\x80\xc2\x07\x4b\xbf\x43\x81\x19\xa2",
|
|
|
|
32);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
2013-08-14 16:18:50 +02:00
|
|
|
CONTAINS("\x01", 1);
|
|
|
|
tt_assert(! TO_CONN(conn)->marked_for_close);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(TO_CONN(conn)->state, OP_EQ, EXT_OR_CONN_STATE_OPEN);
|
2013-08-14 16:18:50 +02:00
|
|
|
|
|
|
|
done: ;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_ext_or_handshake(void *arg)
|
|
|
|
{
|
|
|
|
or_connection_t *conn=NULL;
|
|
|
|
char b[256];
|
|
|
|
|
2013-08-01 19:19:07 +02:00
|
|
|
(void) arg;
|
|
|
|
MOCK(connection_write_to_buf_impl_,
|
|
|
|
connection_write_to_buf_impl_replacement);
|
|
|
|
/* Use same authenticators as for test_ext_or_cookie_auth_testvec */
|
2013-06-04 19:00:28 +02:00
|
|
|
ext_or_auth_cookie = tor_malloc_zero(32);
|
2013-08-01 19:19:07 +02:00
|
|
|
memcpy(ext_or_auth_cookie, "Gliding wrapt in a brown mantle," , 32);
|
|
|
|
ext_or_auth_cookie_is_set = 1;
|
|
|
|
|
|
|
|
init_connection_lists();
|
|
|
|
|
|
|
|
conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, connection_ext_or_start_auth(conn));
|
2013-08-01 19:19:07 +02:00
|
|
|
/* The server starts by telling us about the one supported authtype. */
|
|
|
|
CONTAINS("\x01\x00", 2);
|
|
|
|
/* Say the client hasn't responded yet. */
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
2013-08-01 19:19:07 +02:00
|
|
|
/* Let's say the client replies badly. */
|
|
|
|
WRITE("\x99", 1);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(-1, OP_EQ, connection_ext_or_process_inbuf(conn));
|
2013-08-01 19:19:07 +02:00
|
|
|
CONTAINS("", 0);
|
|
|
|
tt_assert(TO_CONN(conn)->marked_for_close);
|
|
|
|
close_closeable_connections();
|
|
|
|
conn = NULL;
|
|
|
|
|
|
|
|
/* Okay, try again. */
|
|
|
|
conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, connection_ext_or_start_auth(conn));
|
2013-08-01 19:19:07 +02:00
|
|
|
CONTAINS("\x01\x00", 2);
|
|
|
|
/* Let's say the client replies sensibly this time. "Yes, AUTHTYPE_COOKIE
|
|
|
|
* sounds delicious. Let's have some of that!" */
|
|
|
|
WRITE("\x01", 1);
|
|
|
|
/* Let's say that the client also sends part of a nonce. */
|
|
|
|
WRITE("But when I look ", 16);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
2013-08-01 19:19:07 +02:00
|
|
|
CONTAINS("", 0);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(TO_CONN(conn)->state, OP_EQ,
|
2013-08-01 19:19:07 +02:00
|
|
|
EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE);
|
|
|
|
/* Pump it again. Nothing should happen. */
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
2013-08-01 19:19:07 +02:00
|
|
|
/* send the rest of the nonce. */
|
|
|
|
WRITE("ahead up the whi", 16);
|
|
|
|
MOCK(crypto_rand, crypto_rand_return_tse_str);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
2013-08-01 19:19:07 +02:00
|
|
|
UNMOCK(crypto_rand);
|
|
|
|
/* We should get the right reply from the server. */
|
|
|
|
CONTAINS("\xec\x80\xed\x6e\x54\x6d\x3b\x36\xfd\xfc\x22\xfe\x13\x15\x41\x6b"
|
|
|
|
"\x02\x9f\x1a\xde\x76\x10\xd9\x10\x87\x8b\x62\xee\xb7\x40\x38\x21"
|
|
|
|
"te road There is always another ", 64);
|
|
|
|
/* Send the wrong response. */
|
|
|
|
WRITE("not with a bang but a whimper...", 32);
|
|
|
|
MOCK(control_event_bootstrap_problem, ignore_bootstrap_problem);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(-1, OP_EQ, connection_ext_or_process_inbuf(conn));
|
2013-08-01 19:19:07 +02:00
|
|
|
CONTAINS("\x00", 1);
|
|
|
|
tt_assert(TO_CONN(conn)->marked_for_close);
|
|
|
|
/* XXXX Hold-open-until-flushed. */
|
|
|
|
close_closeable_connections();
|
|
|
|
conn = NULL;
|
|
|
|
UNMOCK(control_event_bootstrap_problem);
|
|
|
|
|
2013-08-01 23:29:10 +02:00
|
|
|
MOCK(connection_start_reading, note_read_started);
|
|
|
|
MOCK(connection_stop_reading, note_read_stopped);
|
|
|
|
MOCK(connection_tls_start_handshake, handshake_start);
|
|
|
|
|
2013-08-01 19:19:07 +02:00
|
|
|
/* Okay, this time let's succeed. */
|
|
|
|
conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
|
2013-08-14 16:18:50 +02:00
|
|
|
do_ext_or_handshake(conn);
|
2013-08-01 19:19:07 +02:00
|
|
|
|
2013-08-01 23:29:10 +02:00
|
|
|
/* Now let's run through some messages. */
|
|
|
|
/* First let's send some junk and make sure it's ignored. */
|
|
|
|
WRITE("\xff\xf0\x00\x03""ABC", 7);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
2013-08-01 23:29:10 +02:00
|
|
|
CONTAINS("", 0);
|
|
|
|
/* Now let's send a USERADDR command. */
|
|
|
|
WRITE("\x00\x01\x00\x0c""1.2.3.4:5678", 16);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
|
|
|
tt_int_op(TO_CONN(conn)->port, OP_EQ, 5678);
|
|
|
|
tt_int_op(tor_addr_to_ipv4h(&TO_CONN(conn)->addr), OP_EQ, 0x01020304);
|
2013-08-01 23:29:10 +02:00
|
|
|
/* Now let's send a TRANSPORT command. */
|
|
|
|
WRITE("\x00\x02\x00\x07""rfc1149", 11);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
|
|
|
tt_ptr_op(NULL, OP_NE, conn->ext_or_transport);
|
|
|
|
tt_str_op("rfc1149", OP_EQ, conn->ext_or_transport);
|
|
|
|
tt_int_op(is_reading,OP_EQ,1);
|
|
|
|
tt_int_op(TO_CONN(conn)->state, OP_EQ, EXT_OR_CONN_STATE_OPEN);
|
2013-08-01 23:29:10 +02:00
|
|
|
/* DONE */
|
|
|
|
WRITE("\x00\x00\x00\x00", 4);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
|
|
|
tt_int_op(TO_CONN(conn)->state, OP_EQ, EXT_OR_CONN_STATE_FLUSHING);
|
|
|
|
tt_int_op(is_reading,OP_EQ,0);
|
2013-08-01 23:29:10 +02:00
|
|
|
CONTAINS("\x10\x00\x00\x00", 4);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(handshake_start_called,OP_EQ,0);
|
|
|
|
tt_int_op(0, OP_EQ, connection_ext_or_finished_flushing(conn));
|
|
|
|
tt_int_op(is_reading,OP_EQ,1);
|
|
|
|
tt_int_op(handshake_start_called,OP_EQ,1);
|
|
|
|
tt_int_op(TO_CONN(conn)->type, OP_EQ, CONN_TYPE_OR);
|
|
|
|
tt_int_op(TO_CONN(conn)->state, OP_EQ, 0);
|
2013-08-14 16:18:50 +02:00
|
|
|
close_closeable_connections();
|
|
|
|
conn = NULL;
|
|
|
|
|
|
|
|
/* Okay, this time let's succeed the handshake but fail the USERADDR
|
|
|
|
command. */
|
|
|
|
conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
|
|
|
|
do_ext_or_handshake(conn);
|
|
|
|
/* USERADDR command with an extra NUL byte */
|
|
|
|
WRITE("\x00\x01\x00\x0d""1.2.3.4:5678\x00", 17);
|
|
|
|
MOCK(control_event_bootstrap_problem, ignore_bootstrap_problem);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(-1, OP_EQ, connection_ext_or_process_inbuf(conn));
|
2013-08-14 16:18:50 +02:00
|
|
|
CONTAINS("", 0);
|
|
|
|
tt_assert(TO_CONN(conn)->marked_for_close);
|
|
|
|
close_closeable_connections();
|
|
|
|
conn = NULL;
|
|
|
|
UNMOCK(control_event_bootstrap_problem);
|
|
|
|
|
|
|
|
/* Now fail the TRANSPORT command. */
|
|
|
|
conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
|
|
|
|
do_ext_or_handshake(conn);
|
|
|
|
/* TRANSPORT command with an extra NUL byte */
|
|
|
|
WRITE("\x00\x02\x00\x08""rfc1149\x00", 12);
|
|
|
|
MOCK(control_event_bootstrap_problem, ignore_bootstrap_problem);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(-1, OP_EQ, connection_ext_or_process_inbuf(conn));
|
2013-08-14 16:18:50 +02:00
|
|
|
CONTAINS("", 0);
|
|
|
|
tt_assert(TO_CONN(conn)->marked_for_close);
|
|
|
|
close_closeable_connections();
|
|
|
|
conn = NULL;
|
|
|
|
UNMOCK(control_event_bootstrap_problem);
|
|
|
|
|
|
|
|
/* Now fail the TRANSPORT command. */
|
|
|
|
conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
|
|
|
|
do_ext_or_handshake(conn);
|
|
|
|
/* TRANSPORT command with transport name with symbols (not a
|
|
|
|
C-identifier) */
|
|
|
|
WRITE("\x00\x02\x00\x07""rf*1149", 11);
|
|
|
|
MOCK(control_event_bootstrap_problem, ignore_bootstrap_problem);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(-1, OP_EQ, connection_ext_or_process_inbuf(conn));
|
2013-08-14 16:18:50 +02:00
|
|
|
CONTAINS("", 0);
|
|
|
|
tt_assert(TO_CONN(conn)->marked_for_close);
|
|
|
|
close_closeable_connections();
|
|
|
|
conn = NULL;
|
|
|
|
UNMOCK(control_event_bootstrap_problem);
|
2013-08-01 23:29:10 +02:00
|
|
|
|
2013-08-01 19:19:07 +02:00
|
|
|
done:
|
|
|
|
UNMOCK(connection_write_to_buf_impl_);
|
|
|
|
UNMOCK(crypto_rand);
|
|
|
|
if (conn)
|
|
|
|
connection_free_(TO_CONN(conn));
|
2013-08-14 16:18:50 +02:00
|
|
|
#undef CONTAINS
|
2013-08-01 19:19:07 +02:00
|
|
|
#undef WRITE
|
|
|
|
}
|
|
|
|
|
2013-07-18 21:51:29 +02:00
|
|
|
struct testcase_t extorport_tests[] = {
|
|
|
|
{ "id_map", test_ext_or_id_map, TT_FORK, NULL, NULL },
|
2013-07-18 22:23:48 +02:00
|
|
|
{ "write_command", test_ext_or_write_command, TT_FORK, NULL, NULL },
|
2013-08-01 22:24:20 +02:00
|
|
|
{ "init_auth", test_ext_or_init_auth, TT_FORK, NULL, NULL },
|
2013-08-01 17:44:52 +02:00
|
|
|
{ "cookie_auth", test_ext_or_cookie_auth, TT_FORK, NULL, NULL },
|
2013-08-01 18:13:09 +02:00
|
|
|
{ "cookie_auth_testvec", test_ext_or_cookie_auth_testvec, TT_FORK,
|
|
|
|
NULL, NULL },
|
2013-08-01 19:19:07 +02:00
|
|
|
{ "handshake", test_ext_or_handshake, TT_FORK, NULL, NULL },
|
2013-07-18 21:51:29 +02:00
|
|
|
END_OF_TESTCASES
|
|
|
|
};
|
2013-07-18 22:23:48 +02:00
|
|
|
|