[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [obfsproxy/master] Implements the protocol side of the new CLI.
commit 67a106ad3bbafe83f1917d8060a1c78bf6d43ff6
Author: George Kadianakis <desnacked@xxxxxxxxx>
Date: Sun May 29 04:04:32 2011 +0200
Implements the protocol side of the new CLI.
---
src/network.c | 60 ++++++----------------
src/network.h | 14 +++--
src/protocol.c | 29 ++++++-----
src/protocol.h | 37 ++++++++------
src/protocols/dummy.c | 70 ++++++++++++++++++++++++-
src/protocols/dummy.h | 5 +-
src/protocols/obfs2.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++---
src/protocols/obfs2.h | 5 +-
src/socks.h | 1 -
9 files changed, 262 insertions(+), 94 deletions(-)
diff --git a/src/network.c b/src/network.c
index cfdd398..1c4b853 100644
--- a/src/network.c
+++ b/src/network.c
@@ -16,20 +16,11 @@
#include <stdlib.h>
#include <string.h>
-#include <event2/buffer.h>
-#include <event2/bufferevent.h>
-#include <event2/listener.h>
-#include <event2/event.h>
-
#include <errno.h>
#include <event2/util.h>
struct listener_t {
struct evconnlistener *listener;
- struct sockaddr_storage target_address;
- int target_address_len;
- int mode;
- int proto; /* Protocol that this listener can speak. */
protocol_params_t *proto_params;
};
@@ -49,46 +40,29 @@ static void output_event_cb(struct bufferevent *bev, short what, void *arg);
listener_t *
listener_new(struct event_base *base,
- int mode, int protocol,
- const struct sockaddr *on_address, int on_address_len,
- const struct sockaddr *target_address, int target_address_len,
- const char *shared_secret, size_t shared_secret_len)
+ int n_options, char **options)
{
const unsigned flags =
LEV_OPT_CLOSE_ON_FREE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_REUSEABLE;
- listener_t *lsn = calloc(1, sizeof(listener_t));
- assert(mode == LSN_SIMPLE_CLIENT || mode == LSN_SIMPLE_SERVER ||
- mode == LSN_SOCKS_CLIENT);
-
- if (set_up_protocol(protocol)<0) {
- printf("This is just terrible. We can't even set up a protocol! Exiting.\n");
- exit(1);
- }
-
- lsn->proto = protocol;
- lsn->mode = mode;
+ listener_t *lsn = calloc(1, sizeof(listener_t));
+ if (!lsn)
+ return NULL;
protocol_params_t *proto_params = calloc(1, sizeof(protocol_params_t));
- proto_params->is_initiator = mode != LSN_SIMPLE_SERVER;
- proto_params->shared_secret = shared_secret;
- proto_params->shared_secret_len = shared_secret_len;
-
lsn->proto_params = proto_params;
-
- if (target_address) {
- assert(target_address_len <= sizeof(struct sockaddr_storage));
- memcpy(&lsn->target_address, target_address, target_address_len);
- lsn->target_address_len = target_address_len;
- } else {
- assert(lsn->mode == LSN_SOCKS_CLIENT);
+
+ if (set_up_protocol(n_options,options,lsn->proto_params)<0) {
+ listener_free(lsn);
+ return NULL;
}
lsn->listener = evconnlistener_new_bind(base, simple_listener_cb, lsn,
flags,
-1,
- on_address,
- on_address_len);
+ &lsn->proto_params->on_address,
+ lsn->proto_params->on_address_len);
+
if (!lsn->listener) {
listener_free(lsn);
return NULL;
@@ -101,8 +75,9 @@ static void
protocol_params_free(protocol_params_t *params)
{
assert(params);
+
if (params->shared_secret)
- free(¶ms->shared_secret);
+ free(params->shared_secret);
free(params);
}
@@ -129,10 +104,9 @@ simple_listener_cb(struct evconnlistener *evcl,
dbg(("Got a connection\n"));
- conn->mode = lsn->mode;
+ conn->mode = lsn->proto_params->mode;
- conn->proto = proto_new(lsn->proto,
- lsn->proto_params);
+ conn->proto = proto_new(lsn->proto_params);
if (!conn->proto) {
printf("Creation of protocol object failed! Closing connection.\n");
goto err;
@@ -194,8 +168,8 @@ simple_listener_cb(struct evconnlistener *evcl,
if (conn->mode == LSN_SIMPLE_SERVER || conn->mode == LSN_SIMPLE_CLIENT) {
/* Launch the connect attempt. */
if (bufferevent_socket_connect(conn->output,
- (struct sockaddr *) &lsn->target_address,
- lsn->target_address_len)<0)
+ (struct sockaddr*)&lsn->proto_params->target_address,
+ lsn->proto_params->target_address_len)<0)
goto err;
bufferevent_enable(conn->output, EV_READ|EV_WRITE);
diff --git a/src/network.h b/src/network.h
index 619e45f..5537680 100644
--- a/src/network.h
+++ b/src/network.h
@@ -10,6 +10,12 @@
#include <stdlib.h>
+#include <event2/buffer.h>
+#include <event2/bufferevent.h>
+#include <event2/listener.h>
+#include <event2/event.h>
+
+
typedef struct listener_t *listener;
struct sockaddr;
@@ -23,12 +29,8 @@ struct socks_state_t;
typedef struct listener_t listener_t;
struct addrinfo;
-listener_t *listener_new(
- struct event_base *base,
- int mode, int protocol,
- const struct sockaddr *on_address, int on_address_len,
- const struct sockaddr *target_address, int target_address_len,
- const char *shared_secret, size_t shared_secret_len);
+listener_t *listener_new(struct event_base *base,
+ int n_options, char **options);
void listener_free(listener_t *listener);
#ifdef NETWORK_PRIVATE
diff --git a/src/protocol.c b/src/protocol.c
index 8fff6a3..ce96f86 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -1,6 +1,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
+#include <string.h>
#include "protocol.h"
#include "network.h"
@@ -13,15 +14,18 @@
It's called once in the runtime of the program for each proto.
*/
int
-set_up_protocol(int protocol) {
- if (protocol == OBFS2_PROTOCOL)
- obfs2_init();
- else if (protocol == DUMMY_PROTOCOL)
- dummy_init();
+set_up_protocol(int n_options, char **options,
+ struct protocol_params_t *params)
+{
+ char **name = options;
+ while (!strncmp(*name,"--",2))
+ name++;
+ if (!strcmp(*name,"dummy"))
+ return dummy_init(n_options, options, params);
+ else if (!strcmp(*name,"obfs2"))
+ return obfs2_init(n_options, options, params);
else
return -1;
-
- return 1;
}
/**
@@ -31,7 +35,7 @@ set_up_protocol(int protocol) {
Return the protocol_t if successful, NULL otherwise.
*/
struct protocol_t *
-proto_new(int protocol, protocol_params_t *params) {
+proto_new(protocol_params_t *params) {
struct protocol_t *proto = calloc(1, sizeof(struct protocol_t));
if (!proto)
return NULL;
@@ -40,11 +44,9 @@ proto_new(int protocol, protocol_params_t *params) {
if (!proto->vtable)
return NULL;
- if (protocol == OBFS2_PROTOCOL) {
- proto->proto = protocol;
+ if (params->proto == OBFS2_PROTOCOL) {
proto->state = obfs2_new(proto, params);
- } else if (protocol == DUMMY_PROTOCOL) {
- proto->proto = protocol;
+ } else if (params->proto == DUMMY_PROTOCOL) {
proto->state = dummy_new(proto, NULL);
}
@@ -81,7 +83,8 @@ proto_recv(struct protocol_t *proto, void *source, void *dest) {
return -1;
}
-void proto_destroy(struct protocol_t *proto) {
+void
+proto_destroy(struct protocol_t *proto) {
assert(proto);
assert(proto->state);
diff --git a/src/protocol.h b/src/protocol.h
index e4c3e0f..646bf7c 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -1,3 +1,5 @@
+#include <event2/buffer.h>
+
#ifndef PROTOCOL_H
#define PROTOCOL_H
@@ -5,6 +7,7 @@
#define OBFS2_PROTOCOL 1
struct evbuffer;
+struct listener_t;
/**
This struct defines parameters of the protocol per-listener basis.
@@ -15,15 +18,17 @@ struct evbuffer;
*/
typedef struct protocol_params_t {
int is_initiator;
-
- const char *shared_secret;
+ struct sockaddr_storage target_address;
+ int target_address_len;
+ struct sockaddr on_address;
+ int on_address_len;
+ int mode;
+ int proto; /* Protocol that this listener can speak. */
+ char *shared_secret;
size_t shared_secret_len;
} protocol_params_t;
struct protocol_t {
- /* protocol */
- int proto;
-
/* protocol vtable */
struct protocol_vtable *vtable;
@@ -39,17 +44,25 @@ struct protocol_t {
*/
void *state;
};
+int set_up_protocol(int n_options, char **options,
+ struct protocol_params_t *params);
+struct protocol_t *proto_new(struct protocol_params_t *params);
+void proto_destroy(struct protocol_t *proto);
+int proto_handshake(struct protocol_t *proto, void *buf);
+int proto_send(struct protocol_t *proto, void *source, void *dest);
+int proto_recv(struct protocol_t *proto, void *source, void *dest);
typedef struct protocol_vtable {
/* Initialization function: Fills in the protocol vtable. */
- int (*init)(struct protocol_t *self);
+ int (*init)(int n_options, char **options,
+ struct protocol_params_t *params);
/* Destructor: Destroys the protocol state. */
void (*destroy)(void *state);
/* Constructor: Creates a protocol object. */
- void *(*create)(struct protocol_t *proto_struct,
- protocol_params_t *parameters);
+ void *(*create)(struct protocol_t *proto_params,
+ struct protocol_params_t *parameters);
/* does handshake. Not all protocols have a handshake. */
int (*handshake)(void *state,
@@ -67,12 +80,4 @@ typedef struct protocol_vtable {
} protocol_vtable;
-int set_up_protocol(int protocol);
-struct protocol_t *proto_new(int protocol,
- protocol_params_t *params);
-void proto_destroy(struct protocol_t *proto);
-int proto_handshake(struct protocol_t *proto, void *buf);
-int proto_send(struct protocol_t *proto, void *source, void *dest);
-int proto_recv(struct protocol_t *proto, void *source, void *dest);
-
#endif
diff --git a/src/protocols/dummy.c b/src/protocols/dummy.c
index 482c927..2a24b56 100644
--- a/src/protocols/dummy.c
+++ b/src/protocols/dummy.c
@@ -9,6 +9,7 @@
#include <event2/buffer.h>
#include "dummy.h"
+#include "../network.h"
#include "../util.h"
#include "../protocol.h"
@@ -17,11 +18,55 @@ static int dummy_send(void *nothing,
struct evbuffer *source, struct evbuffer *dest);
static int dummy_recv(void *nothing, struct evbuffer *source,
struct evbuffer *dest);
+static void usage(void);
static protocol_vtable *vtable=NULL;
+/**
+ This function sets up the protocol and populates 'listner'
+ according to 'options'.
+
+ 'options' is an array like this:
+ {"dummy","socks","127.0.0.1:6666"}
+*/
int
-dummy_init(void) {
+dummy_init(int n_options, char **options,
+ struct protocol_params_t *params)
+{
+ struct sockaddr_storage ss_listen;
+ int sl_listen;
+ const char* defport;
+
+ if (n_options != 3)
+ goto err;
+
+ assert(!strcmp(options[0],"dummy"));
+ params->proto = DUMMY_PROTOCOL;
+
+ if (!strcmp(options[1], "client")) {
+ defport = "48988"; /* bf5c */
+ params->mode = LSN_SIMPLE_CLIENT;
+ } else if (!strcmp(options[1], "socks")) {
+ defport = "23548"; /* 5bf5 */
+ params->mode = LSN_SOCKS_CLIENT;
+ } else if (!strcmp(options[1], "server")) {
+ defport = "11253"; /* 2bf5 */
+ params->mode = LSN_SIMPLE_SERVER;
+ } else
+ goto err;
+
+ if (resolve_address_port(options[2], 1, 1,
+ &ss_listen, &sl_listen, defport) < 0) {
+ printf("addr\n");
+ goto err;
+ }
+ assert(sl_listen <= sizeof(struct sockaddr_storage));
+ struct sockaddr *sa_listen=NULL;
+ sa_listen = (struct sockaddr *)&ss_listen;
+ memcpy(¶ms->on_address, sa_listen, sl_listen);
+ params->on_address_len = sl_listen;
+
+ /* XXX memleak. */
vtable = calloc(1, sizeof(protocol_vtable));
if (!vtable)
return -1;
@@ -33,11 +78,30 @@ dummy_init(void) {
vtable->recv = dummy_recv;
return 1;
+
+ err:
+ usage();
+ return -1;
}
+static void
+usage(void)
+{
+ printf("Great... You can't even form a dummy protocol line:\n"
+ "dummy syntax:\n"
+ "\tdummy dummy_opts\n"
+ "\t'dummy_opts':\n"
+ "\t\tmode ~ server|client|socks\n"
+ "\t\tlisten address ~ host:port\n"
+ "Example:\n"
+ "\tobfsproxy dummy socks 127.0.0.1:5000\n");
+}
+
+
+
void *
-dummy_new(struct protocol_t *proto_struct,
- protocol_params_t *params)
+dummy_new(struct protocol_t *proto_struct,
+ struct protocol_params_t *params)
{
proto_struct->vtable = vtable;
diff --git a/src/protocols/dummy.h b/src/protocols/dummy.h
index 1ee0e02..a00248f 100644
--- a/src/protocols/dummy.h
+++ b/src/protocols/dummy.h
@@ -5,7 +5,8 @@ struct protocol_t;
struct evbuffer;
struct protocol_params_t;
-int dummy_init(void);
-void *dummy_new(struct protocol_t *proto_struct, struct protocol_params_t *params);
+int dummy_init(int n_options, char **options, struct protocol_params_t *lsn);
+void *dummy_new(struct protocol_t *proto_struct,
+ struct protocol_params_t *params);
#endif
diff --git a/src/protocols/obfs2.c b/src/protocols/obfs2.c
index a8f9155..41a97aa 100644
--- a/src/protocols/obfs2.c
+++ b/src/protocols/obfs2.c
@@ -17,6 +17,7 @@
#include "obfs2_crypt.h"
#include "obfs2.h"
+#include "../network.h"
#include "../util.h"
#include "../protocol.h"
@@ -30,6 +31,9 @@ static void *obfs2_state_new(protocol_params_t *params);
static int obfs2_state_set_shared_secret(void *s,
const char *secret,
size_t secretlen);
+static int set_up_vtable(void);
+static void usage(void);
+
static protocol_vtable *vtable=NULL;
@@ -38,22 +42,136 @@ static protocol_vtable *vtable=NULL;
Returns 0 on success, -1 on fail.
*/
int
-obfs2_init(void) {
+obfs2_init(int n_options, char **options,
+ struct protocol_params_t *params)
+{
+ struct sockaddr_storage ss_listen;
+ int sl_listen;
+ int got_dest=0;
+ int got_ss=0;
+ const char* defport;
+
+ if ((n_options < 3) || (n_options > 5)) {
+ printf("wrong options number: %d\n", n_options);
+ goto err;
+ }
+
+ assert(!strcmp(*options,"obfs2"));
+ params->proto = OBFS2_PROTOCOL;
+ options++;
+
+ /* Now parse the optional arguments */
+ while (!strncmp(*options,"--",2)) {
+ if (!strncmp(*options,"--dest=",7)) {
+ if (got_dest)
+ goto err;
+ struct sockaddr_storage ss_target;
+ struct sockaddr *sa_target=NULL;
+ int sl_target=0;
+ if (resolve_address_port(*options+7, 1, 0,
+ &ss_target, &sl_target, NULL) < 0)
+ goto err;
+ assert(sl_target <= sizeof(struct sockaddr_storage));
+ sa_target = (struct sockaddr *)&ss_target;
+ memcpy(¶ms->target_address, sa_target, sl_target);
+ params->target_address_len = sl_target;
+ got_dest=1;
+ } else if (!strncmp(*options,"--shared-secret=",16)) {
+ if (got_ss)
+ goto err;
+ /* this is freed in protocol_params_free() */
+ params->shared_secret = strdup(*options+16);
+ params->shared_secret_len = strlen(*options+16);
+ got_ss=1;
+ } else {
+ printf("Unknown argument.\n");
+ goto err;
+ }
+ options++;
+ }
+
+ if (!strcmp(*options, "client")) {
+ defport = "48988"; /* bf5c */
+ params->mode = LSN_SIMPLE_CLIENT;
+ } else if (!strcmp(*options, "socks")) {
+ defport = "23548"; /* 5bf5 */
+ params->mode = LSN_SOCKS_CLIENT;
+ } else if (!strcmp(*options, "server")) {
+ defport = "11253"; /* 2bf5 */
+ params->mode = LSN_SIMPLE_SERVER;
+ } else {
+ printf("only client/socks/server modes supported.\n");
+ goto err;
+ }
+ options++;
+
+ params->is_initiator = (params->mode != LSN_SIMPLE_SERVER);
+
+ if (resolve_address_port(*options, 1, 1,
+ &ss_listen, &sl_listen, defport) < 0)
+ goto err;
+ assert(sl_listen <= sizeof(struct sockaddr_storage));
+ struct sockaddr *sa_listen=NULL;
+ sa_listen = (struct sockaddr *)&ss_listen;
+ memcpy(¶ms->on_address, sa_listen, sl_listen);
+ params->on_address_len = sl_listen;
+
+ /* Validate option selection. */
+ if (got_dest && (params->mode == LSN_SOCKS_CLIENT)) {
+ printf("You can't be on socks mode and have --dest.\n");
+ goto err;
+ }
+
+ if (!got_dest && (params->mode != LSN_SOCKS_CLIENT)) {
+ printf("client/server mode needs --dest.\n");
+ goto err;
+ }
+
+ if (!set_up_vtable())
+ return -1;
+
+ if (initialize_crypto() < 0) {
+ fprintf(stderr, "Can't initialize crypto; failing\n");
+ return -1;
+ }
+
+ return 1;
+ err:
+ usage();
+ return -1;
+}
+
+static void
+usage(void)
+{
+ printf("You failed at creating an understandable command.\n"
+ "obfs2 syntax:\n"
+ "\tobfs2 [obfs2_args] obfs2_opts\n"
+ "\t'obfs2_opts':\n"
+ "\t\tmode ~ server|client|socks\n"
+ "\t\tlisten address ~ host:port\n"
+ "\t'obfs2_args':\n"
+ "\t\tDestination Address ~ --dest=host:port\n"
+ "\t\tShared Secret ~ --shared-secret=<secret>\n"
+ "\tExample:\n"
+ "\tobfsproxy --dest=127.0.0.1:666 --shared-secret=himitsu "
+ "\tobfs2 server 127.0.0.1:1026\n");
+}
+
+static int
+set_up_vtable(void)
+{
+ /* XXX memleak. */
vtable = calloc(1, sizeof(protocol_vtable));
if (!vtable)
- return -1;
+ return 0;
vtable->destroy = obfs2_state_free;
vtable->create = obfs2_new;
vtable->handshake = obfs2_send_initial_message;
vtable->send = obfs2_send;
vtable->recv = obfs2_recv;
-
- if (initialize_crypto() < 0) {
- fprintf(stderr, "Can't initialize crypto; failing\n");
- return -1;
- }
-
+
return 1;
}
@@ -205,6 +323,7 @@ obfs2_state_set_shared_secret(void *s, const char *secret,
uchar buf[SHARED_SECRET_LENGTH];
obfs2_state_t *state = s;
+ /* ASN we must say in spec that we hash command line shared secret. */
digest_t *c = digest_new();
digest_update(c, (uchar*)secret, secretlen);
digest_getdigest(c, buf, sizeof(buf));
diff --git a/src/protocols/obfs2.h b/src/protocols/obfs2.h
index 0d70144..7747330 100644
--- a/src/protocols/obfs2.h
+++ b/src/protocols/obfs2.h
@@ -14,11 +14,12 @@ typedef struct obfs2_state_t obfs2_state_t;
struct evbuffer;
struct protocol_t;
struct protocol_params_t;
+struct listener_t;
#define SHARED_SECRET_LENGTH SHA256_LENGTH
-int obfs2_init(void);
-void *obfs2_new(struct protocol_t *proto_struct,
+int obfs2_init(int n_options, char **options, struct protocol_params_t *params);
+void *obfs2_new(struct protocol_t *proto_struct,
struct protocol_params_t *params);
diff --git a/src/socks.h b/src/socks.h
index 7b35cb5..20fd610 100644
--- a/src/socks.h
+++ b/src/socks.h
@@ -102,7 +102,6 @@ int socks5_send_reply(struct evbuffer *reply_dest, socks_state_t *state,
int status);
enum req_status socks5_handle_request(struct evbuffer *source, struct parsereq *parsereq);
-
int socks4_read_request(struct evbuffer *source, socks_state_t *state);
int socks4_send_reply(struct evbuffer *dest,
socks_state_t *state, int status);
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits