tor-commits
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 1 participants
- 214275 discussions
[obfsproxy/master] Merge remote-tracking branch 'zwol/port-fixes'
by nickm@torproject.org 14 Jul '11
by nickm@torproject.org 14 Jul '11
14 Jul '11
commit c37354b1e0adcb6d16929613e3bd4a509d487d2d
Merge: 3fb0f0e 7f03b8e
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Thu Jul 14 12:28:12 2011 -0400
Merge remote-tracking branch 'zwol/port-fixes'
Conflicts:
src/network.c
src/network.h
src/protocol.c
src/protocols/dummy.c
src/protocols/obfs2.c
src/socks.c
src/socks.h
src/util.c
Makefile.am | 34 +++---
configure.ac | 49 ++++-----
m4/winsock.m4 | 56 ++++++++++
src/crypt.c | 220 ++++++++++++++++++++++++++++++++++++++
src/crypt.h | 64 +++++++++++
src/main.c | 7 +-
src/network.c | 27 +++--
src/network.h | 19 ++--
src/protocol.c | 25 +++--
src/protocol.h | 35 +++---
src/protocols/dummy.c | 54 ++++------
src/protocols/dummy.h | 1 -
src/protocols/obfs2.c | 84 ++++++---------
src/protocols/obfs2.h | 11 +-
src/protocols/obfs2_crypt.c | 245 -------------------------------------------
src/protocols/obfs2_crypt.h | 61 -----------
src/sha256.c | 89 ++++------------
src/sha256.h | 18 +++
src/socks.c | 102 ++++++++----------
src/socks.h | 24 ++---
src/test/tinytest.c | 10 +-
src/test/unittest.c | 3 +-
src/test/unittest_crypt.c | 19 +---
src/test/unittest_obfs2.c | 133 ++++++++++++-----------
src/test/unittest_socks.c | 16 ++--
src/util.c | 154 ++++++++++------------------
src/util.h | 83 +++++---------
27 files changed, 772 insertions(+), 871 deletions(-)
diff --cc src/crypt.c
index 0000000,43f6dfb..6be9726
mode 000000,100644..100644
--- a/src/crypt.c
+++ b/src/crypt.c
@@@ -1,0 -1,178 +1,220 @@@
+ /* Copyright 2011 Nick Mathewson, George Kadianakis
+ See LICENSE for other credits and copying information
+ */
+
+ #define CRYPT_PRIVATE
+ #include "crypt.h"
+
+ #include <assert.h>
+ #include <fcntl.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
+
+ #include <openssl/opensslv.h>
+ #include <openssl/err.h>
+ #include <openssl/rand.h>
+
+ #if OPENSSL_VERSION_NUMBER >= 0x0090800f
+ #define USE_OPENSSL_RANDPOLL 1
+ #define USE_OPENSSL_SHA256 1
+ #include <openssl/sha.h>
+ #else
+ #include "sha256.h"
+ #endif
+
++/**
++ Initializes the obfs2 crypto subsystem.
++*/
+ int
+ initialize_crypto(void)
+ {
+ ERR_load_crypto_strings();
+
+ #ifdef USE_OPENSSL_RANDPOLL
+ return RAND_poll() == 1 ? 0 : -1;
+ #else
+ /* XXX Or maybe fall back to the arc4random implementation in libevent2? */
+ {
+ char buf[32];
+ int fd, n;
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd == -1) {
+ perror("open");
+ return -1;
+ }
+ n = read(fd, buf, sizeof(buf));
+ if (n != sizeof(buf)) {
+ close(fd);
+ return -1;
+ }
+ RAND_seed(buf, sizeof(buf));
+ close(fd);
+ return 0;
+ }
+ #endif
+ }
+
++/**
++ Cleans up the obfs2 crypto subsystem.
++*/
+ void
+ cleanup_crypto(void)
+ {
+ ERR_free_strings();
+ }
+
+ /* =====
+ Digests
+ ===== */
+
+ #ifdef USE_OPENSSL_SHA256
+ struct digest_t {
+ SHA256_CTX ctx;
+ };
++
++/**
++ Returns a new SHA256 digest container, or NULL on failure.
++*/
+ digest_t *
+ digest_new(void)
+ {
+ digest_t *d = malloc(sizeof(digest_t));
++ if (!d)
++ return NULL;
+ SHA256_Init(&d->ctx);
+ return d;
+ }
++
++/**
++ Updates the contents of the SHA256 container 'd' with the first
++ 'len' bytes of 'buf'.
++*/
+ void
+ digest_update(digest_t *d, const uchar *buf, size_t len)
+ {
+ SHA256_Update(&d->ctx, buf, len);
+ }
++
++/**
++ Returns the digest stored in 'd' into 'buf' of length 'len'.
++*/
+ size_t
+ digest_getdigest(digest_t *d, uchar *buf, size_t len)
+ {
+ uchar tmp[SHA256_LENGTH];
+ int n = 32;
+ SHA256_Final(tmp, &d->ctx);
+ if (len < 32)
+ n = len;
+ memcpy(buf, tmp, n);
+ memset(tmp, 0, sizeof(tmp));
+ return n;
+ }
+ #else
+ struct digest_t {
+ sha256_state ctx;
+ };
+ digest_t *
+ digest_new(void)
+ {
+ digest_t *d = malloc(sizeof(digest_t));
++ if (!d)
++ return NULL;
+ sha256_init(&d->ctx);
+ return d;
+ }
+ void
+ digest_update(digest_t *d, const uchar *buf, size_t len)
+ {
+ sha256_process(&d->ctx, buf, len);
+ }
+ size_t
+ digest_getdigest(digest_t *d, uchar *buf, size_t len)
+ {
+ uchar tmp[SHA256_LENGTH];
+ int n = 32;
+ sha256_done(&d->ctx, tmp);
+ if (len < 32)
+ n = len;
+ memcpy(buf, tmp, n);
+ memset(tmp, 0, sizeof(tmp));
+ return n;
+ }
+ #endif
+
+ void
+ digest_free(digest_t *d)
+ {
+ memset(d, 0, sizeof(digest_t));
+ free(d);
+ }
+
+ /* =====
+ Stream crypto
+ ===== */
+
++/**
++ Initializes the AES cipher with 'key'.
++*/
+ crypt_t *
+ crypt_new(const uchar *key, size_t keylen)
+ {
+ crypt_t *k;
+ if (keylen < AES_BLOCK_SIZE)
+ return NULL;
+
+ k = calloc(1, sizeof(crypt_t));
+ if (k == NULL)
+ return NULL;
+
+ AES_set_encrypt_key(key, 128, &k->key);
+
+ return k;
+ }
++
++/**
++ Sets the IV of 'key' to 'iv'.
++*/
+ void
+ crypt_set_iv(crypt_t *key, const uchar *iv, size_t ivlen)
+ {
+ assert(ivlen == sizeof(key->ivec));
+ memcpy(key->ivec, iv, ivlen);
+ }
++
++/*
++ In-place encrypts 'buf' with 'key'.
++*/
+ void
+ stream_crypt(crypt_t *key, uchar *buf, size_t len)
+ {
+ AES_ctr128_encrypt(buf, buf, /* XXX make sure this is okay to do. */
+ len,
+ &key->key, key->ivec, key->ecount_buf,
+ &key->pos);
+ }
++
++/**
++ Deallocates memory space of 'key'.
++*/
+ void
+ crypt_free(crypt_t *key)
+ {
+ memset(key, 0, sizeof(key));
+ free(key);
+ }
+
+ /* =====
+ PRNG
+ ===== */
+
++/**
++ Fills 'buf' with 'buflen' random bytes and returns 0 on success.
++ Returns -1 on failure.
++*/
+ int
+ random_bytes(uchar *buf, size_t buflen)
+ {
+ return RAND_bytes(buf, buflen) == 1 ? 0 : -1;
+ }
diff --cc src/main.c
index ee2a802,8788067..48d0d37
--- a/src/main.c
+++ b/src/main.c
@@@ -402,12 -358,11 +398,11 @@@ main(int argc, const char **argv
log_info("Exiting.");
- if (close_obfsproxy_logfile() < 0)
- printf("Failed closing logfile!\n");
+ close_obfsproxy_logfile();
+ free_all_listeners(); /* free all listeners in our listener dll */
+
/* We are exiting. Clean everything. */
- for (h=0;h<n_listeners;h++)
- listener_free(listeners[h]);
free(protocol_options);
free(n_options_array);
free(protocols);
diff --cc src/network.c
index 6d1d211,081af6e..ea06bc2
--- a/src/network.c
+++ b/src/network.c
@@@ -4,13 -4,13 +4,14 @@@
#define NETWORK_PRIVATE
#include "network.h"
+
#include "util.h"
++#include "main.h"
#include "socks.h"
#include "protocol.h"
- #include "socks.h"
- #include "main.h"
#include <assert.h>
+ #include <errno.h>
#include <stdlib.h>
#include <string.h>
@@@ -18,14 -20,10 +21,14 @@@
#include <event2/util.h>
#ifdef _WIN32
- #include <WS2tcpip.h>
+ #include <ws2tcpip.h> /* socklen_t */
#endif
+/** Doubly linked list holding all our listeners. */
+static dll_t listener_list = DLL_INIT();
+
struct listener_t {
+ dll_node_t dll_node;
struct evconnlistener *listener;
protocol_params_t *proto_params;
};
@@@ -55,50 -43,10 +58,50 @@@ static void input_event_cb(struct buffe
static void output_event_cb(struct bufferevent *bev, short what, void *arg);
/**
- This function sets up the protocol defined by 'options' and
- attempts to bind a new listener for it.
+ Puts obfsproxy's networking subsystem on "closing time" mode. This
+ means that we stop accepting new connections and we shutdown when
+ the last connection is closed.
+
+ If 'barbaric' is set, we forcefully close all open connections and
+ finish shutdown.
+
+ (Only called by signal handlers)
+*/
+void
+start_shutdown(int barbaric)
+{
+ if (!shutting_down)
+ shutting_down=1;
+
+ if (!n_connections) {
+ finish_shutdown();
+ return;
+ }
+
+ if (barbaric) {
+ if (n_connections)
+ close_all_connections();
+ return;
+ }
+}
+
+/**
+ Closes all open connections.
+*/
+static void
+close_all_connections(void)
+{
+ /** Traverse the dll and close all connections */
+ while (conn_list.head) {
+ conn_t *conn = UPCAST(conn_t, dll_node, conn_list.head);
+ conn_free(conn); /* removes it */
+ }
+ assert(!n_connections);
+}
+/**
+ This function spawns a listener according to the 'proto_params'.
- Returns the listener on success and NULL on fail.
+ Returns the listener on success, NULL on fail.
*/
listener_t *
listener_new(struct event_base *base,
diff --cc src/network.h
index dc6b583,7bc4811..ad54686
--- a/src/network.h
+++ b/src/network.h
@@@ -45,13 -33,13 +33,20 @@@ typedef struct listener_t listener_t
listener_t *listener_new(struct event_base *base,
struct protocol_params_t *params);
void listener_free(listener_t *listener);
+void free_all_listeners(void);
+
+void start_shutdown(int barbaric);
#ifdef NETWORK_PRIVATE
++
++#include "util.h"
++
+ struct bufferevent;
+ struct socks_state_t;
+ struct protocol_t;
+
typedef struct conn_t {
+ dll_node_t dll_node;
struct socks_state_t *socks_state;
struct protocol_t *proto; /* ASN Do we like this here? We probably don't.
But it's so convenient!! So convenient! */
diff --cc src/protocol.c
index 0845c11,557a5cc..282db10
--- a/src/protocol.c
+++ b/src/protocol.c
@@@ -40,8 -38,9 +38,9 @@@ set_up_protocol(int n_options, char **o
}
/**
- This function creates a protocol object.
- It's called once per connection.
- It creates a new protocol_t structure and fills it's vtable etc.
+ This function is called once per connection and creates a protocol
+ object to be used during the session.
++
Return a 'protocol_t' if successful, NULL otherwise.
*/
struct protocol_t *
diff --cc src/protocols/dummy.c
index eaf921c,7a32b47..3b31e12
--- a/src/protocols/dummy.c
+++ b/src/protocols/dummy.c
@@@ -54,20 -49,15 +50,18 @@@ dummy_init(int n_options, char **option
vtable->send = dummy_send;
vtable->recv = dummy_recv;
- return 1;
+ return 0;
}
+/**
+ Helper: Parses 'options' and fills 'params'.
+*/
static int
- parse_and_set_options(int n_options, char **options,
+ parse_and_set_options(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)
return -1;
@@@ -91,18 -82,10 +86,13 @@@
log_warn("addr");
return -1;
}
- 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;
-
- return 0;
+
+ return 1;
}
+/**
+ Prints dummy protocol usage information.
+*/
static void
usage(void)
{
@@@ -115,13 -98,8 +105,13 @@@
"Example:\n"
"\tobfsproxy dummy socks 127.0.0.1:5000\n");
}
-
+
+/*
+ This is called everytime we get a connection for the dummy
+ protocol.
-
+
+ It sets up the protocol vtable in 'proto_struct'.
+*/
void *
dummy_new(struct protocol_t *proto_struct,
struct protocol_params_t *params)
diff --cc src/protocols/obfs2.c
index f9beee5,c2169a1..27e9272
--- a/src/protocols/obfs2.c
+++ b/src/protocols/obfs2.c
@@@ -58,18 -55,13 +55,16 @@@ obfs2_init(int n_options, char **option
return -1;
}
- return 1;
+ return 0;
}
+/**
+ Helper: Parses 'options' and fills 'params'.
+*/
int
- parse_and_set_options(int n_options, char **options,
+ parse_and_set_options(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;
@@@ -192,8 -174,8 +177,8 @@@ set_up_vtable(void
vtable->handshake = obfs2_send_initial_message;
vtable->send = obfs2_send;
vtable->recv = obfs2_recv;
-
+
- return 1;
+ return 0;
}
/** Return true iff the OBFUSCATE_SEED_LENGTH-byte seed in 'seed' is nonzero */
diff --cc src/socks.c
index f175a8e,e6d72fd..e89812f
--- a/src/socks.c
+++ b/src/socks.c
@@@ -50,16 -40,8 +40,13 @@@
*/
- static enum socks_ret socks5_do_negotiation(struct evbuffer *dest,
- unsigned int neg_was_success);
-
typedef unsigned char uchar;
+/**
+ Creates a new SOCKS state.
+
+ Returns a 'socks_state_t' on success, NULL on fail.
+*/
socks_state_t *
socks_state_new(void)
{
@@@ -123,17 -102,19 +110,16 @@@ socks_errno_to_reply(socks_state_t *sta
#undef ERR
/**
- Takes a command request from 'source', it evaluates it and if it's
- legit it parses it into 'parsereq'.
-
- It returns '1' if everything went fine.
- It returns '0' if we need more data from the client.
- It returns '-1' if we didn't like something.
- It returns '-2' if the client asked for something else than CONNECT.
- If that's the case we should send a reply back to the client
- telling him that we don't support it.
-
- Disclaimer: This is just a temporary documentation.
-
- Client Request (Client -> Server)
+ Takes a SOCKS5 command request from 'source', it evaluates it and
+ if it's legit it parses it into 'parsereq'.
+
+ It returns SOCKS_GOOD if everything went fine.
+ It returns SOCKS_INCOMPLETE if we need more data from the client.
+ It returns SOCKS_BROKEN if we didn't like something.
+ It returns SOCKS_CMD_NOT_CONNECT if the client asked for something
+ else other than CONNECT. If that's the case we should send a reply
+ back to the client telling him that we don't support it.
+
- Client Request (Client -> Server)
*/
enum socks_ret
socks5_handle_request(struct evbuffer *source, struct parsereq *parsereq)
@@@ -292,8 -274,35 +280,33 @@@ socks5_send_reply(struct evbuffer *repl
}
/**
+ This function sends a method negotiation reply to 'dest'.
+ If 'neg_was_success' is true send a positive response,
+ otherwise send a negative one.
+ It returns -1 if no suitable negotiation methods were found,
+ or if there was an error during replying.
+
+ Method Negotiation Reply (Server -> Client):
+ | version | method selected |
+ 1b 1b
+ */
+ static enum socks_ret
+ socks5_do_negotiation(struct evbuffer *dest, unsigned int neg_was_success)
+ {
+ uchar reply[2];
+ reply[0] = SOCKS5_VERSION;
+
+ reply[1] = neg_was_success ? SOCKS5_METHOD_NOAUTH : SOCKS5_METHOD_FAIL;
+
+ if (evbuffer_add(dest, reply, 2) == -1 || !neg_was_success)
+ return SOCKS_BROKEN;
+ else
+ return SOCKS_GOOD;
+ }
+
+ /**
This function handles the initial SOCKS5 packet in 'source' sent by
- the client, which negotiates the version and method of SOCKS. If
+ the client which negotiates the version and method of SOCKS. If
the packet is actually valid, we reply to 'dest'.
Method Negotiation Packet (Client -> Server):
@@@ -338,39 -347,7 +351,16 @@@ socks5_handle_negotiation(struct evbuff
return socks5_do_negotiation(dest,found_noauth);
}
-/* rename to socks4_handle_request or something. */
+/**
- This function sends a method negotiation reply to 'dest'.
- If 'neg_was_success' is true send a positive response,
- otherwise send a negative one.
- It returns -1 if no suitable negotiation methods were found,
- or if there was an error during replying.
-
- Method Negotiation Reply (Server -> Client):
- | version | method selected |
- 1b 1b
- */
- static enum socks_ret
- socks5_do_negotiation(struct evbuffer *dest, unsigned int neg_was_success)
- {
- uchar reply[2];
- reply[0] = SOCKS5_VERSION;
-
- reply[1] = neg_was_success ? SOCKS5_METHOD_NOAUTH : SOCKS5_METHOD_FAIL;
-
- if (evbuffer_add(dest, reply, 2) == -1 || !neg_was_success)
- return SOCKS_BROKEN;
- else
- return SOCKS_GOOD;
- }
-
- /**
+ Takes a SOCKS4/SOCKS4a command request from 'source', it evaluates
+ it and if it's legit it parses it into 'parsereq'.
+
+ It returns SOCKS_GOOD if everything went fine.
+ It returns SOCKS_INCOMPLETE if we need more data from the client.
+ It returns SOCKS_BROKEN if we didn't like something.
+*/
++
++/* XXXX rename to socks4_handle_request or something. */
enum socks_ret
socks4_read_request(struct evbuffer *source, socks_state_t *state)
{
diff --cc src/socks.h
index 6ae69e9,ef7b953..e2c20b5
--- a/src/socks.h
+++ b/src/socks.h
@@@ -43,11 -39,11 +39,10 @@@ int socks_state_get_address(const socks
const char **addr_out,
int *port_out);
int socks_state_set_address(socks_state_t *state, const struct sockaddr *sa);
-int socks_send_reply(socks_state_t *state, struct evbuffer *dest, int error);
-int socks5_send_reply(struct evbuffer *reply_dest,
- socks_state_t *state, int status);
-
+void socks_send_reply(socks_state_t *state, struct evbuffer *dest, int error);
- void socks5_send_reply(struct evbuffer *reply_dest,
++void socks5_send_reply(struct evbuffer *reply_dest,
+ socks_state_t *state, int status);
-
#define SOCKS5_SUCCESS 0x00
#define SOCKS5_FAILED_GENERAL 0x01
#define SOCKS5_FAILED_NOTALLOWED 0x02
@@@ -106,11 -102,16 +101,14 @@@ struct socks_state_t
enum socks_ret socks5_handle_negotiation(struct evbuffer *source,
struct evbuffer *dest, socks_state_t *state);
-int socks5_send_reply(struct evbuffer *reply_dest, socks_state_t *state,
- int status);
-enum socks_ret socks5_handle_request(struct evbuffer *source,
- struct parsereq *parsereq);
+enum socks_ret socks5_handle_request(struct evbuffer *source, struct parsereq *parsereq);
+
- enum socks_ret socks4_read_request(struct evbuffer *source, socks_state_t *state);
- void socks4_send_reply(struct evbuffer *dest,
+
+ enum socks_ret socks4_read_request(struct evbuffer *source,
+ socks_state_t *state);
-int socks4_send_reply(struct evbuffer *dest,
- socks_state_t *state, int status);
++void socks4_send_reply(struct evbuffer *dest,
+ socks_state_t *state, int status);
- #endif
- #endif
+ #endif /* SOCKS_PRIVATE */
+
+ #endif /* socks.h */
diff --cc src/test/unittest_obfs2.c
index 27395df,a7c8112..0b2054b
--- a/src/test/unittest_obfs2.c
+++ b/src/test/unittest_obfs2.c
@@@ -31,10 -30,10 +30,10 @@@ test_proto_option_parsing(void *data
log_set_method(LOG_METHOD_NULL, NULL);
tt_assert(set_up_protocol(n_options, options,
- proto_params) == 1);
+ proto_params) == 0);
/** two --dest. */
- char *options2[] = {"obfs2", "--dest=127.0.0.1:5555", "--dest=a",
+ char *options2[] = {"obfs2", "--dest=127.0.0.1:5555", "--dest=a",
"server", "127.0.0.1:5552"};
n_options = 5;
diff --cc src/util.c
index 4517f95,d54c67f..cab4bf1
--- a/src/util.c
+++ b/src/util.c
@@@ -159,120 -134,8 +145,120 @@@ obfs_vsnprintf(char *str, size_t size,
return r;
}
+/************************ Doubly Linked List (DLL) ******************/
+
+/**
+ Insert 'new_node' after 'node' in the doubly linked list 'list'.
+*/
+static void
+dll_insert_after(dll_t *list, dll_node_t *node, dll_node_t *new_node)
+{
+ assert(node);
+ assert(new_node);
+
+ if (!list)
+ return;
+
+ new_node->prev = node;
+ new_node->next = node->next;
+ if (!node->next)
+ list->tail = new_node;
+ else
+ node->next->prev = new_node;
+ node->next = new_node;
+}
+
+/**
+ Insert 'new_node' before 'node' in the doubly linked list 'list'.
+*/
+static void
+dll_insert_before(dll_t *list, dll_node_t *node, dll_node_t *new_node)
+{
+ assert(node);
+ assert(new_node);
+
+ if (!list)
+ return;
+
+ new_node->prev = node->prev;
+ new_node->next = node;
+ if (!node->prev)
+ list->head = new_node;
+ else
+ node->prev->next = new_node;
+ node->prev = new_node;
+}
+
+/** Initialize <b>list</b> as an empty list. */
+void
+dll_init(dll_t *list)
+{
+ list->head = list->tail = NULL;
+}
+
+/**
+ Insert 'node' in the beginning of the doubly linked 'list'.
+*/
+static void
+dll_insert_beginning(dll_t *list, dll_node_t *node)
+{
+ assert(node);
+
+ if (!list)
+ return;
+
+ if (!list->head) {
+ list->head = node;
+ list->tail = node;
+ node->prev = NULL;
+ node->next = NULL;
+ } else {
+ dll_insert_before(list, list->head, node);
+ }
+}
+
+/**
+ Appends 'data' to the end of the doubly linked 'list'.
+ Returns 1 on success, -1 on fail.
+*/
+int
+dll_append(dll_t *list, dll_node_t *node)
+{
+ assert(list);
+ assert(node);
+
+ if (!list->tail)
+ dll_insert_beginning(list, node);
+ else
+ dll_insert_after(list, list->tail, node);
+
+ return 1;
+}
+
+/**
+ Removes 'node' from the doubly linked list 'list'.
+ It frees the list node, but leaves its data intact.
+*/
+void
+dll_remove(dll_t *list, dll_node_t *node)
+{
+ assert(node);
+
+ if (!list)
+ return;
+
+ if (!node->prev)
+ list->head = node->next;
+ else
+ node->prev->next = node->next;
+ if (!node->next)
+ list->tail = node->prev;
+ else
+ node->next->prev = node->prev;
+}
+
/************************ Logging Subsystem *************************/
- /** The code of this section was to a great extend shamelessly copied
+ /** The code of this section was to a great extent shamelessly copied
off tor. It's basicaly a stripped down version of tor's logging
system. Thank you tor. */
@@@ -331,27 -200,8 +323,8 @@@ sev_is_valid(int severity
}
/**
- Sets the global logging 'method' and also sets and open the logfile
- 'filename' in case we want to log into a file.
- It returns 0 on success and -1 on fail.
- */
- int
- log_set_method(int method, const char *filename)
- {
-
- logging_method = method;
- if (method == LOG_METHOD_FILE) {
- if (open_and_set_obfsproxy_logfile(filename) < 0)
- return -1;
- if (write_logfile_prologue(logging_logfile) < 0)
- return -1;
- }
- return 0;
- }
-
- /**
Helper: Opens 'filename' and sets it as the obfsproxy logfile.
- On success it returns 1, on fail it returns -1.
+ On success it returns 0, on fail it returns -1.
*/
static int
open_and_set_obfsproxy_logfile(const char *filename)
@@@ -381,17 -228,14 +351,16 @@@ close_obfsproxy_logfile(void
}
/**
- Writes a small prologue in the logfile 'fd' to separate log
- instances.
+ Writes a small prologue in the logfile 'fd' that mentions the
+ obfsproxy version and helps separate log instances.
+
+ Returns 0 on success, -1 on failure.
*/
static int
- write_logfile_prologue(int logfile) {
- char buf[256];
- if (compose_logfile_prologue(buf, sizeof(buf)) < 0)
- return -1;
- if (write(logfile, buf, strlen(buf)) < 0)
+ write_logfile_prologue(int logfile)
+ {
+ static const char prologue[] = "\nBrand new obfsproxy log:\n";
+ if (write(logfile, prologue, strlen(prologue)) != strlen(prologue))
return -1;
return 0;
}
diff --cc src/util.h
index 7e73cee,f52f335..ff9df22
--- a/src/util.h
+++ b/src/util.h
@@@ -50,60 -35,8 +35,36 @@@ int obfs_snprintf(char *str, size_t siz
const char *format, ...)
__attribute__((format(printf, 3, 4)));
+/***** Doubly Linked List stuff. *****/
+
+#define OFFSETOF(container_type, element) \
+ (((char*)&((container_type*)0)->element) - ((char*) ((container_type*)0)))
+
+#define UPCAST(container_type, element, ptr) \
+ (container_type*) ( \
+ ((char*)ptr) - OFFSETOF(container_type, element) \
+ )
+
+
+/** A doubly linked list node.
+ [algorithms ripped off Wikipedia (Doubly_linked_list) ] */
+typedef struct dll_node_t {
+ struct dll_node_t *next, *prev;
+} dll_node_t;
+
+/** A doubly linked list. */
+typedef struct dll_t {
+ struct dll_node_t *head;
+ struct dll_node_t *tail;
+} dll_t;
+
+void dll_init(dll_t *list);
+int dll_append(dll_t *list, dll_node_t *node);
+void dll_remove(dll_t *list, dll_node_t *node);
+#define DLL_INIT() { NULL, NULL }
+
/***** Logging subsystem stuff. *****/
- void log_fn(int severity, const char *format, ...)
- __attribute__((format(printf, 2, 3)));
- int log_set_method(int method, const char *filename);
- int log_set_min_severity(const char* sev_string);
- int close_obfsproxy_logfile(void);
-
- #ifdef __GNUC__
- #define log_info(args...) log_fn(LOG_SEV_INFO, args)
- #define log_warn(args...) log_fn(LOG_SEV_WARN, args)
- #define log_debug(args...) log_fn(LOG_SEV_DEBUG, args)
- #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
- #define log_info(...) log_fn(LOG_SEV_INFO, __VA_ARGS__)
- #define log_warn(...) log_fn(LOG_SEV_WARN, __VA_ARGS__)
- #define log_debug(...) log_fn(LOG_SEV_DEBUG, __VA_ARGS__)
- #else
- #define NEED_LOG_WRAPPERS
- void log_info(const char *format, ...)
- __attribute__((format(printf, 1, 2)));
- void log_warn(const char *format, ...)
- __attribute__((format(printf, 1, 2)));
- void log_debug(const char *format, ...)
- __attribute__((format(printf, 1, 2)));
- #endif
-
/** Logging methods */
/** Spit log messages on stdout. */
1
0
[obfsproxy/master] Header file hygiene part 1. May not compile on Windows or *BSD.
by nickm@torproject.org 14 Jul '11
by nickm@torproject.org 14 Jul '11
14 Jul '11
commit ea61c56da371a96a914ba367fbef26957af127ab
Author: Zack Weinberg <zackw(a)panix.com>
Date: Mon Jul 11 12:03:38 2011 -0700
Header file hygiene part 1. May not compile on Windows or *BSD.
All header files (except tinytest_macros.h) now include all headers
that should be required for their contents. All source files have
been pruned to the minimal set of headers which still permit
compilation on Linux. Also a certain amount of code reformatting
(removal of trailing spaces, fix overlong lines, etc).
---
src/crypt.c | 14 ++---
src/crypt.h | 5 ++
src/main.c | 4 --
src/network.c | 17 ++----
src/protocol.c | 14 ++---
src/protocol.h | 4 +-
src/protocols/dummy.c | 30 +++++------
src/protocols/dummy.h | 1 -
src/protocols/obfs2.c | 52 +++++++++---------
src/protocols/obfs2.h | 11 ++--
src/socks.c | 106 ++++++++++++++++--------------------
src/test/tinytest.c | 10 ++--
src/test/unittest.c | 1 -
src/test/unittest_crypt.c | 17 ++-----
src/test/unittest_obfs2.c | 131 ++++++++++++++++++++++++---------------------
src/test/unittest_socks.c | 13 ++---
src/util.c | 19 ++-----
17 files changed, 205 insertions(+), 244 deletions(-)
diff --git a/src/crypt.c b/src/crypt.c
index 91868f2..43f6dfb 100644
--- a/src/crypt.c
+++ b/src/crypt.c
@@ -2,22 +2,18 @@
See LICENSE for other credits and copying information
*/
-#include "config.h"
+#define CRYPT_PRIVATE
+#include "crypt.h"
#include <assert.h>
-#include <string.h>
+#include <fcntl.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
-#include <fcntl.h>
-#include <stdint.h>
#include <openssl/opensslv.h>
-#include <openssl/aes.h>
-#include <openssl/rand.h>
#include <openssl/err.h>
-
-#define CRYPT_PRIVATE
-#include "crypt.h"
+#include <openssl/rand.h>
#if OPENSSL_VERSION_NUMBER >= 0x0090800f
#define USE_OPENSSL_RANDPOLL 1
diff --git a/src/crypt.h b/src/crypt.h
index 5681a4c..d87b1de 100644
--- a/src/crypt.h
+++ b/src/crypt.h
@@ -5,6 +5,8 @@
#ifndef CRYPT_H
#define CRYPT_H
+#include <stddef.h> /* for size_t */
+
#define SHA256_LENGTH 32
/* Stream cipher state */
@@ -43,6 +45,9 @@ void crypt_free(crypt_t *);
int random_bytes(uchar *b, size_t n);
#ifdef CRYPT_PRIVATE
+
+#include <openssl/aes.h>
+
/* ==========
These definitions are not part of the crypt interface.
They're exposed here so that the unit tests can use them.
diff --git a/src/main.c b/src/main.c
index 0ba1f3f..8788067 100644
--- a/src/main.c
+++ b/src/main.c
@@ -13,10 +13,6 @@
#include "util.h"
#include "protocol.h"
-#ifdef _WIN32
-#include <Ws2tcpip.h>
-#endif
-
#ifndef __GNUC__
#define __attribute__(x)
#endif
diff --git a/src/network.c b/src/network.c
index dfa086c..c6348fa 100644
--- a/src/network.c
+++ b/src/network.c
@@ -4,10 +4,10 @@
#define NETWORK_PRIVATE
#include "network.h"
+
#include "util.h"
#include "socks.h"
#include "protocol.h"
-#include "socks.h"
#include <assert.h>
#include <errno.h>
@@ -19,10 +19,6 @@
#include <event2/listener.h>
#include <event2/util.h>
-#ifdef _WIN32
-#include <WS2tcpip.h>
-#endif
-
struct listener_t {
struct evconnlistener *listener;
protocol_params_t *proto_params;
@@ -63,12 +59,11 @@ listener_new(struct event_base *base,
}
lsn->proto_params = proto_params;
-
lsn->listener = evconnlistener_new_bind(base, simple_listener_cb, lsn,
flags,
-1,
- lsn->proto_params->listen_address,
- lsn->proto_params->listen_address_len);
+ proto_params->listen_address,
+ proto_params->listen_address_len);
if (!lsn->listener) {
log_warn("Failed to create listener!");
@@ -286,11 +281,11 @@ obfuscated_read_cb(struct bufferevent *bev, void *arg)
r = proto_recv(conn->proto,
bufferevent_get_input(bev),
bufferevent_get_output(other));
-
+
if (r == RECV_BAD)
conn_free(conn);
else if (r == RECV_SEND_PENDING)
- proto_send(conn->proto,
+ proto_send(conn->proto,
bufferevent_get_input(conn->input),
bufferevent_get_output(conn->output));
}
@@ -346,7 +341,7 @@ output_event_cb(struct bufferevent *bev, short what, void *arg)
client and terminate the connection.
*/
if (what & BEV_EVENT_ERROR) {
- if ((conn->mode == LSN_SOCKS_CLIENT) &&
+ if ((conn->mode == LSN_SOCKS_CLIENT) &&
(conn->socks_state) &&
(socks_state_get_status(conn->socks_state) == ST_HAVE_ADDR)) {
log_debug("Connection failed") ;
diff --git a/src/protocol.c b/src/protocol.c
index e306c8e..557a5cc 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -2,18 +2,16 @@
See LICENSE for other credits and copying information
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <string.h>
-
#include "protocol.h"
-#include "network.h"
-
#include "protocols/obfs2.h"
#include "protocols/dummy.h"
-/**
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/**
All supported protocols should be put in this array.
It's used by main.c.
*/
diff --git a/src/protocol.h b/src/protocol.h
index 1f0e7dd..6d5dcfe 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -5,8 +5,10 @@
#ifndef PROTOCOL_H
#define PROTOCOL_H
+#include <stddef.h> /* for size_t */
+#include "network.h" /* for recv_ret */
+
struct evbuffer;
-struct listener_t;
struct sockaddr;
#define DUMMY_PROTOCOL 1
diff --git a/src/protocols/dummy.c b/src/protocols/dummy.c
index 8db5d51..7a32b47 100644
--- a/src/protocols/dummy.c
+++ b/src/protocols/dummy.c
@@ -1,40 +1,36 @@
/* Copyright 2011 Nick Mathewson, George Kadianakis
See LICENSE for other credits and copying information
*/
+
+#include "dummy.h"
+#include "../protocol.h"
+#include "../util.h"
+
#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
-#include <unistd.h>
-
-#include <openssl/rand.h>
#include <event2/buffer.h>
-#include "dummy.h"
-#include "../network.h"
-#include "../util.h"
-#include "../protocol.h"
-#include "../network.h"
-
static int dummy_send(void *nothing,
- struct evbuffer *source, struct evbuffer *dest);
+ struct evbuffer *source, struct evbuffer *dest);
static enum recv_ret dummy_recv(void *nothing, struct evbuffer *source,
struct evbuffer *dest);
static void usage(void);
-static int parse_and_set_options(int n_options, char **options,
+static int parse_and_set_options(int n_options, char **options,
struct protocol_params_t *params);
static protocol_vtable *vtable=NULL;
/**
- This function sets up the protocol and populates 'listner'
+ This function sets up the protocol and populates 'params'
according to 'options'.
'options' is an array like this:
{"dummy","socks","127.0.0.1:6666"}
-*/
+*/
int
-dummy_init(int n_options, char **options,
+dummy_init(int n_options, char **options,
struct protocol_params_t *params)
{
if (parse_and_set_options(n_options,options,params) < 0) {
@@ -127,7 +123,7 @@ static enum recv_ret
dummy_recv(void *nothing,
struct evbuffer *source, struct evbuffer *dest) {
(void)nothing;
-
+
if (evbuffer_add_buffer(dest,source)<0)
return RECV_BAD;
else
diff --git a/src/protocols/dummy.h b/src/protocols/dummy.h
index 654e0a2..a3fa32d 100644
--- a/src/protocols/dummy.h
+++ b/src/protocols/dummy.h
@@ -5,7 +5,6 @@
#define DUMMY_H
struct protocol_t;
-struct evbuffer;
struct protocol_params_t;
int dummy_init(int n_options, char **options, struct protocol_params_t *lsn);
diff --git a/src/protocols/obfs2.c b/src/protocols/obfs2.c
index d297c16..c2169a1 100644
--- a/src/protocols/obfs2.c
+++ b/src/protocols/obfs2.c
@@ -2,22 +2,19 @@
See LICENSE for other credits and copying information
*/
+#define CRYPT_PROTOCOL_PRIVATE
+#include "obfs2.h"
+
+#include "../protocol.h"
+#include "../util.h"
+
#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
-#include <openssl/rand.h>
#include <event2/buffer.h>
-#include "../crypt.h"
-#include "../network.h"
-#include "../util.h"
-#include "../protocol.h"
-#include "../network.h"
-
-#define CRYPT_PROTOCOL_PRIVATE
-#include "obfs2.h"
static void obfs2_state_free(void *state);
static int obfs2_send_initial_message(void *state, struct evbuffer *buf);
@@ -171,13 +168,13 @@ set_up_vtable(void)
vtable = calloc(1, sizeof(protocol_vtable));
if (!vtable)
return -1;
-
+
vtable->destroy = obfs2_state_free;
vtable->create = obfs2_new;
vtable->handshake = obfs2_send_initial_message;
vtable->send = obfs2_send;
vtable->recv = obfs2_recv;
-
+
return 1;
}
@@ -230,7 +227,7 @@ derive_key(void *s, const char *keytype)
/**
Derive and return padding key of type 'keytype' from the seeds
currently set in state 's'. Returns NULL on failure.
-*/
+*/
static crypt_t *
derive_padding_key(void *s, const uchar *seed,
const char *keytype)
@@ -269,7 +266,7 @@ derive_padding_key(void *s, const uchar *seed,
/**
This is called everytime we get a connection for the obfs2
protocol.
-
+
It sets up the protocol vtable in 'proto_struct' and then attempts
to create and return a protocol state according to the protocol
parameters 'params'.
@@ -280,10 +277,10 @@ obfs2_new(struct protocol_t *proto_struct,
{
assert(vtable);
proto_struct->vtable = vtable;
-
+
return obfs2_state_new(params);
}
-
+
/**
Returns an obfs2 state according to the protocol parameters
'params'. If something goes wrong it returns NULL.
@@ -314,8 +311,8 @@ obfs2_state_new(protocol_params_t *params)
}
if (params->shared_secret)
- if (obfs2_state_set_shared_secret(state,
- params->shared_secret,
+ if (obfs2_state_set_shared_secret(state,
+ params->shared_secret,
params->shared_secret_len)<0)
return NULL;
@@ -329,11 +326,11 @@ obfs2_state_new(protocol_params_t *params)
return state;
}
-/**
+/**
Sets the shared 'secret' to be used, on the protocol state 's'.
*/
static int
-obfs2_state_set_shared_secret(void *s, const char *secret,
+obfs2_state_set_shared_secret(void *s, const char *secret,
size_t secretlen)
{
assert(secret);
@@ -494,7 +491,7 @@ init_crypto(void *s)
/* Called when we receive data in an evbuffer 'source': deobfuscates that data
* and writes it to 'dest', by using protocol state 's' to get crypto keys.
*
- * It returns:
+ * It returns:
* RECV_GOOD to say that everything went fine.
* RECV_BAD to say that something went bad.
* RECV_INCOMPLETE to say that we need more data to form an opinion.
@@ -549,12 +546,13 @@ obfs2_recv(void *s, struct evbuffer *source,
/* Fall through here: if there is padding data waiting on the buffer, pull
it off immediately. */
- log_debug("%s(): Received key, expecting %d bytes of padding", __func__, plength);
+ log_debug("%s(): Received key, expecting %d bytes of padding",
+ __func__, plength);
}
/* If we have pending data to send, we set the return code
appropriately so that we call proto_send() right after we get out of
- here! */
+ here! */
if (state->pending_data_to_send)
r = RECV_SEND_PENDING;
@@ -569,7 +567,7 @@ obfs2_recv(void *s, struct evbuffer *source,
n = evbuffer_get_length(source);
evbuffer_drain(source, n);
state->padding_left_to_read -= n;
- log_debug("%s(): Received %d bytes of padding; %d left to read",
+ log_debug("%s(): Received %d bytes of padding; %d left to read",
__func__, n, state->padding_left_to_read);
}
@@ -586,8 +584,8 @@ obfs2_recv(void *s, struct evbuffer *source,
return r;
}
-/**
- Frees obfs2 state 's'
+/**
+ Frees obfs2 state 's'
*/
static void
obfs2_state_free(void *s)
diff --git a/src/protocols/obfs2.h b/src/protocols/obfs2.h
index 608ae7a..a9ebfb1 100644
--- a/src/protocols/obfs2.h
+++ b/src/protocols/obfs2.h
@@ -5,25 +5,22 @@
#ifndef OBFS2_H
#define OBFS2_H
-#include <sys/types.h>
-
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(int n_options, char **options, struct protocol_params_t *params);
void *obfs2_new(struct protocol_t *proto_struct,
struct protocol_params_t *params);
-int parse_and_set_options(int n_options, char **options,
+int parse_and_set_options(int n_options, char **options,
struct protocol_params_t *params);
+#ifdef CRYPT_PROTOCOL_PRIVATE
+#include "../crypt.h"
-#ifdef CRYPT_PROTOCOL_PRIVATE
/* ==========
These definitions are not part of the crypt_protocol interface.
They're exposed here so that the unit tests can use them.
@@ -44,6 +41,8 @@ int parse_and_set_options(int n_options, char **options,
#define INITIATOR_SEND_TYPE "Initiator obfuscated data"
#define RESPONDER_SEND_TYPE "Responder obfuscated data"
+#define SHARED_SECRET_LENGTH SHA256_LENGTH
+
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
diff --git a/src/socks.c b/src/socks.c
index 7e6f6b2..b403be8 100644
--- a/src/socks.c
+++ b/src/socks.c
@@ -2,31 +2,17 @@
See LICENSE for other credits and copying information
*/
-#include <sys/types.h>
-#ifdef _WIN32
-#include <Winsock2.h>
-#include <Ws2tcpip.h>
-#else
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#endif
+#define SOCKS_PRIVATE
+#include "socks.h"
+#include "util.h"
#include <assert.h>
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
#include <errno.h>
-
-#define SOCKS_PRIVATE
-#include "socks.h"
-#include "util.h"
+#include <stdlib.h>
+#include <string.h>
#include <event2/buffer.h>
-#include <event2/event.h>
-#include <event2/bufferevent.h>
-
/**
General SOCKS5 idea:
@@ -50,9 +36,6 @@
*/
-static enum socks_ret socks5_do_negotiation(struct evbuffer *dest,
- unsigned int neg_was_success);
-
typedef unsigned char uchar;
socks_state_t *
@@ -98,7 +81,7 @@ socks_errno_to_reply(socks_state_t *state, int error)
return SOCKS5_SUCCESS;
else {
switch (error) {
- case ERR(ENETUNREACH):
+ case ERR(ENETUNREACH):
return SOCKS5_FAILED_NETUNREACH;
case ERR(EHOSTUNREACH):
return SOCKS5_FAILED_HOSTUNREACH;
@@ -106,7 +89,7 @@ socks_errno_to_reply(socks_state_t *state, int error)
return SOCKS5_FAILED_REFUSED;
default:
return SOCKS5_FAILED_GENERAL;
- }
+ }
}
} else
return -1;
@@ -117,16 +100,16 @@ socks_errno_to_reply(socks_state_t *state, int error)
/**
Takes a command request from 'source', it evaluates it and if it's
legit it parses it into 'parsereq'.
-
+
It returns '1' if everything went fine.
It returns '0' if we need more data from the client.
It returns '-1' if we didn't like something.
It returns '-2' if the client asked for something else than CONNECT.
If that's the case we should send a reply back to the client
telling him that we don't support it.
-
- Disclaimer: This is just a temporary documentation.
-
+
+ Disclaimer: This is just a temporary documentation.
+
Client Request (Client -> Server)
*/
enum socks_ret
@@ -216,7 +199,8 @@ socks5_handle_request(struct evbuffer *source, struct parsereq *parsereq)
char a[16];
assert(addrlen <= 16);
memcpy(a, destaddr, addrlen);
- if (evutil_inet_ntop(af, destaddr, parsereq->addr, sizeof(parsereq->addr)) == NULL)
+ if (evutil_inet_ntop(af, destaddr, parsereq->addr,
+ sizeof(parsereq->addr)) == NULL)
goto err;
}
@@ -269,7 +253,8 @@ socks5_send_reply(struct evbuffer *reply_dest, socks_state_t *state,
p[3] = SOCKS5_ATYP_FQDN;
} else {
addrlen = (state->parsereq.af == AF_INET) ? 4 : 16;
- p[3] = (state->parsereq.af == AF_INET) ? SOCKS5_ATYP_IPV4 : SOCKS5_ATYP_IPV6;
+ p[3] = (state->parsereq.af == AF_INET)
+ ? SOCKS5_ATYP_IPV4 : SOCKS5_ATYP_IPV6;
evutil_inet_pton(state->parsereq.af, state->parsereq.addr, addr);
}
port = htons(state->parsereq.port);
@@ -287,6 +272,31 @@ socks5_send_reply(struct evbuffer *reply_dest, socks_state_t *state,
}
/**
+ This function sends a method negotiation reply to 'dest'.
+ If 'neg_was_success' is true send a positive response,
+ otherwise send a negative one.
+ It returns -1 if no suitable negotiation methods were found,
+ or if there was an error during replying.
+
+ Method Negotiation Reply (Server -> Client):
+ | version | method selected |
+ 1b 1b
+*/
+static enum socks_ret
+socks5_do_negotiation(struct evbuffer *dest, unsigned int neg_was_success)
+{
+ uchar reply[2];
+ reply[0] = SOCKS5_VERSION;
+
+ reply[1] = neg_was_success ? SOCKS5_METHOD_NOAUTH : SOCKS5_METHOD_FAIL;
+
+ if (evbuffer_add(dest, reply, 2) == -1 || !neg_was_success)
+ return SOCKS_BROKEN;
+ else
+ return SOCKS_GOOD;
+}
+
+/**
This function handles the initial SOCKS5 packet in 'source' sent by
the client, which negotiates the version and method of SOCKS. If
the packet is actually valid, we reply to 'dest'.
@@ -333,31 +343,6 @@ socks5_handle_negotiation(struct evbuffer *source,
return socks5_do_negotiation(dest,found_noauth);
}
-/**
- This function sends a method negotiation reply to 'dest'.
- If 'neg_was_success' is true send a positive response,
- otherwise send a negative one.
- It returns -1 if no suitable negotiation methods were found,
- or if there was an error during replying.
-
- Method Negotiation Reply (Server -> Client):
- | version | method selected |
- 1b 1b
-*/
-static enum socks_ret
-socks5_do_negotiation(struct evbuffer *dest, unsigned int neg_was_success)
-{
- uchar reply[2];
- reply[0] = SOCKS5_VERSION;
-
- reply[1] = neg_was_success ? SOCKS5_METHOD_NOAUTH : SOCKS5_METHOD_FAIL;
-
- if (evbuffer_add(dest, reply, 2) == -1 || !neg_was_success)
- return SOCKS_BROKEN;
- else
- return SOCKS_GOOD;
-}
-
/* rename to socks4_handle_request or something. */
enum socks_ret
socks4_read_request(struct evbuffer *source, socks_state_t *state)
@@ -425,7 +410,8 @@ socks4_read_request(struct evbuffer *source, socks_state_t *state)
} else {
struct in_addr in;
in.s_addr = htonl(ipaddr);
- if (evutil_inet_ntop(AF_INET, &in, state->parsereq.addr, sizeof(state->parsereq.addr)) == NULL)
+ if (evutil_inet_ntop(AF_INET, &in, state->parsereq.addr,
+ sizeof(state->parsereq.addr)) == NULL)
return SOCKS_BROKEN;
}
@@ -520,7 +506,7 @@ handle_socks(struct evbuffer *source, struct evbuffer *dest,
if (r == SOCKS_GOOD) {
socks_state->state = ST_HAVE_ADDR;
return SOCKS_GOOD;
- } else if (r == SOCKS_INCOMPLETE)
+ } else if (r == SOCKS_INCOMPLETE)
return SOCKS_INCOMPLETE;
else if (r == SOCKS_CMD_NOT_CONNECT) {
socks_state->broken = 1;
@@ -567,7 +553,8 @@ socks_state_set_address(socks_state_t *state, const struct sockaddr *sa)
if (sa->sa_family == AF_INET) {
const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
port = sin->sin_port;
- if (evutil_inet_ntop(AF_INET, &sin->sin_addr, state->parsereq.addr, sizeof(state->parsereq.addr)) == NULL)
+ if (evutil_inet_ntop(AF_INET, &sin->sin_addr, state->parsereq.addr,
+ sizeof(state->parsereq.addr)) == NULL)
return -1;
} else if (sa->sa_family == AF_INET6) {
if (state->version == 4) {
@@ -576,7 +563,8 @@ socks_state_set_address(socks_state_t *state, const struct sockaddr *sa)
}
const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
port = sin6->sin6_port;
- if (evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, state->parsereq.addr, sizeof(state->parsereq.addr)) == NULL)
+ if (evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, state->parsereq.addr,
+ sizeof(state->parsereq.addr)) == NULL)
return -1;
} else {
log_debug("Unknown address family %d", sa->sa_family);
diff --git a/src/test/tinytest.c b/src/test/tinytest.c
index 32410fd..e3107b2 100644
--- a/src/test/tinytest.c
+++ b/src/test/tinytest.c
@@ -23,15 +23,18 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "tinytest.h"
+#include "tinytest_macros.h"
+
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <assert.h>
#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
-#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#endif
@@ -40,9 +43,6 @@
#define __attribute__(x)
#endif
-#include "tinytest.h"
-#include "tinytest_macros.h"
-
#define LONGEST_TEST_NAME 16384
static int in_tinytest_main = 0; /**< true if we're in tinytest_main().*/
diff --git a/src/test/unittest.c b/src/test/unittest.c
index 184a192..fed4bf3 100644
--- a/src/test/unittest.c
+++ b/src/test/unittest.c
@@ -1,7 +1,6 @@
/* Copyright 2011 Nick Mathewson, George Kadianakis
See LICENSE for other credits and copying information
*/
-#include <stdlib.h>
#include "tinytest.h"
#include "../crypt.h"
diff --git a/src/test/unittest_crypt.c b/src/test/unittest_crypt.c
index a65f07b..14c2c41 100644
--- a/src/test/unittest_crypt.c
+++ b/src/test/unittest_crypt.c
@@ -1,22 +1,15 @@
/* Copyright 2011 Nick Mathewson, George Kadianakis
See LICENSE for other credits and copying information
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+
#include "tinytest.h"
#include "tinytest_macros.h"
-#include <openssl/aes.h>
-
+#define CRYPT_PRIVATE
#include "../crypt.h"
-struct crypt_t {
- AES_KEY key;
- uchar ivec[AES_BLOCK_SIZE];
- uchar ecount_buf[AES_BLOCK_SIZE];
- unsigned int pos;
-};
+#include <stdio.h>
+#include <string.h>
/* Test vectors for sha256 */
static void
@@ -169,5 +162,3 @@ struct testcase_t crypt_tests[] = {
T(rng,0),
END_OF_TESTCASES
};
-
-
diff --git a/src/test/unittest_obfs2.c b/src/test/unittest_obfs2.c
index ec5cc47..a7c8112 100644
--- a/src/test/unittest_obfs2.c
+++ b/src/test/unittest_obfs2.c
@@ -1,29 +1,28 @@
/* Copyright 2011 Nick Mathewson, George Kadianakis
See LICENSE for other credits and copying information
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include "tinytest.h"
#include "tinytest_macros.h"
-#include <event2/buffer.h>
-#include <openssl/aes.h>
-
-
#define CRYPT_PROTOCOL_PRIVATE
#define CRYPT_PRIVATE
+#include "../protocols/obfs2.h"
#include "../crypt.h"
#include "../util.h"
#include "../protocol.h"
-#include "../protocols/obfs2.h"
-#include "../network.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <event2/buffer.h>
+
static void
test_proto_option_parsing(void *data)
{
- protocol_params_t *proto_params = calloc(1, sizeof(protocol_params_t));
+ protocol_params_t *proto_params = calloc(1, sizeof(protocol_params_t));
char *options[] = {"obfs2", "--shared-secret=a", "socks", "127.0.0.1:0"};
int n_options = 4;
@@ -34,7 +33,7 @@ test_proto_option_parsing(void *data)
proto_params) == 1);
/** two --dest. */
- char *options2[] = {"obfs2", "--dest=127.0.0.1:5555", "--dest=a",
+ char *options2[] = {"obfs2", "--dest=127.0.0.1:5555", "--dest=a",
"server", "127.0.0.1:5552"};
n_options = 5;
@@ -42,7 +41,7 @@ test_proto_option_parsing(void *data)
proto_params) == -1);
/** unknown arg */
- char *options3[] = {"obfs2", "--gabura=a",
+ char *options3[] = {"obfs2", "--gabura=a",
"server", "127.0.0.1:5552"};
n_options = 4;
@@ -57,7 +56,7 @@ test_proto_option_parsing(void *data)
proto_params) == -1);
/** wrong mode */
- char *options5[] = {"obfs2", "--dest=1:1",
+ char *options5[] = {"obfs2", "--dest=1:1",
"gladiator", "127.0.0.1:5552"};
n_options = 4;
@@ -65,7 +64,7 @@ test_proto_option_parsing(void *data)
proto_params) == -1);
/** stupid listen addr. */
- char *options6[] = {"obfs2", "--dest=1:1",
+ char *options6[] = {"obfs2", "--dest=1:1",
"server", "127.0.0.1:a"};
n_options = 4;
@@ -73,7 +72,7 @@ test_proto_option_parsing(void *data)
proto_params) == -1);
/** stupid dest addr. */
- char *options7[] = {"obfs2", "--dest=1:b",
+ char *options7[] = {"obfs2", "--dest=1:b",
"server", "127.0.0.1:1"};
n_options = 4;
@@ -81,7 +80,7 @@ test_proto_option_parsing(void *data)
proto_params) == -1);
/** socks with dest. */
- char *options8[] = {"obfs2", "--dest=1:2",
+ char *options8[] = {"obfs2", "--dest=1:2",
"socks", "127.0.0.1:1"};
n_options = 4;
@@ -89,7 +88,7 @@ test_proto_option_parsing(void *data)
proto_params) == -1);
/** socks with dest. */
- char *options9[] = {"obfs2", "--shared-secret=a",
+ char *options9[] = {"obfs2", "--shared-secret=a",
"server", "127.0.0.1:1"};
n_options = 4;
@@ -111,11 +110,13 @@ test_proto_setup(void *data)
struct protocol_t *server_proto = NULL;
protocol_params_t *proto_params_client = calloc(1, sizeof(protocol_params_t));
- char *options_client[] = {"obfs2", "--shared-secret=hahaha", "socks", "127.0.0.1:1800"};
+ char *options_client[] = {"obfs2", "--shared-secret=hahaha",
+ "socks", "127.0.0.1:1800"};
int n_options_client = 4;
protocol_params_t *proto_params_serv = calloc(1, sizeof(protocol_params_t));
- char *options_server[] = {"obfs2", "--shared-secret=hahaha", "--dest=127.0.0.1:1500",
+ char *options_server[] = {"obfs2", "--shared-secret=hahaha",
+ "--dest=127.0.0.1:1500",
"server", "127.0.0.1:1800"};
int n_options_server = 5;
@@ -151,12 +152,14 @@ test_proto_handshake(void *data)
struct protocol_t *server_proto = NULL;
protocol_params_t *proto_params_client = calloc(1, sizeof(protocol_params_t));
- char *options_client[] = {"obfs2", "--shared-secret=hahaha", "socks", "127.0.0.1:1800"};
+ char *options_client[] = {"obfs2", "--shared-secret=hahaha",
+ "socks", "127.0.0.1:1800"};
int n_options_client = 4;
protocol_params_t *proto_params_serv = calloc(1, sizeof(protocol_params_t));
- char *options_server[] = {"obfs2", "--shared-secret=hahaha", "--dest=127.0.0.1:1500",
- "server", "127.0.0.1:1800"};
+ char *options_server[] = {"obfs2", "--shared-secret=hahaha",
+ "--dest=127.0.0.1:1500",
+ "server", "127.0.0.1:1800"};
int n_options_server = 5;
tt_assert(set_up_protocol(n_options_client, options_client,
@@ -178,8 +181,8 @@ test_proto_handshake(void *data)
/* We create a client handshake message and pass it to output_buffer */
tt_int_op(0, <=, proto_handshake(client_proto, output_buffer));
- /* We simulate the server receiving and processing the client's handshake message,
- by using proto_recv() on the output_buffer */
+ /* We simulate the server receiving and processing the client's
+ handshake message, by using proto_recv() on the output_buffer */
tt_assert(RECV_GOOD == proto_recv(server_proto, output_buffer, dummy_buffer));
/* Now, we create the server's handshake and pass it to output_buffer */
@@ -223,17 +226,19 @@ test_proto_transfer(void *data)
struct evbuffer *dummy_buffer = NULL;
output_buffer = evbuffer_new();
dummy_buffer = evbuffer_new();
-
+
struct protocol_t *client_proto = NULL;
struct protocol_t *server_proto = NULL;
protocol_params_t *proto_params_client = calloc(1, sizeof(protocol_params_t));
- char *options_client[] = {"obfs2", "--shared-secret=hahaha", "socks", "127.0.0.1:1800"};
+ char *options_client[] = {"obfs2", "--shared-secret=hahaha",
+ "socks", "127.0.0.1:1800"};
int n_options_client = 4;
protocol_params_t *proto_params_serv = calloc(1, sizeof(protocol_params_t));
- char *options_server[] = {"obfs2", "--shared-secret=hahaha", "--dest=127.0.0.1:1500",
- "server", "127.0.0.1:1800"};
+ char *options_server[] = {"obfs2", "--shared-secret=hahaha",
+ "--dest=127.0.0.1:1500",
+ "server", "127.0.0.1:1800"};
int n_options_server = 5;
tt_assert(set_up_protocol(n_options_client, options_client,
@@ -254,11 +259,9 @@ test_proto_transfer(void *data)
/* Handshake */
tt_int_op(0, <=, proto_handshake(client_proto, output_buffer));
- tt_assert(RECV_GOOD == proto_recv(server_proto,
- output_buffer, dummy_buffer));
+ tt_assert(RECV_GOOD == proto_recv(server_proto, output_buffer, dummy_buffer));
tt_int_op(0, <=, proto_handshake(server_proto, output_buffer));
- tt_assert(RECV_GOOD == proto_recv(client_proto,
- output_buffer, dummy_buffer));
+ tt_assert(RECV_GOOD == proto_recv(client_proto, output_buffer, dummy_buffer));
/* End of Handshake */
/* Now let's pass some data around. */
@@ -269,8 +272,7 @@ test_proto_transfer(void *data)
evbuffer_add(dummy_buffer, msg1, 54);
proto_send(client_proto, dummy_buffer, output_buffer);
- tt_assert(RECV_GOOD == proto_recv(server_proto,
- output_buffer, dummy_buffer));
+ tt_assert(RECV_GOOD == proto_recv(server_proto, output_buffer, dummy_buffer));
n = evbuffer_peek(dummy_buffer, -1, NULL, &v[0], 2);
tt_int_op(n, !=, -1);
@@ -286,8 +288,7 @@ test_proto_transfer(void *data)
evbuffer_add(dummy_buffer, msg2, 55);
tt_int_op(0, <=, proto_send(server_proto, dummy_buffer, output_buffer));
- tt_assert(RECV_GOOD == proto_recv(client_proto,
- output_buffer, dummy_buffer));
+ tt_assert(RECV_GOOD == proto_recv(client_proto, output_buffer, dummy_buffer));
n = evbuffer_peek(dummy_buffer, -1, NULL, &v[1], 2);
tt_int_op(0, ==, strncmp(msg2, v[1].iov_base, 55));
@@ -322,7 +323,7 @@ test_proto_transfer(void *data)
Afterwards we will verify that they both got the correct keys.
That's right, this unit test is loco . */
static void
-test_proto_splitted_handshake(void *data)
+test_proto_split_handshake(void *data)
{
obfs2_state_t *client_state = NULL;
obfs2_state_t *server_state = NULL;
@@ -336,12 +337,14 @@ test_proto_splitted_handshake(void *data)
struct protocol_t *server_proto = NULL;
protocol_params_t *proto_params_client = calloc(1, sizeof(protocol_params_t));
- char *options_client[] = {"obfs2", "--shared-secret=hahaha", "socks", "127.0.0.1:1800"};
+ char *options_client[] = {"obfs2", "--shared-secret=hahaha",
+ "socks", "127.0.0.1:1800"};
int n_options_client = 4;
protocol_params_t *proto_params_serv = calloc(1, sizeof(protocol_params_t));
- char *options_server[] = {"obfs2", "--shared-secret=hahaha", "--dest=127.0.0.1:1500",
- "server", "127.0.0.1:1800"};
+ char *options_server[] = {"obfs2", "--shared-secret=hahaha",
+ "--dest=127.0.0.1:1500",
+ "server", "127.0.0.1:1800"};
int n_options_server = 5;
tt_assert(set_up_protocol(n_options_client, options_client,
@@ -382,16 +385,19 @@ test_proto_splitted_handshake(void *data)
memcpy(msgclient_1, seed1, OBFUSCATE_SEED_LENGTH);
memcpy(msgclient_1+OBFUSCATE_SEED_LENGTH, &magic, 4);
memcpy(msgclient_1+OBFUSCATE_SEED_LENGTH+4, &send_plength1, 4);
- tt_int_op(0, <=, random_bytes(msgclient_1+OBFUSCATE_SEED_LENGTH+8, plength1_msg1));
+ tt_int_op(0, <=, random_bytes(msgclient_1+OBFUSCATE_SEED_LENGTH+8,
+ plength1_msg1));
- stream_crypt(client_state->send_padding_crypto, msgclient_1+OBFUSCATE_SEED_LENGTH, 8+plength1_msg1);
+ stream_crypt(client_state->send_padding_crypto,
+ msgclient_1+OBFUSCATE_SEED_LENGTH, 8+plength1_msg1);
/* Client sends handshake part 1 */
- evbuffer_add(output_buffer, msgclient_1, OBFUSCATE_SEED_LENGTH+8+plength1_msg1);
+ evbuffer_add(output_buffer, msgclient_1,
+ OBFUSCATE_SEED_LENGTH+8+plength1_msg1);
/* Server receives handshake part 1 */
tt_assert(RECV_INCOMPLETE == proto_recv(server_proto,
- output_buffer, dummy_buffer));
+ output_buffer, dummy_buffer));
tt_assert(server_state->state == ST_WAIT_FOR_PADDING);
@@ -403,8 +409,7 @@ test_proto_splitted_handshake(void *data)
evbuffer_add(output_buffer, msgclient_2, plength1_msg2);
/* Server receives handshake part 2 */
- tt_assert(RECV_GOOD == proto_recv(server_proto,
- output_buffer, dummy_buffer));
+ tt_assert(RECV_GOOD == proto_recv(server_proto, output_buffer, dummy_buffer));
tt_assert(server_state->state == ST_OPEN);
@@ -427,14 +432,15 @@ test_proto_splitted_handshake(void *data)
memcpy(msgserver_1+OBFUSCATE_SEED_LENGTH, &magic, 4);
memcpy(msgserver_1+OBFUSCATE_SEED_LENGTH+4, &send_plength2, 4);
- stream_crypt(server_state->send_padding_crypto, msgserver_1+OBFUSCATE_SEED_LENGTH, 8);
+ stream_crypt(server_state->send_padding_crypto,
+ msgserver_1+OBFUSCATE_SEED_LENGTH, 8);
/* Server sends handshake part 1 */
evbuffer_add(output_buffer, msgserver_1, OBFUSCATE_SEED_LENGTH+8);
/* Client receives handshake part 1 */
- tt_assert(RECV_INCOMPLETE == proto_recv(client_proto,
- output_buffer, dummy_buffer));
+ tt_assert(RECV_INCOMPLETE == proto_recv(client_proto,
+ output_buffer, dummy_buffer));
tt_assert(client_state->state == ST_WAIT_FOR_PADDING);
@@ -446,8 +452,7 @@ test_proto_splitted_handshake(void *data)
evbuffer_add(output_buffer, msgserver_2, plength2);
/* Client receives handshake part 2 */
- tt_assert(RECV_GOOD == proto_recv(client_proto,
- output_buffer, dummy_buffer));
+ tt_assert(RECV_GOOD == proto_recv(client_proto, output_buffer, dummy_buffer));
tt_assert(client_state->state == ST_OPEN);
@@ -498,12 +503,14 @@ test_proto_wrong_handshake_magic(void *data)
struct protocol_t *server_proto = NULL;
protocol_params_t *proto_params_client = calloc(1, sizeof(protocol_params_t));
- char *options_client[] = {"obfs2", "--shared-secret=hahaha", "socks", "127.0.0.1:1800"};
+ char *options_client[] = {"obfs2", "--shared-secret=hahaha",
+ "socks", "127.0.0.1:1800"};
int n_options_client = 4;
protocol_params_t *proto_params_serv = calloc(1, sizeof(protocol_params_t));
- char *options_server[] = {"obfs2", "--shared-secret=hahaha", "--dest=127.0.0.1:1500",
- "server", "127.0.0.1:1800"};
+ char *options_server[] = {"obfs2", "--shared-secret=hahaha",
+ "--dest=127.0.0.1:1500",
+ "server", "127.0.0.1:1800"};
int n_options_server = 5;
tt_assert(set_up_protocol(n_options_client, options_client,
@@ -543,8 +550,7 @@ test_proto_wrong_handshake_magic(void *data)
evbuffer_add(output_buffer, msg, OBFUSCATE_SEED_LENGTH+8+plength);
- tt_assert(RECV_BAD == proto_recv(server_proto,
- output_buffer, dummy_buffer));
+ tt_assert(RECV_BAD == proto_recv(server_proto, output_buffer, dummy_buffer));
tt_assert(server_state->state == ST_WAIT_FOR_KEY);
@@ -584,12 +590,14 @@ test_proto_wrong_handshake_plength(void *data)
protocol_params_t *proto_params_client = calloc(1, sizeof(protocol_params_t));
- char *options_client[] = {"obfs2", "--shared-secret=hahaha", "socks", "127.0.0.1:1800"};
+ char *options_client[] = {"obfs2", "--shared-secret=hahaha",
+ "socks", "127.0.0.1:1800"};
int n_options_client = 4;
protocol_params_t *proto_params_serv = calloc(1, sizeof(protocol_params_t));
- char *options_server[] = {"obfs2", "--shared-secret=hahaha", "--dest=127.0.0.1:1500",
- "server", "127.0.0.1:1800"};
+ char *options_server[] = {"obfs2", "--shared-secret=hahaha",
+ "--dest=127.0.0.1:1500",
+ "server", "127.0.0.1:1800"};
int n_options_server = 5;
tt_assert(set_up_protocol(n_options_client, options_client,
@@ -628,8 +636,7 @@ test_proto_wrong_handshake_plength(void *data)
evbuffer_add(output_buffer, msg, OBFUSCATE_SEED_LENGTH+8+plength);
- tt_assert(RECV_BAD == proto_recv(server_proto,
- output_buffer, dummy_buffer));
+ tt_assert(RECV_BAD == proto_recv(server_proto, output_buffer, dummy_buffer));
tt_assert(server_state->state == ST_WAIT_FOR_KEY);
@@ -658,7 +665,7 @@ struct testcase_t protocol_tests[] = {
T(setup, 0),
T(handshake, 0),
T(transfer, 0),
- T(splitted_handshake, 0),
+ T(split_handshake, 0),
T(wrong_handshake_magic, 0),
T(wrong_handshake_plength, 0),
END_OF_TESTCASES
diff --git a/src/test/unittest_socks.c b/src/test/unittest_socks.c
index 1719f8e..0841136 100644
--- a/src/test/unittest_socks.c
+++ b/src/test/unittest_socks.c
@@ -1,20 +1,19 @@
/* Copyright 2011 Nick Mathewson, George Kadianakis
See LICENSE for other credits and copying information
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include "tinytest.h"
#include "tinytest_macros.h"
-#include <event2/buffer.h>
-
#define SOCKS_PRIVATE
#include "../socks.h"
#include "../crypt.h"
-#include "../util.h"
-#include "../protocols/obfs2.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <event2/buffer.h>
+
/**
This function tests the negotiation phase of the SOCKS5 protocol.
diff --git a/src/util.c b/src/util.c
index 9ac2260..6f5302b 100644
--- a/src/util.c
+++ b/src/util.c
@@ -2,25 +2,18 @@
See LICENSE for other credits and copying information
*/
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
+#include "util.h"
#include <assert.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/stat.h>
#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
-#include "util.h"
-
-#ifdef _WIN32
-#include <Ws2tcpip.h>
-#endif
-
-#include <event2/util.h>
#include <event2/dns.h>
+#include <event2/util.h>
/** Any size_t larger than this amount is likely to be an underflow. */
#define SIZE_T_CEILING (SIZE_MAX/2 - 16)
1
0
commit e6cf978c7cc2251564e8547e201b3f74a715a87e
Author: Zack Weinberg <zackw(a)panix.com>
Date: Thu Jul 7 16:40:21 2011 -0700
Low-hanging portability fixes.
* Modernize Makefile.am and configure.ac.
* Remove a whole bunch of checks from configure.ac that probably were
unnecessary and the code wasn't bothering to pay attention to, anyway.
* Make the configure script agree with the code on the way to detect Windows.
* Remove an unnecessary Windows #ifdef block.
* Define SIZE_T_CEILING in a way that doesn't need a configure check.
* GCC uninitialized-variable warning fix in the test suite.
---
Makefile.am | 8 +++-----
configure.ac | 42 +++++++++++++++++++-----------------------
src/test/unittest_socks.c | 1 +
src/util.c | 8 ++++----
src/util.h | 15 ---------------
5 files changed, 27 insertions(+), 47 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 614748f..eb32bdc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
-AUTOMAKE_OPTIONS = foreign
-ACLOCAL_AMFLAGS = -I m4
-CFLAGS = -DDEBUG -g -Wall -O2 -Werror @libevent_CFLAGS@ @openssl_CFLAGS@
+ACLOCAL_AMFLAGS = -I m4
+AM_CFLAGS = -DDEBUG -Wall -Werror @libevent_CFLAGS@ @openssl_CFLAGS@
+LDADD = libobfsproxy.a @libevent_LIBS@ @openssl_LIBS@ @ws32_LIBS@
bin_PROGRAMS = obfsproxy
noinst_LIBRARIES = libobfsproxy.a
@@ -18,7 +18,6 @@ libobfsproxy_a_SOURCES = \
obfsproxy_SOURCES = \
src/main.c
-obfsproxy_LDADD = libobfsproxy.a @libevent_LIBS@ @openssl_LIBS@ @LIB_WS32@
unittests_SOURCES = \
src/test/tinytest.c \
@@ -26,7 +25,6 @@ unittests_SOURCES = \
src/test/unittest_obfs2.c \
src/test/unittest_crypt.c \
src/test/unittest_socks.c
-unittests_LDADD = libobfsproxy.a @libevent_LIBS@ @openssl_LIBS@ @LIB_WS32@
noinst_HEADERS = \
src/network.h \
diff --git a/configure.ac b/configure.ac
index c799d61..e49ddf3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,34 +1,30 @@
-AC_INIT
-AM_INIT_AUTOMAKE(obsproxy, 0.0)
-AM_CONFIG_HEADER(config.h)
+AC_PREREQ([2.67])dnl Possibly earlier will do, but this is what I have
+AC_INIT([obsproxy], [0.0])
+AC_CONFIG_SRCDIR([src/main.c])
-AC_CANONICAL_HOST
+AM_INIT_AUTOMAKE([foreign])
-AC_PROG_GCC_TRADITIONAL
-AC_PROG_SED
+AC_PROG_CC
+AC_PROG_CPP
AC_PROG_RANLIB
PKG_PROG_PKG_CONFIG
-AC_CHECK_HEADERS(stdint.h unistd.h fcntl.h)
-
PKG_CHECK_MODULES([libevent], [libevent >= 2.0])
PKG_CHECK_MODULES([openssl], [openssl >= 0.9.7])
-# We don't need -lssl, only -lcrypto
-openssl_LIBS=`echo "$openssl_LIBS" | $SED -e 's/-lssl//'`
-
-AC_CHECK_HEADERS([winsock2.h], HAVE_WINSOCK2_H=yes)
-AM_CONDITIONAL(HAVE_WINSOCK2_H, test "x$HAVE_WINSOCK2_H" = "xyes")
-if test "x$HAVE_WINSOCK2_H" = "xyes"; then
- LIB_WS32=-lws2_32
-else
- LIB_WS32=
-fi
-AC_SUBST(LIB_WS32)
-
-AC_CHECK_SIZEOF(size_t)
+AC_CACHE_CHECK([for winsock], [ac_cv_lib_winsock],
+ [AC_PREPROC_IFELSE(
+ [#ifndef _WIN32
+ #error "not windows"
+ #endif
+ ],
+ [ac_cv_lib_winsock=yes], [ac_cv_lib_winsock=no])
+])
+AS_IF([test "x$ac_cv_lib_winsock" = xyes],
+ [ws32_LIBS=-lws2_32],
+ [ws32_LIBS=])
+AC_SUBST(ws32_LIBS)
AC_CONFIG_FILES([Makefile])
-
+AC_CONFIG_HEADERS([config.h])
AC_OUTPUT
-
diff --git a/src/test/unittest_socks.c b/src/test/unittest_socks.c
index c85fcf9..c77e3dc 100644
--- a/src/test/unittest_socks.c
+++ b/src/test/unittest_socks.c
@@ -425,6 +425,7 @@ test_socks_socks4_request(void *data)
/* First test:
Correct SOCKS4 req packet with nothing in the optional field. */
struct parsereq pr1;
+ memset(&pr1, 0, sizeof(struct parsereq));
state->parsereq = pr1;
uchar req1[8];
req1[0] = 1;
diff --git a/src/util.c b/src/util.c
index 7e3e747..70a6586 100644
--- a/src/util.c
+++ b/src/util.c
@@ -7,6 +7,7 @@
#include <stdlib.h>
#include <assert.h>
+#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -21,6 +22,9 @@
#include <event2/util.h>
#include <event2/dns.h>
+/** Any size_t larger than this amount is likely to be an underflow. */
+#define SIZE_T_CEILING (SIZE_MAX/2 - 16)
+
static const char *sev_to_string(int severity);
static int sev_is_valid(int severity);
static int write_logfile_prologue(int fd);
@@ -137,11 +141,7 @@ obfs_vsnprintf(char *str, size_t size, const char *format, va_list args)
return -1; /* no place for the NUL */
if (size > SIZE_T_CEILING)
return -1;
-#ifdef MS_WINDOWS
- r = _vsnprintf(str, size, format, args);
-#else
r = vsnprintf(str, size, format, args);
-#endif
str[size-1] = '\0';
if (r < 0 || r >= (ssize_t)size)
return -1;
diff --git a/src/util.h b/src/util.h
index 2705d51..ee04c85 100644
--- a/src/util.h
+++ b/src/util.h
@@ -8,8 +8,6 @@
/* va_list definition */
#include <stdarg.h>
-#include "config.h"
-
struct sockaddr_storage;
struct event_base;
struct evdns_base;
@@ -27,19 +25,6 @@ int init_evdns_base(struct event_base *base);
/***** String functions stuff. *****/
-/* The sizeof a size_t, as computed by sizeof. */
-#ifndef SSIZE_T_MAX
-#if (SIZEOF_SIZE_T == 4)
-#define SSIZE_T_MAX INT32_MAX
-#elif (SIZEOF_SIZE_T == 8)
-#define SSIZE_T_MAX INT64_MAX
-#else
-#error "Can't define SSIZE_T_MAX"
-#endif
-#endif
-/** Any size_t larger than this amount is likely to be an underflow. */
-#define SIZE_T_CEILING ((size_t)(SSIZE_T_MAX-16))
-
#ifndef __GNUC__
#define __attribute__(x)
#endif
1
0
[obfsproxy/master] Aggressive removal of nested includes from header files. Potential not to compile on Windows.
by nickm@torproject.org 14 Jul '11
by nickm@torproject.org 14 Jul '11
14 Jul '11
commit f3ebd94c1caa33f52775a585482431faadcb391d
Author: Zack Weinberg <zackw(a)panix.com>
Date: Fri Jul 8 12:03:06 2011 -0700
Aggressive removal of nested includes from header files. Potential not to compile on Windows.
---
src/network.c | 9 ++++++---
src/network.h | 17 ++++-------------
src/protocol.h | 20 ++++++++++----------
src/socks.h | 25 ++++++++++++-------------
src/util.h | 4 ++--
5 files changed, 34 insertions(+), 41 deletions(-)
diff --git a/src/network.c b/src/network.c
index ed78104..0faf136 100644
--- a/src/network.c
+++ b/src/network.c
@@ -10,10 +10,13 @@
#include "socks.h"
#include <assert.h>
+#include <errno.h>
#include <stdlib.h>
#include <string.h>
-#include <errno.h>
+#include <event2/buffer.h>
+#include <event2/bufferevent.h>
+#include <event2/listener.h>
#include <event2/util.h>
#ifdef _WIN32
@@ -43,7 +46,7 @@ static void output_event_cb(struct bufferevent *bev, short what, void *arg);
This function sets up the protocol defined by 'options' and
attempts to bind a new listener for it.
- Returns the listener on success, NULL on fail.
+ Returns the listener on success, NULL on fail.
*/
listener_t *
listener_new(struct event_base *base,
@@ -60,7 +63,7 @@ listener_new(struct event_base *base,
}
lsn->proto_params = proto_params;
-
+
lsn->listener = evconnlistener_new_bind(base, simple_listener_cb, lsn,
flags,
-1,
diff --git a/src/network.h b/src/network.h
index 2a1daeb..7bc4811 100644
--- a/src/network.h
+++ b/src/network.h
@@ -5,19 +5,7 @@
#ifndef NETWORK_H
#define NETWORK_H
-#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;
struct event_base;
-struct socks_state_t;
struct protocol_params_t;
#define LSN_SIMPLE_CLIENT 1
@@ -41,13 +29,16 @@ enum recv_ret {
};
typedef struct listener_t listener_t;
-struct addrinfo;
listener_t *listener_new(struct event_base *base,
struct protocol_params_t *params);
void listener_free(listener_t *listener);
#ifdef NETWORK_PRIVATE
+struct bufferevent;
+struct socks_state_t;
+struct protocol_t;
+
typedef struct conn_t {
struct socks_state_t *socks_state;
struct protocol_t *proto; /* ASN Do we like this here? We probably don't.
diff --git a/src/protocol.h b/src/protocol.h
index ceae438..483bae2 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -2,11 +2,11 @@
See LICENSE for other credits and copying information
*/
-#include <event2/buffer.h>
-
#ifndef PROTOCOL_H
#define PROTOCOL_H
+#include <sys/socket.h> /* for sockaddr & sockaddr_storage - FIXME */
+
struct evbuffer;
struct listener_t;
@@ -15,7 +15,7 @@ struct listener_t;
/**
This struct defines parameters of the protocol per-listener basis.
-
+
By 'per-listener basis' I mean that the parameters defined here will
be inherited by *all* connections opened from the listener_t that
owns this protocol_params_t.
@@ -35,7 +35,7 @@ typedef struct protocol_params_t {
struct protocol_t {
/* protocol vtable */
struct protocol_vtable *vtable;
-
+
/* This protocol specific struct defines the state of the protocol
per-connection basis.
@@ -48,7 +48,7 @@ struct protocol_t {
*/
void *state;
};
-int set_up_protocol(int n_options, char **options,
+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);
@@ -58,16 +58,16 @@ enum recv_ret proto_recv(struct protocol_t *proto, void *source, void *dest);
void proto_params_free(protocol_params_t *params);
-
typedef struct protocol_vtable {
/* Initialization function: Fills in the protocol vtable. */
- int (*init)(int n_options, char **options,
+ 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_params,
+ void *(*create)(struct protocol_t *proto_params,
struct protocol_params_t *parameters);
/* does handshake. Not all protocols have a handshake. */
@@ -75,12 +75,12 @@ typedef struct protocol_vtable {
struct evbuffer *buf);
/* send data function */
- int (*send)(void *state,
+ int (*send)(void *state,
struct evbuffer *source,
struct evbuffer *dest);
/* receive data function */
- enum recv_ret (*recv)(void *state,
+ enum recv_ret (*recv)(void *state,
struct evbuffer *source,
struct evbuffer *dest);
diff --git a/src/socks.h b/src/socks.h
index 2f1e44b..ef7b953 100644
--- a/src/socks.h
+++ b/src/socks.h
@@ -5,14 +5,9 @@
#ifndef SOCKS_H
#define SOCKS_H
-#ifdef _WIN32
-#include <Winsock2.h>
-#else
-#include <netdb.h>
-#endif
-
typedef struct socks_state_t socks_state_t;
struct evbuffer;
+struct sockaddr;
enum socks_status_t {
/* Waiting for initial socks4 or socks5 message */
@@ -33,7 +28,8 @@ enum socks_ret {
};
enum socks_ret handle_socks(struct evbuffer *source,
- struct evbuffer *dest, socks_state_t *socks_state);
+ struct evbuffer *dest,
+ socks_state_t *socks_state);
socks_state_t *socks_state_new(void);
void socks_state_free(socks_state_t *s);
@@ -44,7 +40,7 @@ int socks_state_get_address(const socks_state_t *state,
int *port_out);
int socks_state_set_address(socks_state_t *state, const struct sockaddr *sa);
int socks_send_reply(socks_state_t *state, struct evbuffer *dest, int error);
-int socks5_send_reply(struct evbuffer *reply_dest,
+int socks5_send_reply(struct evbuffer *reply_dest,
socks_state_t *state, int status);
@@ -108,11 +104,14 @@ enum socks_ret socks5_handle_negotiation(struct evbuffer *source,
struct evbuffer *dest, socks_state_t *state);
int socks5_send_reply(struct evbuffer *reply_dest, socks_state_t *state,
int status);
-enum socks_ret socks5_handle_request(struct evbuffer *source, struct parsereq *parsereq);
+enum socks_ret socks5_handle_request(struct evbuffer *source,
+ struct parsereq *parsereq);
-enum socks_ret socks4_read_request(struct evbuffer *source, socks_state_t *state);
-int socks4_send_reply(struct evbuffer *dest,
+enum socks_ret socks4_read_request(struct evbuffer *source,
+ socks_state_t *state);
+int socks4_send_reply(struct evbuffer *dest,
socks_state_t *state, int status);
-#endif
-#endif
+#endif /* SOCKS_PRIVATE */
+
+#endif /* socks.h */
diff --git a/src/util.h b/src/util.h
index ee04c85..90c55c2 100644
--- a/src/util.h
+++ b/src/util.h
@@ -5,8 +5,8 @@
#ifndef UTIL_H
#define UTIL_H
-/* va_list definition */
-#include <stdarg.h>
+#include <stdarg.h> /* for va_list */
+#include <stddef.h> /* for size_t etc */
struct sockaddr_storage;
struct event_base;
1
0
[obfsproxy/master] Avoid embedding struct sockaddr in protocol_params_t.
by nickm@torproject.org 14 Jul '11
by nickm@torproject.org 14 Jul '11
14 Jul '11
commit 54336bf81d57b44c772fff24df21a058f301dd91
Author: Zack Weinberg <zackw(a)panix.com>
Date: Fri Jul 8 14:27:39 2011 -0700
Avoid embedding struct sockaddr in protocol_params_t.
resolve_address_port now heap-allocates a buffer of exactly the
right size for the sockaddr coming back from evutil_getaddrinfo,
and copies a *pointer* to it into an outparam. This removes the
size limit, the need to include <sys/socket.h> in protocol.h,
and code duplicated in all callers of resolve_address_port.
It might make sense to have resolve_address_port return the entire
evutil_addrinfo structure (eliminating the remaining copy) but
let's not go there just yet.
---
src/network.c | 6 +++---
src/protocol.c | 12 ++++++++----
src/protocol.h | 15 +++++++--------
src/protocols/dummy.c | 21 +++++++--------------
src/protocols/obfs2.c | 32 ++++++++++----------------------
src/util.c | 15 ++++++---------
src/util.h | 6 +++---
7 files changed, 44 insertions(+), 63 deletions(-)
diff --git a/src/network.c b/src/network.c
index 0faf136..dfa086c 100644
--- a/src/network.c
+++ b/src/network.c
@@ -67,8 +67,8 @@ listener_new(struct event_base *base,
lsn->listener = evconnlistener_new_bind(base, simple_listener_cb, lsn,
flags,
-1,
- &lsn->proto_params->on_address,
- lsn->proto_params->on_address_len);
+ lsn->proto_params->listen_address,
+ lsn->proto_params->listen_address_len);
if (!lsn->listener) {
log_warn("Failed to create listener!");
@@ -166,7 +166,7 @@ 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->proto_params->target_address,
+ lsn->proto_params->target_address,
lsn->proto_params->target_address_len)<0)
goto err;
diff --git a/src/protocol.c b/src/protocol.c
index 544dcef..e306c8e 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -28,7 +28,7 @@ int n_supported_protocols = 2;
of obfsproxy.
*/
int
-set_up_protocol(int n_options, char **options,
+set_up_protocol(int n_options, char **options,
struct protocol_params_t *params)
{
if (!strcmp(*options,"dummy"))
@@ -41,7 +41,7 @@ set_up_protocol(int n_options, char **options,
/**
This function creates a protocol object.
- It's called once per connection.
+ It's called once per connection.
It creates a new protocol_t structure and fills it's vtable etc.
Return a 'protocol_t' if successful, NULL otherwise.
*/
@@ -80,7 +80,7 @@ proto_send(struct protocol_t *proto, void *source, void *dest) {
assert(proto);
if (proto->vtable->send)
return proto->vtable->send(proto->state, source, dest);
- else
+ else
return -1;
}
@@ -100,7 +100,7 @@ proto_recv(struct protocol_t *proto, void *source, void *dest) {
This function destroys 'proto'.
It's called everytime we close a connection.
*/
-void
+void
proto_destroy(struct protocol_t *proto) {
assert(proto);
assert(proto->state);
@@ -120,6 +120,10 @@ proto_params_free(protocol_params_t *params)
{
assert(params);
+ if (params->target_address)
+ free(params->target_address);
+ if (params->listen_address)
+ free(params->listen_address);
if (params->shared_secret)
free(params->shared_secret);
free(params);
diff --git a/src/protocol.h b/src/protocol.h
index 483bae2..1f0e7dd 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -5,10 +5,9 @@
#ifndef PROTOCOL_H
#define PROTOCOL_H
-#include <sys/socket.h> /* for sockaddr & sockaddr_storage - FIXME */
-
struct evbuffer;
struct listener_t;
+struct sockaddr;
#define DUMMY_PROTOCOL 1
#define OBFS2_PROTOCOL 2
@@ -21,15 +20,15 @@ struct listener_t;
owns this protocol_params_t.
*/
typedef struct protocol_params_t {
+ struct sockaddr *target_address;
+ struct sockaddr *listen_address;
+ char *shared_secret;
+ size_t shared_secret_len;
+ size_t target_address_len;
+ size_t listen_address_len;
int is_initiator;
- 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 {
diff --git a/src/protocols/dummy.c b/src/protocols/dummy.c
index bdf97fc..8db5d51 100644
--- a/src/protocols/dummy.c
+++ b/src/protocols/dummy.c
@@ -57,13 +57,11 @@ dummy_init(int n_options, char **options,
}
static int
-parse_and_set_options(int n_options, char **options,
+parse_and_set_options(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)
return -1;
@@ -82,17 +80,13 @@ parse_and_set_options(int n_options, char **options,
} else
return -1;
- if (resolve_address_port(options[2], 1, 1,
- &ss_listen, &sl_listen, defport) < 0) {
+ if (resolve_address_port(options[2], 1, 1,
+ ¶ms->listen_address,
+ ¶ms->listen_address_len, defport) < 0) {
log_warn("addr");
return -1;
}
- 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;
-
+
return 1;
}
@@ -108,7 +102,6 @@ usage(void)
"Example:\n"
"\tobfsproxy dummy socks 127.0.0.1:5000\n");
}
-
void *
@@ -117,7 +110,7 @@ dummy_new(struct protocol_t *proto_struct,
{
proto_struct->vtable = vtable;
- /* Dodging state check.
+ /* Dodging state check.
This is terrible I know.*/
return (void *)666U;
}
diff --git a/src/protocols/obfs2.c b/src/protocols/obfs2.c
index 676ddd7..57a695f 100644
--- a/src/protocols/obfs2.c
+++ b/src/protocols/obfs2.c
@@ -25,7 +25,7 @@ static int obfs2_send(void *state,
struct evbuffer *source, struct evbuffer *dest);
static enum recv_ret obfs2_recv(void *state, struct evbuffer *source,
struct evbuffer *dest);
-static void *obfs2_state_new(protocol_params_t *params);
+static void *obfs2_state_new(protocol_params_t *params);
static int obfs2_state_set_shared_secret(void *s,
const char *secret,
size_t secretlen);
@@ -34,7 +34,7 @@ static void usage(void);
static protocol_vtable *vtable=NULL;
-/*
+/*
This function parses 'options' and fills the protocol parameters
structure 'params'.
It then fills the obfs2 vtable and initializes the crypto subsystem.
@@ -42,7 +42,7 @@ static protocol_vtable *vtable=NULL;
Returns 0 on success, -1 on fail.
*/
int
-obfs2_init(int n_options, char **options,
+obfs2_init(int n_options, char **options,
struct protocol_params_t *params)
{
if (parse_and_set_options(n_options,options,params) < 0) {
@@ -62,11 +62,9 @@ obfs2_init(int n_options, char **options,
}
int
-parse_and_set_options(int n_options, char **options,
+parse_and_set_options(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;
@@ -85,21 +83,15 @@ parse_and_set_options(int n_options, char **options,
if (!strncmp(*options,"--dest=",7)) {
if (got_dest)
return -1;
- 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)
+ ¶ms->target_address,
+ ¶ms->target_address_len, NULL) < 0)
return -1;
- 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)
return -1;
- /* this is freed in protocol_params_free() */
+ /* this is freed in proto_params_free() */
params->shared_secret = strdup(*options+16);
params->shared_secret_len = strlen(*options+16);
got_ss=1;
@@ -127,14 +119,10 @@ parse_and_set_options(int n_options, char **options,
params->is_initiator = (params->mode != LSN_SIMPLE_SERVER);
- if (resolve_address_port(*options, 1, 1,
- &ss_listen, &sl_listen, defport) < 0)
+ if (resolve_address_port(*options, 1, 1,
+ ¶ms->listen_address,
+ ¶ms->listen_address_len, defport) < 0)
return -1;
- 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)) {
diff --git a/src/util.c b/src/util.c
index 70a6586..ce9a042 100644
--- a/src/util.c
+++ b/src/util.c
@@ -38,8 +38,8 @@ static void logv(int severity, const char *format, va_list ap);
int
resolve_address_port(const char *address,
int nodns, int passive,
- struct sockaddr_storage *addr_out,
- int *addrlen_out,
+ struct sockaddr **addr_out,
+ size_t *addrlen_out,
const char *default_port)
{
struct evutil_addrinfo *ai = NULL;
@@ -78,13 +78,10 @@ resolve_address_port(const char *address,
log_warn("No result for address %s", address);
goto done;
}
- if (ai->ai_addrlen > sizeof(struct sockaddr_storage)) {
- log_warn("Result for address %s too long", address);
- goto done;
- }
-
- memcpy(addr_out, ai->ai_addr, ai->ai_addrlen);
- *addrlen_out = (int) ai->ai_addrlen;
+ struct sockaddr *addr = malloc(ai->ai_addrlen);
+ memcpy(addr, ai->ai_addr, ai->ai_addrlen);
+ *addr_out = addr;
+ *addrlen_out = ai->ai_addrlen;
result = 0;
done:
diff --git a/src/util.h b/src/util.h
index 90c55c2..9a8a577 100644
--- a/src/util.h
+++ b/src/util.h
@@ -8,7 +8,7 @@
#include <stdarg.h> /* for va_list */
#include <stddef.h> /* for size_t etc */
-struct sockaddr_storage;
+struct sockaddr;
struct event_base;
struct evdns_base;
@@ -16,8 +16,8 @@ struct evdns_base;
int resolve_address_port(const char *address,
int nodns, int passive,
- struct sockaddr_storage *addr_out,
- int *addrlen_out,
+ struct sockaddr **addr_out,
+ size_t *addrlen_out,
const char *default_port);
struct evdns_base *get_evdns_base(void);
1
0
commit 97e0e668dde5168c926722d367cc86bef2fb38c3
Author: Zack Weinberg <zackw(a)panix.com>
Date: Fri Jul 8 15:38:16 2011 -0700
Clean up the logging API.
Not so many ifdefs, and now uses the standard unixy -1/error, 0/success
return value convention where that makes sense, or no return value at
all for functions that shouldn't ever fail.
---
src/main.c | 3 +-
src/util.c | 122 +++++++++++++++++++++--------------------------------------
src/util.h | 60 +++++++++++++-----------------
3 files changed, 71 insertions(+), 114 deletions(-)
diff --git a/src/main.c b/src/main.c
index a8347c2..0ba1f3f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -362,8 +362,7 @@ main(int argc, const char **argv)
log_info("Exiting.");
- if (close_obfsproxy_logfile() < 0)
- printf("Failed closing logfile!\n");
+ close_obfsproxy_logfile();
/* We are exiting. Clean everything. */
for (h=0;h<n_listeners;h++)
diff --git a/src/util.c b/src/util.c
index ce9a042..9ac2260 100644
--- a/src/util.c
+++ b/src/util.c
@@ -25,14 +25,6 @@
/** Any size_t larger than this amount is likely to be an underflow. */
#define SIZE_T_CEILING (SIZE_MAX/2 - 16)
-static const char *sev_to_string(int severity);
-static int sev_is_valid(int severity);
-static int write_logfile_prologue(int fd);
-static int compose_logfile_prologue(char *buf, size_t buflen);
-static int string_to_sev(const char *string);
-static int open_and_set_obfsproxy_logfile(const char *filename);
-static void logv(int severity, const char *format, va_list ap);
-
/************************ Obfsproxy Network Routines *************************/
int
@@ -146,7 +138,7 @@ obfs_vsnprintf(char *str, size_t size, const char *format, va_list args)
}
/************************ Logging Subsystem *************************/
-/** The code of this section was to a great extend shamelessly copied
+/** The code of this section was to a great extent shamelessly copied
off tor. It's basicaly a stripped down version of tor's logging
system. Thank you tor. */
@@ -157,6 +149,12 @@ obfs_vsnprintf(char *str, size_t size, const char *format, va_list args)
/* strlen(TRUNCATED_STR) */
#define TRUNCATED_STR_LEN 14
+/** Logging severities */
+
+#define LOG_SEV_WARN 3
+#define LOG_SEV_INFO 2
+#define LOG_SEV_DEBUG 1
+
/* logging method */
static int logging_method=LOG_METHOD_STDOUT;
/* minimum logging severity */
@@ -199,31 +197,12 @@ string_to_sev(const char *string)
static int
sev_is_valid(int severity)
{
- return (severity == LOG_SEV_WARN ||
- severity == LOG_SEV_INFO ||
+ return (severity == LOG_SEV_WARN ||
+ severity == LOG_SEV_INFO ||
severity == LOG_SEV_DEBUG);
}
/**
- Sets the global logging 'method' and also sets and open the logfile
- 'filename' in case we want to log into a file.
- It returns 1 on success and -1 on fail.
-*/
-int
-log_set_method(int method, const char *filename)
-{
-
- logging_method = method;
- if (method == LOG_METHOD_FILE) {
- if (open_and_set_obfsproxy_logfile(filename) < 0)
- return -1;
- if (write_logfile_prologue(logging_logfile) < 0)
- return -1;
- }
- return 1;
-}
-
-/**
Helper: Opens 'filename' and sets it as the obfsproxy logfile.
On success it returns 1, on fail it returns -1.
*/
@@ -232,56 +211,55 @@ open_and_set_obfsproxy_logfile(const char *filename)
{
if (!filename)
return -1;
- logging_logfile = open(filename,
+ logging_logfile = open(filename,
O_WRONLY|O_CREAT|O_APPEND,
0644);
if (logging_logfile < 0)
return -1;
- return 1;
+ return 0;
}
/**
Closes the obfsproxy logfile if it exists.
- Returns 0 on success or if we weren't using a logfile (that's
- close()'s success return value) and -1 on failure.
+ Ignores errors.
*/
-int
+void
close_obfsproxy_logfile(void)
{
- if (logging_logfile < 0) /* no logfile. */
- return 0;
- else
- return close(logging_logfile);
+ if (logging_logfile >= 0)
+ close(logging_logfile);
}
/**
- Writes a small prologue in the logfile 'fd' that mentions the
- obfsproxy version and helps separate log instances.
+ Writes a small prologue in the logfile 'fd' to separate log
+ instances.
*/
static int
-write_logfile_prologue(int logfile) {
- char buf[256];
- if (compose_logfile_prologue(buf, sizeof(buf)) < 0)
- return -1;
- if (write(logfile, buf, strlen(buf)) < 0)
+write_logfile_prologue(int logfile)
+{
+ static const char prologue[] = "\nBrand new obfsproxy log:\n";
+ if (write(logfile, prologue, strlen(prologue)) != strlen(prologue))
return -1;
- return 1;
+ return 0;
}
-#define TEMP_PROLOGUE "\nBrand new obfsproxy log:\n"
/**
- Helper: Composes the logfile prologue.
+ Sets the global logging 'method' and also sets and open the logfile
+ 'filename' in case we want to log into a file.
+ It returns 1 on success and -1 on fail.
*/
-static int
-compose_logfile_prologue(char *buf, size_t buflen)
-{
- if (obfs_snprintf(buf, buflen, TEMP_PROLOGUE) < 0) {
- log_warn("Logfile prologue couldn't be written.");
- return -1;
+int
+log_set_method(int method, const char *filename)
+{
+ logging_method = method;
+ if (method == LOG_METHOD_FILE) {
+ if (open_and_set_obfsproxy_logfile(filename) < 0)
+ return -1;
+ if (write_logfile_prologue(logging_logfile) < 0)
+ return -1;
}
- return 1;
+ return 0;
}
-#undef TEMP_PROLOGUE
/**
Sets the minimum logging severity of obfsproxy to the severity
@@ -289,37 +267,23 @@ compose_logfile_prologue(char *buf, size_t buflen)
not a valid severity, it returns -1.
*/
int
-log_set_min_severity(const char* sev_string) {
+log_set_min_severity(const char* sev_string)
+{
int severity = string_to_sev(sev_string);
if (!sev_is_valid(severity)) {
log_warn("Severity '%s' makes no sense.", sev_string);
return -1;
}
logging_min_sev = severity;
- return 1;
+ return 0;
}
/**
- Logging function of obfsproxy.
- Don't call this directly; use the log_* macros defined in util.h
- instead.
-
- It accepts a logging 'severity' and a 'format' string and logs the
+ Logging worker function.
+ Accepts a logging 'severity' and a 'format' string and logs the
message in 'format' according to the configured obfsproxy minimum
logging severity and logging method.
*/
-void
-log_fn(int severity, const char *format, ...)
-{
-
- va_list ap;
- va_start(ap,format);
-
- logv(severity, format, ap);
-
- va_end(ap);
-}
-
static void
logv(int severity, const char *format, va_list ap)
{
@@ -369,7 +333,8 @@ logv(int severity, const char *format, va_list ap)
assert(0);
}
-#ifdef NEED_LOG_WRAPPERS
+/**** Public logging API. ****/
+
void
log_info(const char *format, ...)
{
@@ -380,6 +345,7 @@ log_info(const char *format, ...)
va_end(ap);
}
+
void
log_warn(const char *format, ...)
{
@@ -390,6 +356,7 @@ log_warn(const char *format, ...)
va_end(ap);
}
+
void
log_debug(const char *format, ...)
{
@@ -400,4 +367,3 @@ log_debug(const char *format, ...)
va_end(ap);
}
-#endif
diff --git a/src/util.h b/src/util.h
index 9a8a577..f52f335 100644
--- a/src/util.h
+++ b/src/util.h
@@ -8,6 +8,10 @@
#include <stdarg.h> /* for va_list */
#include <stddef.h> /* for size_t etc */
+#ifndef __GNUC__
+#define __attribute__(x) /* nothing */
+#endif
+
struct sockaddr;
struct event_base;
struct evdns_base;
@@ -25,10 +29,6 @@ int init_evdns_base(struct event_base *base);
/***** String functions stuff. *****/
-#ifndef __GNUC__
-#define __attribute__(x)
-#endif
-
int obfs_vsnprintf(char *str, size_t size,
const char *format, va_list args);
int obfs_snprintf(char *str, size_t size,
@@ -37,30 +37,6 @@ int obfs_snprintf(char *str, size_t size,
/***** Logging subsystem stuff. *****/
-void log_fn(int severity, const char *format, ...)
- __attribute__((format(printf, 2, 3)));
-int log_set_method(int method, const char *filename);
-int log_set_min_severity(const char* sev_string);
-int close_obfsproxy_logfile(void);
-
-#ifdef __GNUC__
-#define log_info(args...) log_fn(LOG_SEV_INFO, args)
-#define log_warn(args...) log_fn(LOG_SEV_WARN, args)
-#define log_debug(args...) log_fn(LOG_SEV_DEBUG, args)
-#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-#define log_info(...) log_fn(LOG_SEV_INFO, __VA_ARGS__)
-#define log_warn(...) log_fn(LOG_SEV_WARN, __VA_ARGS__)
-#define log_debug(...) log_fn(LOG_SEV_DEBUG, __VA_ARGS__)
-#else
-#define NEED_LOG_WRAPPERS
-void log_info(const char *format, ...)
- __attribute__((format(printf, 1, 2)));
-void log_warn(const char *format, ...)
- __attribute__((format(printf, 1, 2)));
-void log_debug(const char *format, ...)
- __attribute__((format(printf, 1, 2)));
-#endif
-
/** Logging methods */
/** Spit log messages on stdout. */
@@ -68,17 +44,33 @@ void log_debug(const char *format, ...)
/** Place log messages in a file. */
#define LOG_METHOD_FILE 2
/** We don't want no logs. */
-#define LOG_METHOD_NULL 3
+#define LOG_METHOD_NULL 3
+
+/** Set the log method, and open the logfile 'filename' if appropriate. */
+int log_set_method(int method, const char *filename);
+
+/** Set the minimum severity that will be logged.
+ 'sev_string' may be "warn", "info", or "debug" (case-insensitively). */
+int log_set_min_severity(const char* sev_string);
+
+/** Close the logfile if it's open. Ignores errors. */
+void close_obfsproxy_logfile(void);
+
+/** The actual log-emitting functions */
-/** Logging severities */
+/** Warn-level severity: for messages that only appear when something
+ has gone wrong. */
+void log_warn(const char *format, ...)
+ __attribute__((format(printf, 1, 2)));
-/** Warn-level severity: for messages that only appear when something has gone wrong. */
-#define LOG_SEV_WARN 3
/** Info-level severity: for messages that should be sent to the user
during normal operation. */
-#define LOG_SEV_INFO 2
+void log_info(const char *format, ...)
+ __attribute__((format(printf, 1, 2)));
+
/** Debug-level severity: for hyper-verbose messages of no interest to
anybody but developers. */
-#define LOG_SEV_DEBUG 1
+void log_debug(const char *format, ...)
+ __attribute__((format(printf, 1, 2)));
#endif
1
0
[obfsproxy/master] Move obfs2_crypt.[ch] to top level and rename them crypt.[ch].
by nickm@torproject.org 14 Jul '11
by nickm@torproject.org 14 Jul '11
14 Jul '11
commit 2032347fd043f41d1972bfeb0306b44a5122c148
Author: Zack Weinberg <zackw(a)panix.com>
Date: Fri Jul 8 16:17:59 2011 -0700
Move obfs2_crypt.[ch] to top level and rename them crypt.[ch].
---
Makefile.am | 20 ++--
src/crypt.c | 197 +++++++++++++++++++++++++++++++++++++++++
src/crypt.h | 59 +++++++++++++
src/protocols/obfs2.c | 8 +-
src/protocols/obfs2_crypt.c | 203 -------------------------------------------
src/protocols/obfs2_crypt.h | 61 -------------
src/test/unittest.c | 2 +-
src/test/unittest_crypt.c | 2 +-
src/test/unittest_obfs2.c | 2 +-
src/test/unittest_socks.c | 2 +-
10 files changed, 274 insertions(+), 282 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index eb32bdc..096c0fa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -8,13 +8,13 @@ noinst_LIBRARIES = libobfsproxy.a
noinst_PROGRAMS = unittests
libobfsproxy_a_SOURCES = \
+ src/crypt.c \
src/network.c \
src/protocol.c \
- src/socks.c \
- src/util.c \
- src/protocols/obfs2.c \
- src/protocols/obfs2_crypt.c \
- src/protocols/dummy.c
+ src/socks.c \
+ src/util.c \
+ src/protocols/dummy.c \
+ src/protocols/obfs2.c
obfsproxy_SOURCES = \
src/main.c
@@ -22,20 +22,20 @@ obfsproxy_SOURCES = \
unittests_SOURCES = \
src/test/tinytest.c \
src/test/unittest.c \
- src/test/unittest_obfs2.c \
src/test/unittest_crypt.c \
+ src/test/unittest_obfs2.c \
src/test/unittest_socks.c
noinst_HEADERS = \
+ src/crypt.h \
src/network.h \
src/protocol.h \
src/socks.h \
src/util.h \
- src/test/tinytest.h \
- src/test/tinytest_macros.h \
+ src/protocols/dummy.h \
src/protocols/obfs2.h \
- src/protocols/obfs2_crypt.h \
- src/protocols/dummy.h
+ src/test/tinytest.h \
+ src/test/tinytest_macros.h
EXTRA_DIST = doc/protocol-spec.txt src/sha256.c
diff --git a/src/crypt.c b/src/crypt.c
new file mode 100644
index 0000000..6c35f10
--- /dev/null
+++ b/src/crypt.c
@@ -0,0 +1,197 @@
+/* Copyright 2011 Nick Mathewson, George Kadianakis
+ See LICENSE for other credits and copying information
+*/
+
+#include "config.h"
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdint.h>
+
+#include <openssl/opensslv.h>
+#include <openssl/aes.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+
+#define CRYPT_PRIVATE
+#include "crypt.h"
+
+#if OPENSSL_VERSION_NUMBER >= 0x0090800f
+#define USE_OPENSSL_RANDPOLL 1
+#define USE_OPENSSL_SHA256 1
+#include <openssl/sha.h>
+#else
+#define STMT_BEGIN do {
+#define STMT_END } while (0)
+static void
+set_uint32(void *ptr, uint32_t val)
+{
+ memcpy(ptr, &val, 4);
+}
+static uint32_t
+get_uint32(const void *ptr)
+{
+ uint32_t val;
+ memcpy(&val, ptr, 4);
+ return val;
+}
+#define LTC_ARGCHK(x) assert((x))
+#include "../sha256.c"
+#endif
+
+int
+initialize_crypto(void)
+{
+ ERR_load_crypto_strings();
+
+#ifdef USE_OPENSSL_RANDPOLL
+ return RAND_poll() == 1 ? 0 : -1;
+#else
+ /* XXX Or maybe fall back to the arc4random implementation in libevent2? */
+ {
+ char buf[32];
+ int fd, n;
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd == -1) {
+ perror("open");
+ return -1;
+ }
+ n = read(fd, buf, sizeof(buf));
+ if (n != sizeof(buf)) {
+ close(fd);
+ return -1;
+ }
+ RAND_seed(buf, sizeof(buf));
+ close(fd);
+ return 0;
+ }
+#endif
+}
+
+void
+cleanup_crypto(void)
+{
+ ERR_free_strings();
+}
+
+/* =====
+ Digests
+ ===== */
+
+#ifdef USE_OPENSSL_SHA256
+struct digest_t {
+ SHA256_CTX ctx;
+};
+digest_t *
+digest_new(void)
+{
+ digest_t *d = malloc(sizeof(digest_t));
+ SHA256_Init(&d->ctx);
+ return d;
+}
+void
+digest_update(digest_t *d, const uchar *buf, size_t len)
+{
+ SHA256_Update(&d->ctx, buf, len);
+}
+size_t
+digest_getdigest(digest_t *d, uchar *buf, size_t len)
+{
+ uchar tmp[SHA256_LENGTH];
+ int n = 32;
+ SHA256_Final(tmp, &d->ctx);
+ if (len < 32)
+ n = len;
+ memcpy(buf, tmp, n);
+ memset(tmp, 0, sizeof(tmp));
+ return n;
+}
+#else
+struct digest_t {
+ sha256_state ctx;
+};
+digest_t *
+digest_new(void)
+{
+ digest_t *d = malloc(sizeof(digest_t));
+ sha256_init(&d->ctx);
+ return d;
+}
+void
+digest_update(digest_t *d, const uchar *buf, size_t len)
+{
+ sha256_process(&d->ctx, buf, len);
+}
+size_t
+digest_getdigest(digest_t *d, uchar *buf, size_t len)
+{
+ uchar tmp[SHA256_LENGTH];
+ int n = 32;
+ sha256_done(&d->ctx, tmp);
+ if (len < 32)
+ n = len;
+ memcpy(buf, tmp, n);
+ memset(tmp, 0, sizeof(tmp));
+ return n;
+}
+#endif
+
+void
+digest_free(digest_t *d)
+{
+ memset(d, 0, sizeof(digest_t));
+ free(d);
+}
+
+/* =====
+ Stream crypto
+ ===== */
+
+crypt_t *
+crypt_new(const uchar *key, size_t keylen)
+{
+ crypt_t *k;
+ if (keylen < AES_BLOCK_SIZE)
+ return NULL;
+
+ k = calloc(1, sizeof(crypt_t));
+ if (k == NULL)
+ return NULL;
+
+ AES_set_encrypt_key(key, 128, &k->key);
+
+ return k;
+}
+void
+crypt_set_iv(crypt_t *key, const uchar *iv, size_t ivlen)
+{
+ assert(ivlen == sizeof(key->ivec));
+ memcpy(key->ivec, iv, ivlen);
+}
+void
+stream_crypt(crypt_t *key, uchar *buf, size_t len)
+{
+ AES_ctr128_encrypt(buf, buf, /* XXX make sure this is okay to do. */
+ len,
+ &key->key, key->ivec, key->ecount_buf,
+ &key->pos);
+}
+void
+crypt_free(crypt_t *key)
+{
+ memset(key, 0, sizeof(key));
+ free(key);
+}
+
+/* =====
+ PRNG
+ ===== */
+
+int
+random_bytes(uchar *buf, size_t buflen)
+{
+ return RAND_bytes(buf, buflen) == 1 ? 0 : -1;
+}
diff --git a/src/crypt.h b/src/crypt.h
new file mode 100644
index 0000000..5681a4c
--- /dev/null
+++ b/src/crypt.h
@@ -0,0 +1,59 @@
+/* Copyright 2011 Nick Mathewson, George Kadianakis
+ See LICENSE for other credits and copying information
+*/
+
+#ifndef CRYPT_H
+#define CRYPT_H
+
+#define SHA256_LENGTH 32
+
+/* Stream cipher state */
+typedef struct crypt_t crypt_t;
+/* Digest state */
+typedef struct digest_t digest_t;
+
+typedef unsigned char uchar;
+
+/** Initialize global crypto state. Returrn 0 on success, -1 on failure */
+int initialize_crypto(void);
+/** Clean up global crypto state */
+void cleanup_crypto(void);
+
+/** Return a newly allocated digest state, or NULL on failure. */
+digest_t *digest_new(void);
+/** Add n bytes from b to the digest state. */
+void digest_update(digest_t *, const uchar *b, size_t n);
+/** Get a digest from the digest state. Put it in up the first n bytes of the
+buffer b. Return the number of bytes actually written.*/
+size_t digest_getdigest(digest_t *, uchar *b, size_t n);
+/** Clear and free a digest state */
+void digest_free(digest_t *);
+
+/** Return a new stream cipher state taking key and IV from the data provided.
+ * The data length must be exactly 32 */
+crypt_t *crypt_new(const uchar *, size_t);
+void crypt_set_iv(crypt_t *key, const uchar *iv, size_t ivlen);
+
+/** Encrypt n bytes of data in the buffer b, in place. */
+void stream_crypt(crypt_t *, uchar *b, size_t n);
+/** Clear and free a stream cipher state. */
+void crypt_free(crypt_t *);
+
+/** Set b to contain n random bytes. */
+int random_bytes(uchar *b, size_t n);
+
+#ifdef CRYPT_PRIVATE
+/* ==========
+ These definitions are not part of the crypt interface.
+ They're exposed here so that the unit tests can use them.
+ ==========
+*/
+struct crypt_t {
+ AES_KEY key;
+ uchar ivec[AES_BLOCK_SIZE];
+ uchar ecount_buf[AES_BLOCK_SIZE];
+ unsigned int pos;
+};
+#endif
+
+#endif
diff --git a/src/protocols/obfs2.c b/src/protocols/obfs2.c
index 57a695f..d297c16 100644
--- a/src/protocols/obfs2.c
+++ b/src/protocols/obfs2.c
@@ -10,15 +10,15 @@
#include <openssl/rand.h>
#include <event2/buffer.h>
-#define CRYPT_PROTOCOL_PRIVATE
-
-#include "obfs2_crypt.h"
-#include "obfs2.h"
+#include "../crypt.h"
#include "../network.h"
#include "../util.h"
#include "../protocol.h"
#include "../network.h"
+#define CRYPT_PROTOCOL_PRIVATE
+#include "obfs2.h"
+
static void obfs2_state_free(void *state);
static int obfs2_send_initial_message(void *state, struct evbuffer *buf);
static int obfs2_send(void *state,
diff --git a/src/protocols/obfs2_crypt.c b/src/protocols/obfs2_crypt.c
deleted file mode 100644
index 681fab6..0000000
--- a/src/protocols/obfs2_crypt.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/* Copyright 2011 Nick Mathewson, George Kadianakis
- See LICENSE for other credits and copying information
-*/
-
-#include "config.h"
-
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-#include <openssl/opensslv.h>
-#include <openssl/aes.h>
-#include <openssl/rand.h>
-#include <openssl/err.h>
-
-#define CRYPT_PRIVATE
-#include "obfs2_crypt.h"
-
-#if OPENSSL_VERSION_NUMBER >= 0x0090800f
-#define USE_OPENSSL_RANDPOLL 1
-#define USE_OPENSSL_SHA256 1
-#include <openssl/sha.h>
-#else
-#define STMT_BEGIN do {
-#define STMT_END } while (0)
-static void
-set_uint32(void *ptr, uint32_t val)
-{
- memcpy(ptr, &val, 4);
-}
-static uint32_t
-get_uint32(const void *ptr)
-{
- uint32_t val;
- memcpy(&val, ptr, 4);
- return val;
-}
-#define LTC_ARGCHK(x) assert((x))
-#include "../sha256.c"
-#endif
-
-int
-initialize_crypto(void)
-{
- ERR_load_crypto_strings();
-
-#ifdef USE_OPENSSL_RANDPOLL
- return RAND_poll() == 1 ? 0 : -1;
-#else
- /* XXX Or maybe fall back to the arc4random implementation in libevent2? */
- {
- char buf[32];
- int fd, n;
- fd = open("/dev/urandom", O_RDONLY);
- if (fd == -1) {
- perror("open");
- return -1;
- }
- n = read(fd, buf, sizeof(buf));
- if (n != sizeof(buf)) {
- close(fd);
- return -1;
- }
- RAND_seed(buf, sizeof(buf));
- close(fd);
- return 0;
- }
-#endif
-}
-
-void
-cleanup_crypto(void)
-{
- ERR_free_strings();
-}
-
-/* =====
- Digests
- ===== */
-
-#ifdef USE_OPENSSL_SHA256
-struct digest_t {
- SHA256_CTX ctx;
-};
-digest_t *
-digest_new(void)
-{
- digest_t *d = malloc(sizeof(digest_t));
- SHA256_Init(&d->ctx);
- return d;
-}
-void
-digest_update(digest_t *d, const uchar *buf, size_t len)
-{
- SHA256_Update(&d->ctx, buf, len);
-}
-size_t
-digest_getdigest(digest_t *d, uchar *buf, size_t len)
-{
- uchar tmp[SHA256_LENGTH];
- int n = 32;
- SHA256_Final(tmp, &d->ctx);
- if (len < 32)
- n = len;
- memcpy(buf, tmp, n);
- memset(tmp, 0, sizeof(tmp));
- return n;
-}
-#else
-struct digest_t {
- sha256_state ctx;
-};
-digest_t *
-digest_new(void)
-{
- digest_t *d = malloc(sizeof(digest_t));
- sha256_init(&d->ctx);
- return d;
-}
-void
-digest_update(digest_t *d, const uchar *buf, size_t len)
-{
- sha256_process(&d->ctx, buf, len);
-}
-size_t
-digest_getdigest(digest_t *d, uchar *buf, size_t len)
-{
- uchar tmp[SHA256_LENGTH];
- int n = 32;
- sha256_done(&d->ctx, tmp);
- if (len < 32)
- n = len;
- memcpy(buf, tmp, n);
- memset(tmp, 0, sizeof(tmp));
- return n;
-}
-#endif
-
-void
-digest_free(digest_t *d)
-{
- memset(d, 0, sizeof(digest_t));
- free(d);
-}
-
-/* =====
- Stream crypto
- ===== */
-
-crypt_t *
-crypt_new(const uchar *key, size_t keylen)
-{
- crypt_t *k;
- if (keylen < AES_BLOCK_SIZE)
- return NULL;
-
- k = calloc(1, sizeof(crypt_t));
- if (k == NULL)
- return NULL;
-
- AES_set_encrypt_key(key, 128, &k->key);
-
- return k;
-}
-void
-crypt_set_iv(crypt_t *key, const uchar *iv, size_t ivlen)
-{
- assert(ivlen == sizeof(key->ivec));
- memcpy(key->ivec, iv, ivlen);
-}
-void
-stream_crypt(crypt_t *key, uchar *buf, size_t len)
-{
- AES_ctr128_encrypt(buf, buf, /* XXX make sure this is okay to do. */
- len,
- &key->key, key->ivec, key->ecount_buf,
- &key->pos);
-}
-void
-crypt_free(crypt_t *key)
-{
- memset(key, 0, sizeof(key));
- free(key);
-}
-
-/* =====
- PRNG
- ===== */
-
-int
-random_bytes(uchar *buf, size_t buflen)
-{
- return RAND_bytes(buf, buflen) == 1 ? 0 : -1;
-}
diff --git a/src/protocols/obfs2_crypt.h b/src/protocols/obfs2_crypt.h
deleted file mode 100644
index b449047..0000000
--- a/src/protocols/obfs2_crypt.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright 2011 Nick Mathewson, George Kadianakis
- See LICENSE for other credits and copying information
-*/
-
-#ifndef OBFS2_CRYPT_H
-#define OBFS2_CRYPT_H
-
-#include <sys/types.h>
-
-#define SHA256_LENGTH 32
-
-/* Stream cipher state */
-typedef struct crypt_t crypt_t;
-/* Digest state */
-typedef struct digest_t digest_t;
-
-typedef unsigned char uchar;
-
-/** Initialize global crypto state. Returrn 0 on success, -1 on failure */
-int initialize_crypto(void);
-/** Clean up global crypto state */
-void cleanup_crypto(void);
-
-/** Return a newly allocated digest state, or NULL on failure. */
-digest_t *digest_new(void);
-/** Add n bytes from b to the digest state. */
-void digest_update(digest_t *, const uchar *b, size_t n);
-/** Get a digest from the digest state. Put it in up the first n bytes of the
-buffer b. Return the number of bytes actually written.*/
-size_t digest_getdigest(digest_t *, uchar *b, size_t n);
-/** Clear and free a digest state */
-void digest_free(digest_t *);
-
-/** Return a new stream cipher state taking key and IV from the data provided.
- * The data length must be exactly 32 */
-crypt_t *crypt_new(const uchar *, size_t);
-void crypt_set_iv(crypt_t *key, const uchar *iv, size_t ivlen);
-
-/** Encrypt n bytes of data in the buffer b, in place. */
-void stream_crypt(crypt_t *, uchar *b, size_t n);
-/** Clear and free a stream cipher state. */
-void crypt_free(crypt_t *);
-
-/** Set b to contain n random bytes. */
-int random_bytes(uchar *b, size_t n);
-
-#ifdef CRYPT_PRIVATE
-/* ==========
- These definitions are not part of the crypt interface.
- They're exposed here so that the unit tests can use them.
- ==========
-*/
-struct crypt_t {
- AES_KEY key;
- uchar ivec[AES_BLOCK_SIZE];
- uchar ecount_buf[AES_BLOCK_SIZE];
- unsigned int pos;
-};
-#endif
-
-#endif
diff --git a/src/test/unittest.c b/src/test/unittest.c
index 8ff3747..184a192 100644
--- a/src/test/unittest.c
+++ b/src/test/unittest.c
@@ -4,7 +4,7 @@
#include <stdlib.h>
#include "tinytest.h"
-#include "../protocols/obfs2_crypt.h"
+#include "../crypt.h"
extern struct testcase_t crypt_tests[];
extern struct testcase_t protocol_tests[];
diff --git a/src/test/unittest_crypt.c b/src/test/unittest_crypt.c
index b50d65d..a65f07b 100644
--- a/src/test/unittest_crypt.c
+++ b/src/test/unittest_crypt.c
@@ -9,7 +9,7 @@
#include <openssl/aes.h>
-#include "../protocols/obfs2_crypt.h"
+#include "../crypt.h"
struct crypt_t {
AES_KEY key;
diff --git a/src/test/unittest_obfs2.c b/src/test/unittest_obfs2.c
index af31adc..ec5cc47 100644
--- a/src/test/unittest_obfs2.c
+++ b/src/test/unittest_obfs2.c
@@ -14,7 +14,7 @@
#define CRYPT_PROTOCOL_PRIVATE
#define CRYPT_PRIVATE
-#include "../protocols/obfs2_crypt.h"
+#include "../crypt.h"
#include "../util.h"
#include "../protocol.h"
#include "../protocols/obfs2.h"
diff --git a/src/test/unittest_socks.c b/src/test/unittest_socks.c
index c77e3dc..1719f8e 100644
--- a/src/test/unittest_socks.c
+++ b/src/test/unittest_socks.c
@@ -12,7 +12,7 @@
#define SOCKS_PRIVATE
#include "../socks.h"
-#include "../protocols/obfs2_crypt.h"
+#include "../crypt.h"
#include "../util.h"
#include "../protocols/obfs2.h"
1
0
[obfsproxy/master] Switch to building sha256.c separately with an automake conditional. Not tested on a platform that *needs* sha256.c yet.
by nickm@torproject.org 14 Jul '11
by nickm@torproject.org 14 Jul '11
14 Jul '11
commit cae72e5d9fade85faa1c25ae63f324b266ed2789
Author: Zack Weinberg <zackw(a)panix.com>
Date: Fri Jul 8 16:33:14 2011 -0700
Switch to building sha256.c separately with an automake conditional. Not tested on a platform that *needs* sha256.c yet.
---
Makefile.am | 6 +++-
configure.ac | 6 ++++
src/crypt.c | 17 +----------
src/sha256.c | 88 +++++++++++++++------------------------------------------
src/sha256.h | 18 ++++++++++++
5 files changed, 53 insertions(+), 82 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 096c0fa..a78d7d0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -15,6 +15,9 @@ libobfsproxy_a_SOURCES = \
src/util.c \
src/protocols/dummy.c \
src/protocols/obfs2.c
+if NEED_SHA256
+libobfsproxy_a_SOURCES += src/sha256.c
+endif
obfsproxy_SOURCES = \
src/main.c
@@ -30,6 +33,7 @@ noinst_HEADERS = \
src/crypt.h \
src/network.h \
src/protocol.h \
+ src/sha256.h \
src/socks.h \
src/util.h \
src/protocols/dummy.h \
@@ -37,6 +41,6 @@ noinst_HEADERS = \
src/test/tinytest.h \
src/test/tinytest_macros.h
-EXTRA_DIST = doc/protocol-spec.txt src/sha256.c
+EXTRA_DIST = doc/protocol-spec.txt
TESTS = unittests
diff --git a/configure.ac b/configure.ac
index e49ddf3..7465708 100644
--- a/configure.ac
+++ b/configure.ac
@@ -25,6 +25,12 @@ AS_IF([test "x$ac_cv_lib_winsock" = xyes],
[ws32_LIBS=])
AC_SUBST(ws32_LIBS)
+save_LIBS="$LIBS"
+LIBS="$openssl_LIBS"
+AC_CHECK_FUNC(SHA256_Init, [:], [:])
+LIBS="$save_LIBS"
+AM_CONDITIONAL(NEED_SHA256, [test x$ac_cv_func_SHA256_Init = xno])
+
AC_CONFIG_FILES([Makefile])
AC_CONFIG_HEADERS([config.h])
AC_OUTPUT
diff --git a/src/crypt.c b/src/crypt.c
index 6c35f10..91868f2 100644
--- a/src/crypt.c
+++ b/src/crypt.c
@@ -24,22 +24,7 @@
#define USE_OPENSSL_SHA256 1
#include <openssl/sha.h>
#else
-#define STMT_BEGIN do {
-#define STMT_END } while (0)
-static void
-set_uint32(void *ptr, uint32_t val)
-{
- memcpy(ptr, &val, 4);
-}
-static uint32_t
-get_uint32(const void *ptr)
-{
- uint32_t val;
- memcpy(&val, ptr, 4);
- return val;
-}
-#define LTC_ARGCHK(x) assert((x))
-#include "../sha256.c"
+#include "sha256.h"
#endif
int
diff --git a/src/sha256.c b/src/sha256.c
index d28dcce..4833b99 100644
--- a/src/sha256.c
+++ b/src/sha256.c
@@ -4,12 +4,25 @@
LibTomCrypt, version 1.6. Tor uses it on platforms where OpenSSL doesn't
have a SHA256. */
-
-typedef struct sha256_state {
- uint64_t length;
- uint32_t state[8], curlen;
- unsigned char buf[64];
-} sha256_state;
+#include "sha256.h"
+#include <assert.h>
+#include <string.h>
+
+#define STMT_BEGIN do {
+#define STMT_END } while (0)
+static void
+set_uint32(void *ptr, uint32_t val)
+{
+ memcpy(ptr, &val, 4);
+}
+static uint32_t
+get_uint32(const void *ptr)
+{
+ uint32_t val;
+ memcpy(&val, ptr, 4);
+ return val;
+}
+#define LTC_ARGCHK(x) assert((x))
#define CRYPT_OK 0
#define CRYPT_NOP -1
@@ -43,26 +56,6 @@ typedef struct sha256_state {
SHA256 by Tom St Denis
*/
-
-#ifdef LTC_SMALL_CODE
-/* the K array */
-static const uint32_t K[64] = {
- 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
- 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
- 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
- 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
- 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
- 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
- 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
- 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
- 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
- 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
- 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
- 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
- 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
-};
-#endif
-
/* Various logical functions */
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
#define Maj(x,y,z) (((x | y) & z) | (x & y))
@@ -74,16 +67,9 @@ static const uint32_t K[64] = {
#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
/* compress 512-bits */
-#ifdef LTC_CLEAN_STACK
-static int _sha256_compress(sha256_state * md, unsigned char *buf)
-#else
static int sha256_compress(sha256_state * md, unsigned char *buf)
-#endif
{
uint32_t S[8], W[64], t0, t1;
-#ifdef LTC_SMALL_CODE
- uint32_t t;
-#endif
int i;
/* copy state into S */
@@ -102,19 +88,6 @@ static int sha256_compress(sha256_state * md, unsigned char *buf)
}
/* Compress */
-#ifdef LTC_SMALL_CODE
-#define RND(a,b,c,d,e,f,g,h,i) \
- t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
- t1 = Sigma0(a) + Maj(a, b, c); \
- d += t0; \
- h = t0 + t1;
-
- for (i = 0; i < 64; ++i) {
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i);
- t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
- S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
- }
-#else
#define RND(a,b,c,d,e,f,g,h,i,ki) \
t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
t1 = Sigma0(a) + Maj(a, b, c); \
@@ -188,8 +161,6 @@ static int sha256_compress(sha256_state * md, unsigned char *buf)
#undef RND
-#endif
-
/* feedback */
for (i = 0; i < 8; i++) {
md->state[i] = md->state[i] + S[i];
@@ -197,22 +168,12 @@ static int sha256_compress(sha256_state * md, unsigned char *buf)
return CRYPT_OK;
}
-#ifdef LTC_CLEAN_STACK
-static int sha256_compress(sha256_state * md, unsigned char *buf)
-{
- int err;
- err = _sha256_compress(md, buf);
- burn_stack(sizeof(uint32_t) * 74);
- return err;
-}
-#endif
-
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
-static int sha256_init(sha256_state * md)
+int sha256_init(sha256_state * md)
{
LTC_ARGCHK(md != NULL);
@@ -236,7 +197,8 @@ static int sha256_init(sha256_state * md)
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
-static int sha256_process (sha256_state * md, const unsigned char *in, unsigned long inlen)
+int sha256_process (sha256_state * md, const unsigned char *in,
+ unsigned long inlen)
{
unsigned long n;
int err;
@@ -277,7 +239,7 @@ static int sha256_process (sha256_state * md, const unsigned char *in, unsigned
@param out [out] The destination of the hash (32 bytes)
@return CRYPT_OK if successful
*/
-static int sha256_done(sha256_state * md, unsigned char *out)
+int sha256_done(sha256_state * md, unsigned char *out)
{
int i;
@@ -288,7 +250,6 @@ static int sha256_done(sha256_state * md, unsigned char *out)
return CRYPT_INVALID_ARG;
}
-
/* increase the length of the message */
md->length += md->curlen * 8;
@@ -320,9 +281,6 @@ static int sha256_done(sha256_state * md, unsigned char *out)
for (i = 0; i < 8; i++) {
STORE32H(md->state[i], out+(4*i));
}
-#ifdef LTC_CLEAN_STACK
- zeromem(md, sizeof(sha256_state));
-#endif
return CRYPT_OK;
}
diff --git a/src/sha256.h b/src/sha256.h
new file mode 100644
index 0000000..b6a75be
--- /dev/null
+++ b/src/sha256.h
@@ -0,0 +1,18 @@
+/* Header file for the fallback (libtomcrypt) implementation of SHA256. */
+#ifndef SHA256_H
+#define SHA256_H
+
+#include <stdint.h>
+
+typedef struct sha256_state {
+ uint64_t length;
+ uint32_t state[8], curlen;
+ unsigned char buf[64];
+} sha256_state;
+
+int sha256_init(sha256_state * md);
+int sha256_process(sha256_state * md, const unsigned char *in,
+ unsigned long inlen);
+int sha256_done(sha256_state * md, unsigned char *out);
+
+#endif
1
0
14 Jul '11
commit 3fb0f0ee7009cdfa8a6f9408695c8b3dacb25a31
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Thu Jul 14 12:11:42 2011 -0400
Oops; that return shouldn't be there.
---
src/network.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/src/network.c b/src/network.c
index b76ac8e..6d1d211 100644
--- a/src/network.c
+++ b/src/network.c
@@ -92,8 +92,6 @@ close_all_connections(void)
while (conn_list.head) {
conn_t *conn = UPCAST(conn_t, dll_node, conn_list.head);
conn_free(conn); /* removes it */
-
- return; /* connections are now all closed. */
}
assert(!n_connections);
}
1
0
commit 46762842d8eb314b13a158e725c472da0e0d3601
Author: George Kadianakis <desnacked(a)gmail.com>
Date: Sat Jun 11 00:03:33 2011 +0200
Updated function documentation.
---
src/main.c | 2 +-
src/network.c | 46 ++++++++++++++++++++++---
src/protocol.c | 5 +--
src/protocols/dummy.c | 29 +++++++++++++--
src/protocols/obfs2.c | 3 ++
src/protocols/obfs2_crypt.c | 42 +++++++++++++++++++++++
src/socks.c | 79 +++++++++++++++++++++++++++++++-----------
src/util.c | 16 +++++++++
8 files changed, 188 insertions(+), 34 deletions(-)
diff --git a/src/main.c b/src/main.c
index ace9e8c..9399783 100644
--- a/src/main.c
+++ b/src/main.c
@@ -80,7 +80,7 @@ populate_options(char **options_string,
}
/**
- Returns 1 if 'name' is the nmae of a supported protocol, otherwise
+ Returns 1 if 'name' is the name of a supported protocol, otherwise
it returns 0.
*/
static int
diff --git a/src/network.c b/src/network.c
index e3c2fa0..a0ab6e9 100644
--- a/src/network.c
+++ b/src/network.c
@@ -36,10 +36,9 @@ static void input_event_cb(struct bufferevent *bev, short what, void *arg);
static void output_event_cb(struct bufferevent *bev, short what, void *arg);
/**
- This function sets up the protocol defined by 'options' and
- attempts to bind a new listener for it.
+ This function spawns a listener according to the 'proto_params'.
- Returns the listener on success, NULL on fail.
+ Returns the listener on success and NULL on fail.
*/
listener_t *
listener_new(struct event_base *base,
@@ -72,6 +71,9 @@ listener_new(struct event_base *base,
return lsn;
}
+/**
+ Deallocates listener_t 'lsn'.
+*/
void
listener_free(listener_t *lsn)
{
@@ -83,9 +85,16 @@ listener_free(listener_t *lsn)
free(lsn);
}
+/**
+ This function is called when a new connection is received.
+
+ It initializes the protocol we are using, sets up the necessary
+ callbacks for input/output and does the protocol handshake.
+*/
static void
simple_listener_cb(struct evconnlistener *evcl,
- evutil_socket_t fd, struct sockaddr *sourceaddr, int socklen, void *arg)
+ evutil_socket_t fd, struct sockaddr *sourceaddr,
+ int socklen, void *arg)
{
listener_t *lsn = arg;
struct event_base *base;
@@ -174,6 +183,9 @@ simple_listener_cb(struct evconnlistener *evcl,
evutil_closesocket(fd);
}
+/**
+ Deallocates conn_t 'conn'.
+*/
static void
conn_free(conn_t *conn)
{
@@ -189,6 +201,10 @@ conn_free(conn_t *conn)
free(conn);
}
+/**
+ Closes associated connection if the output evbuffer of 'bev' is
+ empty.
+*/
static void
close_conn_on_flush(struct bufferevent *bev, void *arg)
{
@@ -198,7 +214,9 @@ close_conn_on_flush(struct bufferevent *bev, void *arg)
conn_free(conn);
}
-/** This is only used in the input bufferevent of clients. */
+/**
+ This callback is responsible for handling SOCKS traffic.
+*/
static void
socks_read_cb(struct bufferevent *bev, void *arg)
{
@@ -253,6 +271,9 @@ socks_read_cb(struct bufferevent *bev, void *arg)
}
}
+/**
+ This callback is responsible for handling plaintext traffic.
+*/
static void
plaintext_read_cb(struct bufferevent *bev, void *arg)
{
@@ -267,6 +288,11 @@ plaintext_read_cb(struct bufferevent *bev, void *arg)
conn_free(conn);
}
+/**
+ This callback is responsible for handling obfusacted
+ traffic -- traffic that has already been obfuscated
+ by our protocol.
+*/
static void
obfuscated_read_cb(struct bufferevent *bev, void *arg)
{
@@ -288,6 +314,10 @@ obfuscated_read_cb(struct bufferevent *bev, void *arg)
bufferevent_get_output(conn->output));
}
+/**
+ Something broke in our connection or we reached EOF.
+ We prepare the connection to be closed ASAP.
+*/
static void
error_or_eof(conn_t *conn,
struct bufferevent *bev_err, struct bufferevent *bev_flush)
@@ -311,6 +341,9 @@ error_or_eof(conn_t *conn,
bufferevent_enable(bev_flush, EV_WRITE);
}
+/**
+ We land in here when an event happens on conn->input.
+*/
static void
input_event_cb(struct bufferevent *bev, short what, void *arg)
{
@@ -325,6 +358,9 @@ input_event_cb(struct bufferevent *bev, short what, void *arg)
/* XXX we don't expect any other events */
}
+/**
+ We land in here when an event happens on conn->output.
+*/
static void
output_event_cb(struct bufferevent *bev, short what, void *arg)
{
diff --git a/src/protocol.c b/src/protocol.c
index 544dcef..0845c11 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -40,9 +40,8 @@ set_up_protocol(int n_options, char **options,
}
/**
- This function creates a protocol object.
- It's called once per connection.
- It creates a new protocol_t structure and fills it's vtable etc.
+ This function is called once per connection and creates a protocol
+ object to be used during the session.
Return a 'protocol_t' if successful, NULL otherwise.
*/
struct protocol_t *
diff --git a/src/protocols/dummy.c b/src/protocols/dummy.c
index bdf97fc..be4c287 100644
--- a/src/protocols/dummy.c
+++ b/src/protocols/dummy.c
@@ -26,9 +26,10 @@ static int parse_and_set_options(int n_options, char **options,
struct protocol_params_t *params);
static protocol_vtable *vtable=NULL;
+
/**
- This function sets up the protocol and populates 'listner'
- according to 'options'.
+ This function populates 'params' according to 'options' and sets up
+ the protocol vtable.
'options' is an array like this:
{"dummy","socks","127.0.0.1:6666"}
@@ -56,6 +57,9 @@ dummy_init(int n_options, char **options,
return 1;
}
+/**
+ Helper: Parses 'options' and fills 'params'.
+*/
static int
parse_and_set_options(int n_options, char **options,
struct protocol_params_t *params)
@@ -96,6 +100,9 @@ parse_and_set_options(int n_options, char **options,
return 1;
}
+/**
+ Prints dummy protocol usage information.
+*/
static void
usage(void)
{
@@ -109,8 +116,12 @@ usage(void)
"\tobfsproxy dummy socks 127.0.0.1:5000\n");
}
-
-
+/*
+ This is called everytime we get a connection for the dummy
+ protocol.
+
+ It sets up the protocol vtable in 'proto_struct'.
+*/
void *
dummy_new(struct protocol_t *proto_struct,
struct protocol_params_t *params)
@@ -122,6 +133,11 @@ dummy_new(struct protocol_t *proto_struct,
return (void *)666U;
}
+/**
+ Responsible for sending data according to the dummy protocol.
+
+ The dummy protocol just puts the data of 'source' in 'dest'.
+*/
static int
dummy_send(void *nothing,
struct evbuffer *source, struct evbuffer *dest) {
@@ -130,6 +146,11 @@ dummy_send(void *nothing,
return evbuffer_add_buffer(dest,source);
}
+/*
+ Responsible for receiving data according to the dummy protocol.
+
+ The dummy protocol just puts the data of 'source' into 'dest'.
+*/
static enum recv_ret
dummy_recv(void *nothing,
struct evbuffer *source, struct evbuffer *dest) {
diff --git a/src/protocols/obfs2.c b/src/protocols/obfs2.c
index 676ddd7..f4302a2 100644
--- a/src/protocols/obfs2.c
+++ b/src/protocols/obfs2.c
@@ -61,6 +61,9 @@ obfs2_init(int n_options, char **options,
return 1;
}
+/**
+ Helper: Parses 'options' and fills 'params'.
+*/
int
parse_and_set_options(int n_options, char **options,
struct protocol_params_t *params)
diff --git a/src/protocols/obfs2_crypt.c b/src/protocols/obfs2_crypt.c
index 681fab6..4e814e7 100644
--- a/src/protocols/obfs2_crypt.c
+++ b/src/protocols/obfs2_crypt.c
@@ -48,6 +48,9 @@ get_uint32(const void *ptr)
#include "../sha256.c"
#endif
+/**
+ Initializes the obfs2 crypto subsystem.
+*/
int
initialize_crypto(void)
{
@@ -77,6 +80,9 @@ initialize_crypto(void)
#endif
}
+/**
+ Cleans up the obfs2 crypto subsystem.
+*/
void
cleanup_crypto(void)
{
@@ -91,18 +97,33 @@ cleanup_crypto(void)
struct digest_t {
SHA256_CTX ctx;
};
+
+/**
+ Returns a new SHA256 digest container, or NULL on failure.
+*/
digest_t *
digest_new(void)
{
digest_t *d = malloc(sizeof(digest_t));
+ if (!d)
+ return NULL;
SHA256_Init(&d->ctx);
return d;
}
+
+/**
+ Updates the contents of the SHA256 container 'd' with the first
+ 'len' bytes of 'buf'.
+*/
void
digest_update(digest_t *d, const uchar *buf, size_t len)
{
SHA256_Update(&d->ctx, buf, len);
}
+
+/**
+ Returns the digest stored in 'd' into 'buf' of length 'len'.
+*/
size_t
digest_getdigest(digest_t *d, uchar *buf, size_t len)
{
@@ -123,6 +144,8 @@ digest_t *
digest_new(void)
{
digest_t *d = malloc(sizeof(digest_t));
+ if (!d)
+ return NULL;
sha256_init(&d->ctx);
return d;
}
@@ -156,6 +179,9 @@ digest_free(digest_t *d)
Stream crypto
===== */
+/**
+ Initializes the AES cipher with 'key'.
+*/
crypt_t *
crypt_new(const uchar *key, size_t keylen)
{
@@ -171,12 +197,20 @@ crypt_new(const uchar *key, size_t keylen)
return k;
}
+
+/**
+ Sets the IV of 'key' to 'iv'.
+*/
void
crypt_set_iv(crypt_t *key, const uchar *iv, size_t ivlen)
{
assert(ivlen == sizeof(key->ivec));
memcpy(key->ivec, iv, ivlen);
}
+
+/*
+ In-place encrypts 'buf' with 'key'.
+*/
void
stream_crypt(crypt_t *key, uchar *buf, size_t len)
{
@@ -185,6 +219,10 @@ stream_crypt(crypt_t *key, uchar *buf, size_t len)
&key->key, key->ivec, key->ecount_buf,
&key->pos);
}
+
+/**
+ Deallocates memory space of 'key'.
+*/
void
crypt_free(crypt_t *key)
{
@@ -196,6 +234,10 @@ crypt_free(crypt_t *key)
PRNG
===== */
+/**
+ Fills 'buf' with 'buflen' random bytes and returns 0 on success.
+ Returns -1 on failure.
+*/
int
random_bytes(uchar *buf, size_t buflen)
{
diff --git a/src/socks.c b/src/socks.c
index 7cf179b..d3c69f2 100644
--- a/src/socks.c
+++ b/src/socks.c
@@ -48,6 +48,11 @@ static enum socks_ret socks5_do_negotiation(struct evbuffer *dest,
typedef unsigned char uchar;
+/**
+ Creates a new SOCKS state.
+
+ Returns a 'socks_state_t' on success, NULL on fail.
+*/
socks_state_t *
socks_state_new(void)
{
@@ -59,6 +64,9 @@ socks_state_new(void)
return state;
}
+/**
+ Deallocates memory of socks_state_t 's'.
+*/
void
socks_state_free(socks_state_t *s)
{
@@ -108,17 +116,15 @@ socks_errno_to_reply(socks_state_t *state, int error)
#undef ERR
/**
- Takes a command request from 'source', it evaluates it and if it's
- legit it parses it into 'parsereq'.
-
- It returns '1' if everything went fine.
- It returns '0' if we need more data from the client.
- It returns '-1' if we didn't like something.
- It returns '-2' if the client asked for something else than CONNECT.
- If that's the case we should send a reply back to the client
- telling him that we don't support it.
+ Takes a SOCKS5 command request from 'source', it evaluates it and
+ if it's legit it parses it into 'parsereq'.
- Disclaimer: This is just a temporary documentation.
+ It returns SOCKS_GOOD if everything went fine.
+ It returns SOCKS_INCOMPLETE if we need more data from the client.
+ It returns SOCKS_BROKEN if we didn't like something.
+ It returns SOCKS_CMD_NOT_CONNECT if the client asked for something
+ else other than CONNECT. If that's the case we should send a reply
+ back to the client telling him that we don't support it.
Client Request (Client -> Server)
*/
@@ -223,7 +229,8 @@ socks5_handle_request(struct evbuffer *source, struct parsereq *parsereq)
}
/**
- This sends the appropriate reply to the client on 'reply_dest'.
+ This sends the appropriate SOCKS5 reply to the client on
+ 'reply_dest', according to 'status'.
Server Reply (Server -> Client):
| version | rep | rsv | atyp | destaddr | destport
@@ -281,7 +288,7 @@ socks5_send_reply(struct evbuffer *reply_dest, socks_state_t *state,
/**
This function handles the initial SOCKS5 packet in 'source' sent by
- the client, which negotiates the version and method of SOCKS. If
+ the client which negotiates the version and method of SOCKS. If
the packet is actually valid, we reply to 'dest'.
Method Negotiation Packet (Client -> Server):
@@ -351,7 +358,14 @@ socks5_do_negotiation(struct evbuffer *dest, unsigned int neg_was_success)
return SOCKS_GOOD;
}
-/* rename to socks4_handle_request or something. */
+/**
+ Takes a SOCKS4/SOCKS4a command request from 'source', it evaluates
+ it and if it's legit it parses it into 'parsereq'.
+
+ It returns SOCKS_GOOD if everything went fine.
+ It returns SOCKS_INCOMPLETE if we need more data from the client.
+ It returns SOCKS_BROKEN if we didn't like something.
+*/
enum socks_ret
socks4_read_request(struct evbuffer *source, socks_state_t *state)
{
@@ -418,13 +432,18 @@ socks4_read_request(struct evbuffer *source, socks_state_t *state)
} else {
struct in_addr in;
in.s_addr = htonl(ipaddr);
- if (evutil_inet_ntop(AF_INET, &in, state->parsereq.addr, sizeof(state->parsereq.addr)) == NULL)
+ if (evutil_inet_ntop(AF_INET, &in, state->parsereq.addr,
+ sizeof(state->parsereq.addr)) == NULL)
return SOCKS_BROKEN;
}
return SOCKS_GOOD;
}
+/**
+ This sends the appropriate SOCKS4 reply to the client on
+ 'reply_dest', according to 'status'.
+*/
int
socks4_send_reply(struct evbuffer *dest, socks_state_t *state, int status)
{
@@ -448,12 +467,15 @@ socks4_send_reply(struct evbuffer *dest, socks_state_t *state, int status)
}
/**
- We are given data from the network.
- If we haven't negotiated with the connection, we try to negotiate.
- If we have already negotiated, we suppose it's a CONNECT request and
- try to be helpful.
-
- Returns 1 on done, -1 on unrecoverable error, 0 on "need more bytes
+ We are given SOCKS data from the network.
+ We figure out what what SOCKS version it is and act accordingly.
+
+ It returns SOCKS_GOOD if everything went fine.
+ It returns SOCKS_INCOMPLETE if we need more data from the client.
+ It returns SOCKS_BROKEN if we didn't like something.
+ It returns SOCKS_CMD_NOT_CONNECT if the client asked for something
+ else other than CONNECT. If that's the case we should send a reply
+ back to the client telling him that we don't support it.
*/
enum socks_ret
handle_socks(struct evbuffer *source, struct evbuffer *dest,
@@ -533,12 +555,22 @@ handle_socks(struct evbuffer *source, struct evbuffer *dest,
return SOCKS_BROKEN;
}
+/**
+ Returns the protocol status of the SOCKS state 'state'.
+*/
enum socks_status_t
socks_state_get_status(const socks_state_t *state)
{
return state->state;
}
+/**
+ If we have previously parsed a SOCKS CONNECT request, this function
+ places the corresponding address/port to 'af_out', 'addr_out' and
+ 'port_out'.
+
+ It returns 0 on success and -1 if it was called unnecessarily.
+*/
int
socks_state_get_address(const socks_state_t *state,
int *af_out,
@@ -553,6 +585,10 @@ socks_state_get_address(const socks_state_t *state,
return 0;
}
+/**
+ Places the address/port in 'sa' into the SOCKS state 'state' for
+ later retrieval.
+*/
int
socks_state_set_address(socks_state_t *state, const struct sockaddr *sa)
{
@@ -583,11 +619,12 @@ socks_state_set_address(socks_state_t *state, const struct sockaddr *sa)
/**
This function sends a SOCKS{5,4} "Server Reply" to 'dest'.
+
'error' is 0 if no errors were encountered during the SOCKS
operation (normally a CONNECT with no errors means that the
connect() was successful).
If 'error' is not 0, it means that an error was encountered and
- error carries the errno(3) of the error.
+ error carries the errno(3).
*/
int
socks_send_reply(socks_state_t *state, struct evbuffer *dest, int error)
diff --git a/src/util.c b/src/util.c
index d4eddb6..1d44a52 100644
--- a/src/util.c
+++ b/src/util.c
@@ -27,6 +27,17 @@ static void logv(int severity, const char *format, va_list ap);
/************************ Obfsproxy Network Routines *************************/
+/**
+ Accepts a string 'address' of the form ADDRESS:PORT and attempts to
+ parse it into 'addr_out' and put it's length into 'addrlen_out'.
+
+ If 'nodns' is set it means that 'address' was an IP address.
+ If 'passive' is set it means that the address is destined for
+ listening and not for connecting.
+
+ If no port was given in 'address', we set 'default_port' as the
+ port.
+*/
int
resolve_address_port(const char *address,
int nodns, int passive,
@@ -369,6 +380,10 @@ logv(int severity, const char *format, va_list ap)
}
#ifdef NEED_LOG_WRAPPERS
+/**
+ If our platform doesn't support the log_* macros defined in
+ util.h, we use these functions.
+*/
void
log_info(const char *format, ...)
{
@@ -399,4 +414,5 @@ log_debug(const char *format, ...)
va_end(ap);
}
+
#endif
1
0