[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [obfsproxy/master] Ancient spirits of evil, revive obfs2.
commit c85e65fad3d787f4e3d1643f27a01400afceb0a4
Author: George Kadianakis <desnacked@xxxxxxxxx>
Date: Sat Aug 20 03:26:12 2011 +0200
Ancient spirits of evil, revive obfs2.
---
Makefile.am | 11 ++--
src/protocol.c | 4 +-
src/protocols/obfs2.c | 191 ++++++++++++++++++++++++++++++------------------
src/protocols/obfs2.h | 25 ++++---
4 files changed, 142 insertions(+), 89 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index ece6069..eb35e15 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -16,7 +16,8 @@ libobfsproxy_a_SOURCES = \
src/protocol.c \
src/socks.c \
src/util.c \
- src/protocols/dummy.c
+ src/protocols/dummy.c \
+ src/protocols/obfs2.c
if NEED_SHA256
libobfsproxy_a_SOURCES += src/sha256.c
endif
@@ -30,7 +31,8 @@ unittests_SOURCES = \
src/test/unittest_container.c \
src/test/unittest_crypt.c \
src/test/unittest_socks.c \
- src/test/unittest_dummy.c
+ src/test/unittest_dummy.c \
+ src/test/unittest_obfs2.c
noinst_HEADERS = \
src/container.h \
@@ -47,10 +49,7 @@ noinst_HEADERS = \
src/test/tinytest.h \
src/test/tinytest_macros.h
-EXTRA_DIST = doc/protocol-spec.txt \
- src/protocols/obfs2.c \
- src/test/unittest_obfs2.c
-
+EXTRA_DIST = doc/protocol-spec.txt
TESTS = unittests
diff --git a/src/protocol.c b/src/protocol.c
index e5d1818..65eacf8 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -7,7 +7,7 @@
#include "protocol.h"
#include "protocols/dummy.h"
-/*#include "protocols/obfs2.h"*/
+#include "protocols/obfs2.h"
/**
All supported protocols should be put in this array.
@@ -16,7 +16,7 @@
const protocol_vtable *const supported_protocols[] =
{
&dummy_vtable,
- /*&obfs2_vtable,*/
+ &obfs2_vtable
};
const size_t n_supported_protocols =
sizeof(supported_protocols)/sizeof(supported_protocols[0]);
diff --git a/src/protocols/obfs2.c b/src/protocols/obfs2.c
index 94fd173..366bc45 100644
--- a/src/protocols/obfs2.c
+++ b/src/protocols/obfs2.c
@@ -10,21 +10,23 @@
#include <event2/buffer.h>
/* type-safe downcast wrappers */
-static inline obfs2_params_t *
-downcast_params(protocol_params_t *p)
+static inline obfs2_config_t *
+downcast_config(config_t *p)
{
- return DOWNCAST(obfs2_params_t, super, p);
+ return DOWNCAST(obfs2_config_t, super, p);
}
-static inline obfs2_protocol_t *
-downcast_protocol(protocol_t *p)
+static inline obfs2_conn_t *
+downcast_conn(conn_t *p)
{
- return DOWNCAST(obfs2_protocol_t, super, p);
+ return DOWNCAST(obfs2_conn_t, super, p);
}
static int parse_and_set_options(int n_options,
const char *const *options,
- obfs2_params_t *params);
+ obfs2_config_t *params);
+static obfs2_state_t *state_create(config_t *p);
+static void obfs2_destroy(obfs2_state_t *state);
/** Return true iff the OBFUSCATE_SEED_LENGTH-byte seed in 'seed' is nonzero */
static inline int
@@ -42,22 +44,45 @@ shared_seed_nonzero(const uchar *seed)
return memcmp(seed, SHARED_ZERO_SEED, SHARED_SECRET_LENGTH) != 0;
}
+/** stupid function returning the other conn of the circuit */
+static inline conn_t *
+get_other_conn(conn_t *conn)
+{
+ if (conn->circuit->upstream == conn) {
+ return conn->circuit->downstream;
+ } else {
+ obfs_assert(conn->circuit->downstream == conn);
+ return conn->circuit->upstream;
+ }
+}
+
+static void
+obfs2_config_free(config_t *c)
+{
+ obfs2_config_t *cfg = downcast_config(c);
+ if (cfg->listen_addr)
+ evutil_freeaddrinfo(cfg->listen_addr);
+ if (cfg->target_addr)
+ evutil_freeaddrinfo(cfg->target_addr);
+ free(cfg);
+}
+
/*
This function parses 'options' and fills the protocol parameters
structure 'params'.
Returns 0 on success, -1 on fail.
*/
-static protocol_params_t *
-obfs2_init(int n_options, const char *const *options)
+static config_t *
+obfs2_config_create(int n_options, const char *const *options)
{
- obfs2_params_t *params = xzalloc(sizeof(obfs2_params_t));
- params->super.vtable = &obfs2_vtable;
+ obfs2_config_t *cfg = xzalloc(sizeof(obfs2_config_t));
+ cfg->super.vtable = &obfs2_vtable;
- if (parse_and_set_options(n_options, options, params) == 0)
- return ¶ms->super;
+ if (parse_and_set_options(n_options, options, cfg) == 0)
+ return &cfg->super;
- proto_params_free(¶ms->super);
+ obfs2_config_free(&cfg->super);
log_warn("You failed at creating a correct obfs2 line.\n"
"obfs2 syntax:\n"
"\tobfs2 [obfs2_args] obfs2_opts\n"
@@ -74,11 +99,11 @@ obfs2_init(int n_options, const char *const *options)
}
/**
- Helper: Parses 'options' and fills 'params'.
+ Helper: Parses 'options' and fills 'cfg'.
*/
int
parse_and_set_options(int n_options, const char *const *options,
- obfs2_params_t *params)
+ obfs2_config_t *cfg)
{
int got_dest=0;
int got_ss=0;
@@ -94,9 +119,9 @@ parse_and_set_options(int n_options, const char *const *options,
if (!strncmp(*options,"--dest=",7)) {
if (got_dest)
return -1;
- params->super.target_addr =
+ cfg->target_addr =
resolve_address_port(*options+7, 1, 0, NULL);
- if (!params->super.target_addr)
+ if (!cfg->target_addr)
return -1;
got_dest=1;
} else if (!strncmp(*options,"--shared-secret=",16)) {
@@ -104,11 +129,9 @@ parse_and_set_options(int n_options, const char *const *options,
if (got_ss)
return -1;
- /* ASN we must say in spec that we hash command line shared
- secret. */
c = digest_new();
digest_update(c, (uchar*)*options+16, strlen(*options+16));
- digest_getdigest(c, params->shared_secret, SHARED_SECRET_LENGTH);
+ digest_getdigest(c, cfg->shared_secret, SHARED_SECRET_LENGTH);
digest_free(c);
got_ss=1;
@@ -121,30 +144,30 @@ parse_and_set_options(int n_options, const char *const *options,
if (!strcmp(*options, "client")) {
defport = "48988"; /* bf5c */
- params->super.mode = LSN_SIMPLE_CLIENT;
+ cfg->mode = LSN_SIMPLE_CLIENT;
} else if (!strcmp(*options, "socks")) {
defport = "23548"; /* 5bf5 */
- params->super.mode = LSN_SOCKS_CLIENT;
+ cfg->mode = LSN_SOCKS_CLIENT;
} else if (!strcmp(*options, "server")) {
defport = "11253"; /* 2bf5 */
- params->super.mode = LSN_SIMPLE_SERVER;
+ cfg->mode = LSN_SIMPLE_SERVER;
} else {
log_warn("obfs2: only client/socks/server modes supported.");
return -1;
}
options++;
- params->super.listen_addr = resolve_address_port(*options, 1, 1, defport);
- if (!params->super.listen_addr)
+ cfg->listen_addr = resolve_address_port(*options, 1, 1, defport);
+ if (!cfg->listen_addr)
return -1;
/* Validate option selection. */
- if (got_dest && (params->super.mode == LSN_SOCKS_CLIENT)) {
+ if (got_dest && (cfg->mode == LSN_SOCKS_CLIENT)) {
log_warn("obfs2: You can't be on socks mode and have --dest.");
return -1;
}
- if (!got_dest && (params->super.mode != LSN_SOCKS_CLIENT)) {
+ if (!got_dest && (cfg->mode != LSN_SOCKS_CLIENT)) {
log_warn("obfs2: client/server mode needs --dest.");
return -1;
}
@@ -154,14 +177,55 @@ parse_and_set_options(int n_options, const char *const *options,
return 0;
}
+
+/** Retrieve the 'n'th set of listen addresses for this configuration. */
+static struct evutil_addrinfo *
+obfs2_config_get_listen_addrs(config_t *cfg, size_t n)
+{
+ if (n > 0)
+ return 0;
+ return downcast_config(cfg)->listen_addr;
+}
+
+/* Retrieve the target address for this configuration. */
+static struct evutil_addrinfo *
+obfs2_config_get_target_addr(config_t *cfg)
+{
+ return downcast_config(cfg)->target_addr;
+}
+
+/*
+ This is called everytime we get a connection for the dummy
+ protocol.
+*/
+
+static conn_t *
+obfs2_conn_create(config_t *cfg)
+{
+ obfs2_conn_t *conn = xzalloc(sizeof(obfs2_conn_t));
+ conn->super.cfg = cfg;
+ conn->super.mode = downcast_config(cfg)->mode;
+ conn->state = state_create(cfg);
+
+ return &conn->super;
+}
+
+static void
+obfs2_conn_free(conn_t *conn)
+{
+ obfs2_conn_t *obfs2_conn = downcast_conn(conn);
+
+ obfs2_destroy(obfs2_conn->state);
+ free(obfs2_conn);
+}
+
/**
Derive and return key of type 'keytype' from the seeds currently set in
'state'.
*/
static crypt_t *
-derive_key(void *s, const char *keytype)
+derive_key(obfs2_state_t *state, const char *keytype)
{
- obfs2_protocol_t *state = s;
crypt_t *cryptstate;
uchar buf[SHA256_LENGTH];
digest_t *c = digest_new();
@@ -199,11 +263,9 @@ derive_key(void *s, const char *keytype)
currently set in state 's'.
*/
static crypt_t *
-derive_padding_key(void *s, const uchar *seed,
+derive_padding_key(obfs2_state_t *state, const uchar *seed,
const char *keytype)
{
- obfs2_protocol_t *state = s;
-
crypt_t *cryptstate;
uchar buf[SHA256_LENGTH];
digest_t *c = digest_new();
@@ -235,61 +297,48 @@ derive_padding_key(void *s, const uchar *seed,
}
/**
- Frees obfs2 parameters 'p'
- */
-static void
-obfs2_fini(protocol_params_t *p)
-{
- obfs2_params_t *params = downcast_params(p);
- /* wipe out keys */
- memset(params, 0x99, sizeof(obfs2_params_t));
- free(params);
-}
-
-
-/**
This is called everytime we get a connection for the obfs2
protocol.
*/
-static protocol_t *
-obfs2_create(protocol_params_t *p)
+static obfs2_state_t *
+state_create(config_t *p)
{
- obfs2_params_t *params = downcast_params(p);
- obfs2_protocol_t *proto = xzalloc(sizeof(obfs2_protocol_t));
+ obfs2_config_t *cfg = downcast_config(p);
+
+ obfs2_state_t *state = xzalloc(sizeof(obfs2_state_t));
uchar *seed;
const char *send_pad_type;
- proto->state = ST_WAIT_FOR_KEY;
- proto->we_are_initiator = (params->super.mode != LSN_SIMPLE_SERVER);
- if (proto->we_are_initiator) {
+ state->state = ST_WAIT_FOR_KEY;
+ state->we_are_initiator = (cfg->mode != LSN_SIMPLE_SERVER);
+ if (state->we_are_initiator) {
send_pad_type = INITIATOR_PAD_TYPE;
- seed = proto->initiator_seed;
+ seed = state->initiator_seed;
} else {
send_pad_type = RESPONDER_PAD_TYPE;
- seed = proto->responder_seed;
+ seed = state->responder_seed;
}
/* Generate our seed */
- memcpy(proto->secret_seed, params->shared_secret, SHARED_SECRET_LENGTH);
+ memcpy(state->secret_seed, cfg->shared_secret, SHARED_SECRET_LENGTH);
if (random_bytes(seed, OBFUSCATE_SEED_LENGTH) < 0) {
- free(proto);
+ free(state);
return NULL;
}
/* Derive the key for what we're sending */
- proto->send_padding_crypto = derive_padding_key(proto, seed, send_pad_type);
- proto->super.vtable = &obfs2_vtable;
- return &proto->super;
+ state->send_padding_crypto = derive_padding_key(state, seed, send_pad_type);
+
+ return state;
}
/**
Frees obfs2 state 's'
*/
static void
-obfs2_destroy(protocol_t *s)
+obfs2_destroy(obfs2_state_t *state)
{
- obfs2_protocol_t *state = downcast_protocol(s);
if (state->send_crypto)
crypt_free(state->send_crypto);
if (state->send_padding_crypto)
@@ -300,7 +349,7 @@ obfs2_destroy(protocol_t *s)
crypt_free(state->recv_padding_crypto);
if (state->pending_data_to_send)
evbuffer_free(state->pending_data_to_send);
- memset(state, 0x0a, sizeof(obfs2_protocol_t));
+ memset(state, 0x0a, sizeof(obfs2_state_t));
free(state);
}
@@ -310,9 +359,9 @@ obfs2_destroy(protocol_t *s)
the evbuffer 'buf'. Return 0 on success, -1 on failure.
*/
static int
-obfs2_handshake(protocol_t *s, struct evbuffer *buf)
+obfs2_handshake(conn_t *s, struct evbuffer *buf)
{
- obfs2_protocol_t *state = downcast_protocol(s);
+ obfs2_state_t *state = downcast_conn(s)->state;
uint32_t magic = htonl(OBFUSCATE_MAGIC_VALUE), plength, send_plength;
uchar msg[OBFUSCATE_MAX_PADDING + OBFUSCATE_SEED_LENGTH + 8];
@@ -381,10 +430,10 @@ obfs2_crypt_and_transmit(crypt_t *crypto,
using the state in 'state'. Returns 0 on success, -1 on failure.
*/
static int
-obfs2_send(protocol_t *s,
+obfs2_send(conn_t *s,
struct evbuffer *source, struct evbuffer *dest)
{
- obfs2_protocol_t *state = downcast_protocol(s);
+ obfs2_state_t *state = downcast_conn(get_other_conn(s))->state;
if (state->send_crypto) {
/* First of all, send any data that we've been waiting to send. */
@@ -423,10 +472,8 @@ obfs2_send(protocol_t *s,
keys. Returns 0 on success, -1 on failure.
*/
static void
-init_crypto(void *s)
+init_crypto(obfs2_state_t *state)
{
- obfs2_protocol_t *state = s;
-
const char *send_keytype;
const char *recv_keytype;
const char *recv_pad_keytype;
@@ -463,10 +510,10 @@ init_crypto(void *s)
* our callers that they must call obfs2_send() immediately.
*/
static enum recv_ret
-obfs2_recv(protocol_t *s, struct evbuffer *source,
+obfs2_recv(conn_t *s, struct evbuffer *source,
struct evbuffer *dest)
{
- obfs2_protocol_t *state = downcast_protocol(s);
+ obfs2_state_t *state = downcast_conn(s)->state;
if (state->state == ST_WAIT_FOR_KEY) {
/* We're waiting for the first OBFUSCATE_SEED_LENGTH+8 bytes to show up
diff --git a/src/protocols/obfs2.h b/src/protocols/obfs2.h
index e994d97..a8fe2cc 100644
--- a/src/protocols/obfs2.h
+++ b/src/protocols/obfs2.h
@@ -11,6 +11,7 @@ extern const protocol_vtable obfs2_vtable;
#include "crypt.h"
#include "protocol.h"
+#include "network.h"
/* ==========
These definitions are not part of the obfs2_protocol interface.
@@ -33,14 +34,7 @@ extern const protocol_vtable obfs2_vtable;
#define SHARED_SECRET_LENGTH SHA256_LENGTH
-typedef struct obfs2_params_t {
- protocol_params_t super;
- uchar shared_secret[SHARED_SECRET_LENGTH];
-} obfs2_params_t;
-
-typedef struct obfs2_protocol_t {
- protocol_t super;
-
+typedef struct obfs2_state_t {
/** Current protocol state. We start out waiting for key information. Then
we have a key and wait for padding to arrive. Finally, we are sending
and receiving bytes on the connection.
@@ -73,7 +67,20 @@ typedef struct obfs2_protocol_t {
/** Number of padding bytes to read before we get to real data */
int padding_left_to_read;
-} obfs2_protocol_t;
+} obfs2_state_t;
+
+typedef struct obfs2_config_t {
+ config_t super;
+ struct evutil_addrinfo *listen_addr;
+ struct evutil_addrinfo *target_addr;
+ enum listen_mode mode;
+ uchar shared_secret[SHARED_SECRET_LENGTH];
+} obfs2_config_t;
+
+typedef struct obfs2_conn_t {
+ conn_t super;
+ obfs2_state_t *state;
+} obfs2_conn_t;
#endif
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits