tor-commits
Threads by month
- ----- 2025 -----
- 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
April 2011
- 18 participants
- 883 discussions
commit 5200697b9074178b48083925a7df4f25cc4757ff
Author: George Kadianakis <desnacked(a)gmail.com>
Date: Thu Mar 17 21:44:43 2011 +0100
reviving unittests
---
src/plugins/obfs2.c | 2 +
src/protocol.c | 3 +-
src/test/unittest.c | 2 +-
src/test/unittest_protocol.c | 262 ++++++++++++++++++++----------------------
4 files changed, 131 insertions(+), 138 deletions(-)
diff --git a/src/plugins/obfs2.c b/src/plugins/obfs2.c
index 90a8528..c0cdc1e 100644
--- a/src/plugins/obfs2.c
+++ b/src/plugins/obfs2.c
@@ -158,6 +158,8 @@ obfs2_send_initial_message(obfs2_state_t *state, struct evbuffer *buf)
plength %= OBFUSCATE_MAX_PADDING;
send_plength = htonl(plength);
+ printf("death and dest\n");
+
if (state->we_are_initiator)
seed = state->initiator_seed;
else
diff --git a/src/protocol.c b/src/protocol.c
index 9fda4b0..6530fe0 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -19,12 +19,13 @@ set_up_protocol(int protocol) {
if (protocol == BRL_PROTOCOL) {
proto->new = &obfs2_new;
proto->new(proto);
- printf("Protocol constructed\n");
if (initialize_crypto() < 0) {
fprintf(stderr, "Can't initialize crypto; failing\n");
return NULL;
}
+
+ printf("Protocol constructed\n");
}
/* elif { other protocols } */
diff --git a/src/test/unittest.c b/src/test/unittest.c
index c9c6e17..4e1368c 100644
--- a/src/test/unittest.c
+++ b/src/test/unittest.c
@@ -15,7 +15,7 @@ extern struct testcase_t socks_tests[];
struct testgroup_t groups[] = {
{ "crypt/", crypt_tests },
- /* { "proto/", protocol_tests }, */
+ { "proto/", protocol_tests },
{ "socks/", socks_tests },
END_OF_GROUPS
};
diff --git a/src/test/unittest_protocol.c b/src/test/unittest_protocol.c
index 69dff6f..334591c 100644
--- a/src/test/unittest_protocol.c
+++ b/src/test/unittest_protocol.c
@@ -1,4 +1,3 @@
-#if 0
/* Copyright 2011 Nick Mathewson
You may do anything with this work that copyright law would normally
@@ -20,22 +19,31 @@
#define CRYPT_PRIVATE
#include "../crypt.h"
#include "../util.h"
-#include "../crypt_protocol.h"
+#include "../protocol.h"
+#include "../plugins/obfs2.h"
/* Make sure we can successfully set up a protocol state */
static void
test_proto_setup(void *data)
{
- protocol_state_t *proto1, *proto2;
- proto1 = protocol_state_new(1);
- proto2 = protocol_state_new(0);
- tt_assert(proto1);
- tt_assert(proto2);
+ struct protocol_t *client_proto = set_up_protocol(BRL_PROTOCOL);
+ struct protocol_t *server_proto = set_up_protocol(BRL_PROTOCOL);
+
+ int initiator = 1;
+ int no_initiator = 0;
+ client_proto->state = proto_init(client_proto, &initiator);
+ server_proto->state = proto_init(server_proto, &no_initiator);
+
+ tt_assert(client_proto);
+ tt_assert(server_proto);
+ tt_assert(client_proto->state);
+ tt_assert(server_proto->state);
+
end:
- if (proto1)
- protocol_state_free(proto1);
- if (proto2)
- protocol_state_free(proto2);
+ if (client_proto->state)
+ proto_destroy(client_proto);
+ if (server_proto->state)
+ proto_destroy(server_proto);
}
@@ -47,24 +55,33 @@ test_proto_handshake(void *data)
output_buffer = evbuffer_new();
dummy_buffer = evbuffer_new();
- protocol_state_t *client_state, *server_state;
- client_state = protocol_state_new(1);
- server_state = protocol_state_new(0);
- tt_assert(client_state);
- tt_assert(server_state);
+ struct protocol_t *client_proto = set_up_protocol(BRL_PROTOCOL);
+ struct protocol_t *server_proto = set_up_protocol(BRL_PROTOCOL);
+
+ int initiator = 1;
+ int no_initiator = 0;
+ client_proto->state = proto_init(client_proto, &initiator);
+ server_proto->state = proto_init(server_proto, &no_initiator);
+ tt_assert(client_proto);
+ tt_assert(server_proto);
+ tt_assert(client_proto->state);
+ tt_assert(server_proto->state);
+
+ obfs2_state_t *client_state = client_proto->state;
+ obfs2_state_t *server_state = server_proto->state;
/* We create a client handshake message and pass it to output_buffer */
- tt_int_op(0, <=, proto_send_initial_message(client_state, output_buffer)<0);
+ tt_int_op(0, <=, proto_handshake(client_proto, output_buffer)<0);
/* We simulate the server receiving and processing the client's handshake message,
by using proto_recv() on the output_buffer */
- tt_int_op(0, <=, proto_recv(server_state, output_buffer, dummy_buffer) <0);
+ tt_int_op(0, <=, proto_recv(server_proto, output_buffer, dummy_buffer) <0);
/* Now, we create the server's handshake and pass it to output_buffer */
- tt_int_op(0, <=, proto_send_initial_message(server_state, output_buffer)<0);
+ tt_int_op(0, <=, proto_handshake(server_proto, output_buffer)<0);
/* We simulate the client receiving and processing the server's handshake */
- tt_int_op(0, <=, proto_recv(client_state, output_buffer, dummy_buffer) <0);
+ tt_int_op(0, <=, proto_recv(client_proto, output_buffer, dummy_buffer) <0);
/* The handshake is now complete. We should have:
client's send_crypto == server's recv_crypto
@@ -78,10 +95,10 @@ test_proto_handshake(void *data)
sizeof(crypt_t)));
end:
- if (client_state)
- protocol_state_free(client_state);
- if (server_state)
- protocol_state_free(server_state);
+ if (client_proto->state)
+ proto_destroy(client_proto);
+ if (server_proto->state)
+ proto_destroy(server_proto);
if (output_buffer)
evbuffer_free(output_buffer);
@@ -97,20 +114,26 @@ test_proto_transfer(void *data)
output_buffer = evbuffer_new();
dummy_buffer = evbuffer_new();
- protocol_state_t *client_state, *server_state;
- client_state = protocol_state_new(1);
- server_state = protocol_state_new(0);
- tt_assert(client_state);
- tt_assert(server_state);
+ struct protocol_t *client_proto = set_up_protocol(BRL_PROTOCOL);
+ struct protocol_t *server_proto = set_up_protocol(BRL_PROTOCOL);
+
+ int initiator = 1;
+ int no_initiator = 0;
+ client_proto->state = proto_init(client_proto, &initiator);
+ server_proto->state = proto_init(server_proto, &no_initiator);
+ tt_assert(client_proto);
+ tt_assert(server_proto);
+ tt_assert(client_proto->state);
+ tt_assert(server_proto->state);
int n;
struct evbuffer_iovec v[2];
/* Handshake */
- tt_int_op(0, <=, proto_send_initial_message(client_state, output_buffer)<0);
- tt_int_op(0, <=, proto_recv(server_state, output_buffer, dummy_buffer) <0);
- tt_int_op(0, <=, proto_send_initial_message(server_state, output_buffer)<0);
- tt_int_op(0, <=, proto_recv(client_state, output_buffer, dummy_buffer) <0);
+ tt_int_op(0, <=, proto_handshake(client_proto, output_buffer)<0);
+ tt_int_op(0, <=, proto_recv(server_proto, output_buffer, dummy_buffer) <0);
+ tt_int_op(0, <=, proto_handshake(server_proto, output_buffer)<0);
+ tt_int_op(0, <=, proto_recv(client_proto, output_buffer, dummy_buffer) <0);
/* End of Handshake */
/* Now let's pass some data around. */
@@ -119,9 +142,9 @@ test_proto_transfer(void *data)
/* client -> server */
evbuffer_add(dummy_buffer, msg1, 54);
- proto_send(client_state, dummy_buffer, output_buffer);
+ proto_send(client_proto, dummy_buffer, output_buffer);
- tt_int_op(0, <=, proto_recv(server_state, output_buffer, dummy_buffer));
+ tt_int_op(0, <=, proto_recv(server_proto, output_buffer, dummy_buffer));
n = evbuffer_peek(dummy_buffer, -1, NULL, &v[0], 2);
@@ -134,18 +157,18 @@ test_proto_transfer(void *data)
/* client <- server */
evbuffer_add(dummy_buffer, msg2, 55);
- tt_int_op(0, <=, proto_send(server_state, dummy_buffer, output_buffer));
+ tt_int_op(0, <=, proto_send(server_proto, dummy_buffer, output_buffer));
- tt_int_op(0, <=, proto_recv(client_state, output_buffer, dummy_buffer));
+ tt_int_op(0, <=, 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));
end:
- if (client_state)
- protocol_state_free(client_state);
- if (server_state)
- protocol_state_free(server_state);
+ if (client_proto->state)
+ proto_destroy(client_proto);
+ if (server_proto->state)
+ proto_destroy(server_proto);
if (output_buffer)
evbuffer_free(output_buffer);
@@ -166,17 +189,28 @@ test_proto_transfer(void *data)
static void
test_proto_splitted_handshake(void *data)
{
+ obfs2_state_t *client_state = NULL;
+ obfs2_state_t *server_state = NULL;
+
struct evbuffer *output_buffer = NULL;
struct evbuffer *dummy_buffer = NULL;
output_buffer = evbuffer_new();
dummy_buffer = evbuffer_new();
- protocol_state_t *client_state;
- protocol_state_t *server_state;
- client_state = protocol_state_new(1);
- server_state = protocol_state_new(0);
- tt_assert(client_state);
- tt_assert(server_state);
+ struct protocol_t *client_proto = set_up_protocol(BRL_PROTOCOL);
+ struct protocol_t *server_proto = set_up_protocol(BRL_PROTOCOL);
+
+ int initiator = 1;
+ int no_initiator = 0;
+ client_proto->state = proto_init(client_proto, &initiator);
+ server_proto->state = proto_init(server_proto, &no_initiator);
+ tt_assert(client_proto);
+ tt_assert(server_proto);
+ tt_assert(client_proto->state);
+ tt_assert(server_proto->state);
+
+ client_state = client_proto->state;
+ server_state = server_proto->state;
uint32_t magic = htonl(OBFUSCATE_MAGIC_VALUE);
uint32_t plength1, plength1_msg1, plength1_msg2, send_plength1;
@@ -208,7 +242,7 @@ test_proto_splitted_handshake(void *data)
evbuffer_add(output_buffer, msgclient_1, OBFUSCATE_SEED_LENGTH+8+plength1_msg1);
/* Server receives handshake part 1 */
- tt_int_op(0, <=, proto_recv(server_state, output_buffer, dummy_buffer));
+ tt_int_op(0, <=, proto_recv(server_proto, output_buffer, dummy_buffer));
tt_assert(server_state->state == ST_WAIT_FOR_PADDING);
@@ -220,7 +254,7 @@ test_proto_splitted_handshake(void *data)
evbuffer_add(output_buffer, msgclient_2, plength1_msg2);
/* Server receives handshake part 2 */
- tt_int_op(0, <=, proto_recv(server_state, output_buffer, dummy_buffer));
+ tt_int_op(0, <=, proto_recv(server_proto, output_buffer, dummy_buffer));
tt_assert(server_state->state == ST_OPEN);
@@ -249,7 +283,7 @@ test_proto_splitted_handshake(void *data)
evbuffer_add(output_buffer, msgserver_1, OBFUSCATE_SEED_LENGTH+8);
/* Client receives handshake part 1 */
- tt_int_op(0, <=, proto_recv(client_state, output_buffer, dummy_buffer));
+ tt_int_op(0, <=, proto_recv(client_proto, output_buffer, dummy_buffer));
tt_assert(client_state->state == ST_WAIT_FOR_PADDING);
@@ -261,7 +295,7 @@ test_proto_splitted_handshake(void *data)
evbuffer_add(output_buffer, msgserver_2, plength2);
/* Client receives handshake part 2 */
- tt_int_op(0, <=, proto_recv(client_state, output_buffer, dummy_buffer));
+ tt_int_op(0, <=, proto_recv(client_proto, output_buffer, dummy_buffer));
tt_assert(client_state->state == ST_OPEN);
@@ -278,9 +312,9 @@ test_proto_splitted_handshake(void *data)
end:
if (client_state)
- protocol_state_free(client_state);
+ proto_destroy(client_proto);
if (server_state)
- protocol_state_free(server_state);
+ proto_destroy(server_proto);
if (output_buffer)
evbuffer_free(output_buffer);
@@ -295,17 +329,28 @@ test_proto_splitted_handshake(void *data)
static void
test_proto_wrong_handshake_magic(void *data)
{
+ obfs2_state_t *client_state = NULL;
+ obfs2_state_t *server_state = NULL;
+
struct evbuffer *output_buffer = NULL;
struct evbuffer *dummy_buffer = NULL;
output_buffer = evbuffer_new();
dummy_buffer = evbuffer_new();
- protocol_state_t *client_state;
- protocol_state_t *server_state;
- client_state = protocol_state_new(1);
- server_state = protocol_state_new(0);
- tt_assert(client_state);
- tt_assert(server_state);
+ struct protocol_t *client_proto = set_up_protocol(BRL_PROTOCOL);
+ struct protocol_t *server_proto = set_up_protocol(BRL_PROTOCOL);
+
+ int initiator = 1;
+ int no_initiator = 0;
+ client_proto->state = proto_init(client_proto, &initiator);
+ server_proto->state = proto_init(server_proto, &no_initiator);
+ tt_assert(client_proto);
+ tt_assert(server_proto);
+ tt_assert(client_proto->state);
+ tt_assert(server_proto->state);
+
+ client_state = client_proto->state;
+ server_state = server_proto->state;
uint32_t wrong_magic = 0xD15EA5E;
@@ -328,84 +373,21 @@ test_proto_wrong_handshake_magic(void *data)
evbuffer_add(output_buffer, msg, OBFUSCATE_SEED_LENGTH+8+plength);
- tt_int_op(-1, ==, proto_recv(server_state, output_buffer, dummy_buffer));
-
- tt_assert(server_state->state == ST_WAIT_FOR_KEY);
-
- end:
- if (client_state)
- protocol_state_free(client_state);
- if (server_state)
- protocol_state_free(server_state);
-
- if (output_buffer)
- evbuffer_free(output_buffer);
- if (dummy_buffer)
- evbuffer_free(dummy_buffer);
-}
-
-#if 0
-/*
- Erroneous handshake test:
- Normal plength field but actual padding larger than
- OBFUSCATE_MAX_PADDING.
-
- XXXX This won't actually fail. If we send extra padding, it gets treated as
- part of the message. Decrypting it will give odd results, but this protocol
- doesn't actually get you integrity.
-*/
-static void
-test_proto_wrong_handshake_padding(void *data)
-{
- struct evbuffer *output_buffer = NULL;
- struct evbuffer *dummy_buffer = NULL;
- output_buffer = evbuffer_new();
- dummy_buffer = evbuffer_new();
-
- protocol_state_t *client_state;
- protocol_state_t *server_state;
- client_state = protocol_state_new(1);
- server_state = protocol_state_new(0);
- tt_assert(client_state);
- tt_assert(server_state);
-
- uchar bigmsg[OBFUSCATE_MAX_PADDING + 1 + OBFUSCATE_SEED_LENGTH + 8];
- uint32_t actual_plength, fake_plength, send_plength;
-
- const uchar *seed;
- seed = client_state->initiator_seed;
- uint32_t magic = htonl(OBFUSCATE_MAGIC_VALUE);
-
- actual_plength = OBFUSCATE_MAX_PADDING + 1U;
- fake_plength = 666U;
- send_plength = htonl(fake_plength);
-
- memcpy(bigmsg, seed, OBFUSCATE_SEED_LENGTH);
- memcpy(bigmsg+OBFUSCATE_SEED_LENGTH, &magic, 4);
- memcpy(bigmsg+OBFUSCATE_SEED_LENGTH+4, &send_plength, 4);
- tt_int_op(0, >=, random_bytes(bigmsg+OBFUSCATE_SEED_LENGTH+8, actual_plength));
-
- stream_crypt(client_state->send_padding_crypto,
- bigmsg+OBFUSCATE_SEED_LENGTH, 8+actual_plength);
-
- evbuffer_add(output_buffer, bigmsg, OBFUSCATE_SEED_LENGTH+8+actual_plength);
-
- tt_int_op(-1, ==, proto_recv(server_state, output_buffer, dummy_buffer));
+ tt_int_op(-1, ==, proto_recv(server_proto, output_buffer, dummy_buffer));
tt_assert(server_state->state == ST_WAIT_FOR_KEY);
end:
if (client_state)
- protocol_state_free(client_state);
+ proto_destroy(client_proto);
if (server_state)
- protocol_state_free(server_state);
+ proto_destroy(server_proto);
if (output_buffer)
evbuffer_free(output_buffer);
if (dummy_buffer)
evbuffer_free(dummy_buffer);
}
-#endif
/* Erroneous handshake test:
plength field larger than OBFUSCATE_MAX_PADDING
@@ -413,17 +395,26 @@ test_proto_wrong_handshake_padding(void *data)
static void
test_proto_wrong_handshake_plength(void *data)
{
+ obfs2_state_t *client_state = NULL;
+ obfs2_state_t *server_state = NULL;
struct evbuffer *output_buffer = NULL;
struct evbuffer *dummy_buffer = NULL;
output_buffer = evbuffer_new();
dummy_buffer = evbuffer_new();
-
- protocol_state_t *client_state;
- protocol_state_t *server_state;
- client_state = protocol_state_new(1);
- server_state = protocol_state_new(0);
- tt_assert(client_state);
- tt_assert(server_state);
+
+ struct protocol_t *client_proto = set_up_protocol(BRL_PROTOCOL);
+ struct protocol_t *server_proto = set_up_protocol(BRL_PROTOCOL);
+ int initiator = 1;
+ int no_initiator = 0;
+ client_proto->state = proto_init(client_proto, &initiator);
+ server_proto->state = proto_init(server_proto, &no_initiator);
+ tt_assert(client_proto);
+ tt_assert(server_proto);
+ tt_assert(client_proto->state);
+ tt_assert(server_proto->state);
+
+ client_state = client_proto->state;
+ server_state = server_proto->state;
uchar msg[OBFUSCATE_MAX_PADDING + OBFUSCATE_SEED_LENGTH + 8 + 1];
uint32_t magic = htonl(OBFUSCATE_MAGIC_VALUE);
@@ -444,15 +435,15 @@ test_proto_wrong_handshake_plength(void *data)
evbuffer_add(output_buffer, msg, OBFUSCATE_SEED_LENGTH+8+plength);
- tt_int_op(-1, ==, proto_recv(server_state, output_buffer, dummy_buffer));
+ tt_int_op(-1, ==, proto_recv(server_proto, output_buffer, dummy_buffer));
tt_assert(server_state->state == ST_WAIT_FOR_KEY);
end:
if (client_state)
- protocol_state_free(client_state);
+ proto_destroy(client_proto);
if (server_state)
- protocol_state_free(server_state);
+ proto_destroy(server_proto);
if (output_buffer)
evbuffer_free(output_buffer);
@@ -476,4 +467,3 @@ struct testcase_t protocol_tests[] = {
T(wrong_handshake_plength, 0),
END_OF_TESTCASES
};
-#endif
1
0

[obfsproxy/master] * Renamed the OpenSSH obfuscation variant plugin to "obfs2" and moved
by nickm@torproject.org 27 Apr '11
by nickm@torproject.org 27 Apr '11
27 Apr '11
commit bff0015cb6aef8cde564c2b3d51f3a9019b25533
Author: George Kadianakis <desnacked(a)gmail.com>
Date: Thu Mar 17 16:09:19 2011 +0100
* Renamed the OpenSSH obfuscation variant plugin to "obfs2" and moved
it to the right place.
* Renamed module.{c,h} to protocol.{c,h}.
* Moved the protocol state inside protocol_t.
---
Makefile.am | 14 +-
src/crypt_protocol.c | 359 ---------------------------------------------
src/crypt_protocol.h | 88 -----------
src/main.c | 2 +-
src/module.c | 31 ----
src/module.h | 29 ----
src/network.c | 24 ++--
src/network.h | 5 +-
src/plugins/obfs2.c | 359 +++++++++++++++++++++++++++++++++++++++++++++
src/plugins/obfs2.h | 88 +++++++++++
src/protocol.c | 31 ++++
src/protocol.h | 32 ++++
src/test/unittest_socks.c | 2 +-
13 files changed, 533 insertions(+), 531 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 430fd13..9376df3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,12 +9,11 @@ noinst_PROGRAMS = unittests
libobfsproxy_a_SOURCES = \
src/crypt.c \
- src/crypt_protocol.c \
- src/module.c \
src/network.c \
+ src/protocol.c \
src/socks.c \
- src/util.c
-
+ src/util.c \
+ src/plugins/obfs2.c
obfsproxy_SOURCES = \
src/main.c
@@ -29,15 +28,14 @@ unittests_SOURCES = \
unittests_LDADD = @libevent_LIBS@ @openssl_LIBS@ libobfsproxy.a
noinst_HEADERS = \
- src/crypt_protocol.h \
src/crypt.h \
- src/module.h \
src/network.h \
+ src/protocol.h \
src/socks.h \
src/util.h \
src/test/tinytest.h \
- src/test/tinytest_macros.h
-
+ src/test/tinytest_macros.h \
+ src/plugins/obfs2.h
EXTRA_DIST = doc/protocol-spec.txt src/sha256.c
diff --git a/autogen.sh b/autogen.sh
old mode 100644
new mode 100755
diff --git a/src/crypt_protocol.c b/src/crypt_protocol.c
deleted file mode 100644
index ce81a33..0000000
--- a/src/crypt_protocol.c
+++ /dev/null
@@ -1,359 +0,0 @@
-/* Copyright 2011 Nick Mathewson
-
- You may do anything with this work that copyright law would normally
- restrict, so long as you retain the above notice(s) and this license
- in all redistributed copies and derived works. There is no warranty.
-*/
-
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <openssl/rand.h>
-#include <event2/buffer.h>
-
-#define CRYPT_PROTOCOL_PRIVATE
-
-#include "crypt.h"
-#include "crypt_protocol.h"
-#include "util.h"
-#include "module.h"
-
-void *
-new_brl(struct protocol_t *proto_struct) {
- proto_struct->destroy = (void *)brl_state_free;
- proto_struct->init = (void *)brl_state_new;
- proto_struct->handshake = (void *)brl_send_initial_message;
- proto_struct->send = (void *)brl_send;
- proto_struct->recv = (void *)brl_recv;
-
- return NULL;
-}
-
-/** Return true iff the OBFUSCATE_SEED_LENGTH-byte seed in 'seed' is nonzero */
-static int
-seed_nonzero(const uchar *seed)
-{
- return memcmp(seed, OBFUSCATE_ZERO_SEED, OBFUSCATE_SEED_LENGTH) != 0;
-}
-
-/**
- Derive and return key of type 'keytype' from the seeds currently set in
- 'state'. Returns NULL on failure.
- */
-static crypt_t *
-derive_key(brl_state_t *state, const char *keytype)
-{
- crypt_t *cryptstate;
- uchar buf[32];
- digest_t *c = digest_new();
- digest_update(c, (uchar*)keytype, strlen(keytype));
- if (seed_nonzero(state->initiator_seed))
- digest_update(c, state->initiator_seed, OBFUSCATE_SEED_LENGTH);
- if (seed_nonzero(state->responder_seed))
- digest_update(c, state->responder_seed, OBFUSCATE_SEED_LENGTH);
- if (seed_nonzero(state->secret_seed))
- digest_update(c, state->secret_seed, SHARED_SECRET_LENGTH);
- digest_update(c, (uchar*)keytype, strlen(keytype));
- digest_getdigest(c, buf, sizeof(buf));
- cryptstate = crypt_new(buf, 16);
- crypt_set_iv(cryptstate, buf+16, 16);
- memset(buf, 0, sizeof(buf));
- digest_free(c);
- return cryptstate;
-}
-
-static crypt_t *
-derive_padding_key(brl_state_t *state, const uchar *seed,
- const char *keytype)
-{
- crypt_t *cryptstate;
- uchar buf[32];
- digest_t *c = digest_new();
- digest_update(c, (uchar*)keytype, strlen(keytype));
- if (seed_nonzero(seed))
- digest_update(c, seed, OBFUSCATE_SEED_LENGTH);
- if (seed_nonzero(state->secret_seed))
- digest_update(c, state->secret_seed, OBFUSCATE_SEED_LENGTH);
- digest_update(c, (uchar*)keytype, strlen(keytype));
- digest_getdigest(c, buf, sizeof(buf));
- cryptstate = crypt_new(buf, 16);
- crypt_set_iv(cryptstate, buf+16, 16);
- memset(buf, 0, 16);
- digest_free(c);
- return cryptstate;
-}
-
-/**
- Return a new object to handle protocol state. If 'initiator' is true,
- we're the handshake initiator. Otherwise, we're the responder. Return
- NULL on failure.
- */
-brl_state_t *
-brl_state_new(int *initiator)
-{
- brl_state_t *state = calloc(1, sizeof(brl_state_t));
- uchar *seed;
- const char *send_pad_type;
-
- if (!state)
- return NULL;
- state->state = ST_WAIT_FOR_KEY;
- state->we_are_initiator = *initiator;
- if (*initiator) {
- send_pad_type = INITIATOR_PAD_TYPE;
- seed = state->initiator_seed;
- } else {
- send_pad_type = RESPONDER_PAD_TYPE;
- seed = state->responder_seed;
- }
-
- /* Generate our seed */
- if (random_bytes(seed, OBFUSCATE_SEED_LENGTH) < 0) {
- free(state);
- return NULL;
- }
-
- /* Derive the key for what we're sending */
- state->send_padding_crypto = derive_padding_key(state, seed, send_pad_type);
- if (state->send_padding_crypto == NULL) {
- free(state);
- return NULL;
- }
-
- return state;
-}
-
-/** Set the shared secret to be used with this protocol state. */
-void
-brl_state_set_shared_secret(brl_state_t *state,
- const char *secret, size_t secretlen)
-{
- if (secretlen > SHARED_SECRET_LENGTH)
- secretlen = SHARED_SECRET_LENGTH;
- memcpy(state->secret_seed, secret, secretlen);
-}
-
-/**
- Write the initial protocol setup and padding message for 'state' to
- the evbuffer 'buf'. Return 0 on success, -1 on failure.
- */
-int
-brl_send_initial_message(brl_state_t *state, struct evbuffer *buf)
-{
- uint32_t magic = htonl(OBFUSCATE_MAGIC_VALUE), plength, send_plength;
- uchar msg[OBFUSCATE_MAX_PADDING + OBFUSCATE_SEED_LENGTH + 8];
- const uchar *seed;
-
- /* We're going to send:
- SEED | E_PAD_KEY( UINT32(MAGIC_VALUE) | UINT32(PADLEN) | WR(PADLEN) )
- */
-
- assert(sizeof(magic) == 4);
-
- /* generate padlen */
- if (random_bytes((uchar*)&plength, 4) < 0)
- return -1;
- plength %= OBFUSCATE_MAX_PADDING;
- send_plength = htonl(plength);
-
- if (state->we_are_initiator)
- seed = state->initiator_seed;
- else
- seed = state->responder_seed;
-
- /* Marshal the message, but with no parts encrypted */
- memcpy(msg, seed, OBFUSCATE_SEED_LENGTH);
- memcpy(msg+OBFUSCATE_SEED_LENGTH, &magic, 4);
- memcpy(msg+OBFUSCATE_SEED_LENGTH+4, &send_plength, 4);
- if (random_bytes(msg+OBFUSCATE_SEED_LENGTH+8, plength) < 0)
- return -1;
-
- /* Encrypt it */
- stream_crypt(state->send_padding_crypto,
- msg+OBFUSCATE_SEED_LENGTH, 8+plength);
-
- /* Put it on the buffer */
- evbuffer_add(buf, msg, OBFUSCATE_SEED_LENGTH+8+plength);
- return 0;
-}
-
-/**
- Helper: encrypt every byte from 'source' using the key in 'crypto',
- and write those bytes onto 'dest'. Return 0 on success, -1 on failure.
- */
-static int
-crypt_and_transmit(crypt_t *crypto,
- struct evbuffer *source, struct evbuffer *dest)
-{
- uchar data[1024];
- while (1) {
- int n = evbuffer_remove(source, data, 1024);
- if (n <= 0)
- return 0;
- stream_crypt(crypto, data, n);
- // printf("Message is: %s", data);
- evbuffer_add(dest, data, n);
- dbg(("Processed %d bytes.", n));
- }
-}
-
-/**
- Called when data arrives from the user side and we want to send the
- obfuscated version. Copies and obfuscates data from 'source' into 'dest'
- using the state in 'state'. Returns 0 on success, -1 on failure.
- */
-int
-brl_send(brl_state_t *state,
- struct evbuffer *source, struct evbuffer *dest)
-{
- if (state->send_crypto) {
- /* Our crypto is set up; just relay the bytes */
- return crypt_and_transmit(state->send_crypto, source, dest);
- } else {
- /* Our crypto isn't set up yet, we'll have to queue the data */
- if (evbuffer_get_length(source)) {
- if (! state->pending_data_to_send) {
- state->pending_data_to_send = evbuffer_new();
- }
- evbuffer_add_buffer(state->pending_data_to_send, source);
- }
- return 0;
- }
-}
-
-/**
- Helper: called after reciving our partner's setup message. Initializes all
- keys. Returns 0 on success, -1 on failure.
- */
-static int
-init_crypto(brl_state_t *state)
-{
- const char *send_keytype;
- const char *recv_keytype;
- const char *recv_pad_keytype;
- const uchar *recv_seed;
-
- if (state->we_are_initiator) {
- send_keytype = INITIATOR_SEND_TYPE;
- recv_keytype = RESPONDER_SEND_TYPE;
- recv_pad_keytype = RESPONDER_PAD_TYPE;
- recv_seed = state->responder_seed;
- } else {
- send_keytype = RESPONDER_SEND_TYPE;
- recv_keytype = INITIATOR_SEND_TYPE;
- recv_pad_keytype = INITIATOR_PAD_TYPE;
- recv_seed = state->initiator_seed;
- }
-
- /* Derive all of the keys that depend on our partner's seed */
- state->send_crypto = derive_key(state, send_keytype);
- state->recv_crypto = derive_key(state, recv_keytype);
- state->recv_padding_crypto =
- derive_padding_key(state, recv_seed, recv_pad_keytype);
-
- if (state->send_crypto && state->recv_crypto && state->recv_padding_crypto)
- return 0;
- else
- return -1;
-}
-
-/* Called when we receive data in an evbuffer 'source': deobfuscates that data
- * and writes it to 'dest'.
- *
- * Returns x for "don't call again till you have x bytes". 0 for "all ok". -1
- * for "fail, close" */
-int
-brl_recv(brl_state_t *state, struct evbuffer *source,
- struct evbuffer *dest)
-{
- if (state->state == ST_WAIT_FOR_KEY) {
- /* We're waiting for the first OBFUSCATE_SEED_LENGTH+8 bytes to show up
- * so we can learn the partner's seed and padding length */
- uchar buf[OBFUSCATE_SEED_LENGTH+8], *other_seed;
- uint32_t magic, plength;
- if (evbuffer_get_length(source) < OBFUSCATE_SEED_LENGTH+8) {
- /* data not here yet */
- return OBFUSCATE_SEED_LENGTH+8;
- }
- evbuffer_remove(source, buf, OBFUSCATE_SEED_LENGTH+8);
-
- if (state->we_are_initiator)
- other_seed = state->responder_seed;
- else
- other_seed = state->initiator_seed;
-
- memcpy(other_seed, buf, OBFUSCATE_SEED_LENGTH);
-
- /* Now we can set up all the keys from the seed */
- if (init_crypto(state) < 0)
- return -1;
-
- /* Decrypt the next 8 bytes */
- stream_crypt(state->recv_padding_crypto, buf+OBFUSCATE_SEED_LENGTH, 8);
- /* Check the magic number and extract the padding length */
- memcpy(&magic, buf+OBFUSCATE_SEED_LENGTH, 4);
- memcpy(&plength, buf+OBFUSCATE_SEED_LENGTH+4, 4);
- magic = ntohl(magic);
- plength = ntohl(plength);
- if (magic != OBFUSCATE_MAGIC_VALUE)
- return -1;
- if (plength > OBFUSCATE_MAX_PADDING)
- return -1;
-
- /* Send any data that we've been waiting to send */
- if (state->pending_data_to_send) {
- crypt_and_transmit(state->send_crypto, state->pending_data_to_send, dest);
- evbuffer_free(state->pending_data_to_send);
- state->pending_data_to_send = NULL;
- }
-
- /* Now we're waiting for plength bytes of padding */
- state->padding_left_to_read = plength;
- state->state = ST_WAIT_FOR_PADDING;
-
- /* Fall through here: if there is padding data waiting on the buffer, pull
- it off immediately. */
- dbg(("Received key, expecting %d bytes of padding\n", plength));
- }
-
- /* If we're still looking for padding, start pulling off bytes and
- discarding them. */
- while (state->padding_left_to_read) {
- int n = state->padding_left_to_read;
- size_t sourcelen = evbuffer_get_length(source);
- if (!sourcelen)
- return n;
- if ((size_t) n > evbuffer_get_length(source))
- n = evbuffer_get_length(source);
- evbuffer_drain(source, n);
- state->padding_left_to_read -= n;
- dbg(("Received %d bytes of padding; %d left to read\n", n,
- state->padding_left_to_read));
- }
-
- /* Okay; now we're definitely open. Process whatever data we have. */
- state->state = ST_OPEN;
-
- dbg(("Processing %d bytes data onto destination buffer\n",
- (int) evbuffer_get_length(source)));
- return crypt_and_transmit(state->recv_crypto, source, dest);
-}
-
-void
-brl_state_free(brl_state_t *s)
-{
- if (s->send_crypto)
- crypt_free(s->send_crypto);
- if (s->send_padding_crypto)
- crypt_free(s->send_padding_crypto);
- if (s->recv_crypto)
- crypt_free(s->recv_crypto);
- if (s->recv_padding_crypto)
- crypt_free(s->recv_padding_crypto);
- if (s->pending_data_to_send)
- evbuffer_free(s->pending_data_to_send);
- memset(s, 0x0a, sizeof(brl_state_t));
- free(s);
-}
diff --git a/src/crypt_protocol.h b/src/crypt_protocol.h
deleted file mode 100644
index e6e76d2..0000000
--- a/src/crypt_protocol.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* Copyright 2011 Nick Mathewson
-
- You may do anything with this work that copyright law would normally
- restrict, so long as you retain the above notice(s) and this license
- in all redistributed copies and derived works. There is no warranty.
-*/
-
-#ifndef CRYPT_PROTOCOL_H
-#define CRYPT_PROTOCOL_H
-
-#include <sys/types.h>
-
-typedef struct brl_state_t brl_state_t;
-struct evbuffer;
-struct protocol_t;
-
-#define SHARED_SECRET_LENGTH 16
-
-brl_state_t *brl_state_new(int *initiator);
-void brl_state_set_shared_secret(brl_state_t *state,
- const char *secret, size_t secretlen);
-void brl_state_free(brl_state_t *state);
-int brl_send_initial_message(brl_state_t *state, struct evbuffer *buf);
-int brl_send(brl_state_t *state,
- struct evbuffer *source, struct evbuffer *dest);
-int brl_recv(brl_state_t *state, struct evbuffer *source,
- struct evbuffer *dest);
-
-void *new_brl(struct protocol_t *proto_struct);
-
-
-#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.
- ==========
-*/
-/* from brl's obfuscated-ssh standard. */
-//#define OBFUSCATE_MAGIC_VALUE 0x0BF5CA7E
-
-/* our own, since we break brl's spec */
-#define OBFUSCATE_MAGIC_VALUE 0x2BF5CA7E
-#define OBFUSCATE_SEED_LENGTH 16
-#define OBFUSCATE_MAX_PADDING 8192
-#define OBFUSCATE_ZERO_SEED "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
-
-#define INITIATOR_PAD_TYPE "Initiator obfuscation padding"
-#define RESPONDER_PAD_TYPE "Responder obfuscation padding"
-#define INITIATOR_SEND_TYPE "Initiator obfuscated data"
-#define RESPONDER_SEND_TYPE "Responder obfuscated data"
-
-struct brl_state_t {
- /** Current protocol state. We start out waiting for key information. Then
- we have a key and wait for padding to arrive. Finally, we are sending
- and receiving bytes on the connection.
- */
- enum {
- ST_WAIT_FOR_KEY,
- ST_WAIT_FOR_PADDING,
- ST_OPEN,
- } state;
- /** Random seed we generated for this stream */
- uchar initiator_seed[OBFUSCATE_SEED_LENGTH];
- /** Random seed the other side generated for this stream */
- uchar responder_seed[OBFUSCATE_SEED_LENGTH];
- /** Shared secret seed value. */
- uchar secret_seed[SHARED_SECRET_LENGTH];
- /** True iff we opened this connection */
- int we_are_initiator;
-
- /** key used to encrypt outgoing data */
- crypt_t *send_crypto;
- /** key used to encrypt outgoing padding */
- crypt_t *send_padding_crypto;
- /** key used to decrypt incoming data */
- crypt_t *recv_crypto;
- /** key used to decrypt incoming padding */
- crypt_t *recv_padding_crypto;
-
- /** Buffer full of data we'll send once the handshake is done. */
- struct evbuffer *pending_data_to_send;
-
- /** Number of padding bytes to read before we get to real data */
- int padding_left_to_read;
-};
-#endif
-
-#endif
diff --git a/src/main.c b/src/main.c
index 94e8442..de5cd61 100644
--- a/src/main.c
+++ b/src/main.c
@@ -14,7 +14,7 @@
#include "crypt.h"
#include "network.h"
#include "util.h"
-#include "module.h"
+#include "protocol.h"
#ifndef __GNUC__
#define __attribute__(x)
diff --git a/src/module.c b/src/module.c
deleted file mode 100644
index 51f91ac..0000000
--- a/src/module.c
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "stdlib.h"
-#include "stdio.h"
-
-#include "module.h"
-#include "crypt_protocol.h"
-#include "crypt.h"
-#include "network.h"
-
-/**
- This function returns a protocol_t structure based on the mode
- of obfsproxy
-*/
-struct protocol_t *
-set_up_module(int protocol) {
- struct protocol_t *proto = calloc(1, sizeof(struct protocol_t));
-
- if (protocol == BRL_PROTOCOL) {
- proto->new = &new_brl;
- proto->new(proto);
- printf("Protocol constructed\n");
-
- if (initialize_crypto() < 0) {
- fprintf(stderr, "Can't initialize crypto; failing\n");
- return NULL;
- }
- }
- /* elif { other protocols } */
-
- return proto;
-}
-
diff --git a/src/module.h b/src/module.h
deleted file mode 100644
index 8302acf..0000000
--- a/src/module.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef MODULE_H
-#define MODULE_H
-
-/* ASN I'm gonna be calling crypt_protocol.c BRL_RPOTOCOL for now. Yes. */
-#define BRL_PROTOCOL 1
-
-struct protocol_t *set_up_module(int protocol);
-
-/* ASN */
-struct protocol_t {
- /* Constructor: creates the protocol; sets up functions etc. */
- void *(*new)(struct protocol_t *self);
- /* Destructor */
- void (*destroy)(void *arg);
-
- /* does nessesary initiation steps; like build a proto state etc. */
- void *(*init)(void *arg);
-
- /* does handshake. Supposedly all modules have a handshake. */
- void *(*handshake)(void *state, void *buf);
- /* send data function */
- int (*send)(void *state, void *source,
- void *dest);
- /* receive data function */
- int (*recv)(void *state, void *source,
- void *dest);
-};
-
-#endif
diff --git a/src/network.c b/src/network.c
index 882d352..b6dadd7 100644
--- a/src/network.c
+++ b/src/network.c
@@ -6,11 +6,10 @@
*/
#define NETWORK_PRIVATE
-#include "crypt_protocol.h"
#include "network.h"
#include "util.h"
#include "socks.h"
-#include "module.h"
+#include "protocol.h"
#include <assert.h>
#include <stdlib.h>
@@ -24,6 +23,8 @@
#include <errno.h>
#include <event2/util.h>
+#include "plugins/obfs2.h"
+
struct listener_t {
struct evconnlistener *listener;
struct sockaddr_storage target_address;
@@ -62,9 +63,9 @@ listener_new(struct event_base *base,
assert(mode == LSN_SIMPLE_CLIENT || mode == LSN_SIMPLE_SERVER ||
mode == LSN_SOCKS_CLIENT);
- struct protocol_t *proto = set_up_module(protocol);
+ struct protocol_t *proto = set_up_protocol(protocol);
if (!proto) {
- printf("This is just terrible. We can't even set up a module!Seppuku time!\n");
+ printf("This is just terrible. We can't even set up a protocol! Seppuku time!\n");
exit(-1);
}
@@ -124,9 +125,9 @@ simple_listener_cb(struct evconnlistener *evcl,
/* ASN Is this actually modular. Will all protocols need to init here?
I don't think so. I don't know. */
int is_initiator = (conn->mode != LSN_SIMPLE_SERVER) ? 1 : 0;
- conn->proto_state = lsn->proto->init(&is_initiator);
+ conn->proto->state = lsn->proto->init(&is_initiator);
- if (!conn->proto_state)
+ if (!conn->proto->state)
goto err;
if (conn->mode == LSN_SOCKS_CLIENT) {
@@ -176,8 +177,9 @@ simple_listener_cb(struct evconnlistener *evcl,
/* Queue output right now. */
struct bufferevent *encrypted =
conn->mode == LSN_SIMPLE_SERVER ? conn->input : conn->output;
+
/* ASN Send handshake */
- if (lsn->proto->handshake(conn->proto_state,
+ if (lsn->proto->handshake(conn->proto->state,
bufferevent_get_output(encrypted))<0)
goto err;
@@ -202,8 +204,8 @@ simple_listener_cb(struct evconnlistener *evcl,
static void
conn_free(conn_t *conn)
{
- if (conn->proto_state)
- conn->proto->destroy((void *)conn->proto_state);
+ if (conn->proto->state)
+ conn->proto->destroy((void *)conn->proto->state);
if (conn->socks_state)
socks_state_free(conn->socks_state);
if (conn->input)
@@ -278,7 +280,7 @@ plaintext_read_cb(struct bufferevent *bev, void *arg)
other = (bev == conn->input) ? conn->output : conn->input;
dbg(("Got data on plaintext side\n"));
- if (conn->proto->send(conn->proto_state,
+ if (conn->proto->send(conn->proto->state,
bufferevent_get_input(bev),
bufferevent_get_output(other)) < 0)
conn_free(conn);
@@ -292,7 +294,7 @@ obfsucated_read_cb(struct bufferevent *bev, void *arg)
other = (bev == conn->input) ? conn->output : conn->input;
dbg(("Got data on encrypted side\n"));
- if (conn->proto->recv(conn->proto_state,
+ if (conn->proto->recv(conn->proto->state,
bufferevent_get_input(bev),
bufferevent_get_output(other)) < 0)
conn_free(conn);
diff --git a/src/network.h b/src/network.h
index 048f80c..619e45f 100644
--- a/src/network.h
+++ b/src/network.h
@@ -8,13 +8,14 @@
#ifndef NETWORK_H
#define NETWORK_H
+#include <stdlib.h>
+
typedef struct listener_t *listener;
struct sockaddr;
struct event_base;
struct socks_state_t;
-
#define LSN_SIMPLE_CLIENT 1
#define LSN_SIMPLE_SERVER 2
#define LSN_SOCKS_CLIENT 3
@@ -33,8 +34,6 @@ void listener_free(listener_t *listener);
#ifdef NETWORK_PRIVATE
typedef struct conn_t {
struct socks_state_t *socks_state;
- void *proto_state; /* ASN Is this correct?
- Supposedly, it represents a generic proto state. */
struct protocol_t *proto; /* ASN Do we like this here? We probably don't.
But it's so convenient!! So convenient! */
int mode;
diff --git a/src/plugins/obfs2.c b/src/plugins/obfs2.c
new file mode 100644
index 0000000..90a8528
--- /dev/null
+++ b/src/plugins/obfs2.c
@@ -0,0 +1,359 @@
+/* Copyright 2011 Nick Mathewson
+
+ You may do anything with this work that copyright law would normally
+ restrict, so long as you retain the above notice(s) and this license
+ in all redistributed copies and derived works. There is no warranty.
+*/
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <openssl/rand.h>
+#include <event2/buffer.h>
+
+#define CRYPT_PROTOCOL_PRIVATE
+
+#include "../crypt.h"
+#include "obfs2.h"
+#include "../util.h"
+#include "../protocol.h"
+
+void *
+obfs2_new(struct protocol_t *proto_struct) {
+ proto_struct->destroy = (void *)obfs2_state_free;
+ proto_struct->init = (void *)obfs2_state_new;
+ proto_struct->handshake = (void *)obfs2_send_initial_message;
+ proto_struct->send = (void *)obfs2_send;
+ proto_struct->recv = (void *)obfs2_recv;
+
+ return NULL;
+}
+
+/** Return true iff the OBFUSCATE_SEED_LENGTH-byte seed in 'seed' is nonzero */
+static int
+seed_nonzero(const uchar *seed)
+{
+ return memcmp(seed, OBFUSCATE_ZERO_SEED, OBFUSCATE_SEED_LENGTH) != 0;
+}
+
+/**
+ Derive and return key of type 'keytype' from the seeds currently set in
+ 'state'. Returns NULL on failure.
+ */
+static crypt_t *
+derive_key(obfs2_state_t *state, const char *keytype)
+{
+ crypt_t *cryptstate;
+ uchar buf[32];
+ digest_t *c = digest_new();
+ digest_update(c, (uchar*)keytype, strlen(keytype));
+ if (seed_nonzero(state->initiator_seed))
+ digest_update(c, state->initiator_seed, OBFUSCATE_SEED_LENGTH);
+ if (seed_nonzero(state->responder_seed))
+ digest_update(c, state->responder_seed, OBFUSCATE_SEED_LENGTH);
+ if (seed_nonzero(state->secret_seed))
+ digest_update(c, state->secret_seed, SHARED_SECRET_LENGTH);
+ digest_update(c, (uchar*)keytype, strlen(keytype));
+ digest_getdigest(c, buf, sizeof(buf));
+ cryptstate = crypt_new(buf, 16);
+ crypt_set_iv(cryptstate, buf+16, 16);
+ memset(buf, 0, sizeof(buf));
+ digest_free(c);
+ return cryptstate;
+}
+
+static crypt_t *
+derive_padding_key(obfs2_state_t *state, const uchar *seed,
+ const char *keytype)
+{
+ crypt_t *cryptstate;
+ uchar buf[32];
+ digest_t *c = digest_new();
+ digest_update(c, (uchar*)keytype, strlen(keytype));
+ if (seed_nonzero(seed))
+ digest_update(c, seed, OBFUSCATE_SEED_LENGTH);
+ if (seed_nonzero(state->secret_seed))
+ digest_update(c, state->secret_seed, OBFUSCATE_SEED_LENGTH);
+ digest_update(c, (uchar*)keytype, strlen(keytype));
+ digest_getdigest(c, buf, sizeof(buf));
+ cryptstate = crypt_new(buf, 16);
+ crypt_set_iv(cryptstate, buf+16, 16);
+ memset(buf, 0, 16);
+ digest_free(c);
+ return cryptstate;
+}
+
+/**
+ Return a new object to handle protocol state. If 'initiator' is true,
+ we're the handshake initiator. Otherwise, we're the responder. Return
+ NULL on failure.
+ */
+obfs2_state_t *
+obfs2_state_new(int *initiator)
+{
+ obfs2_state_t *state = calloc(1, sizeof(obfs2_state_t));
+ uchar *seed;
+ const char *send_pad_type;
+
+ if (!state)
+ return NULL;
+ state->state = ST_WAIT_FOR_KEY;
+ state->we_are_initiator = *initiator;
+ if (*initiator) {
+ send_pad_type = INITIATOR_PAD_TYPE;
+ seed = state->initiator_seed;
+ } else {
+ send_pad_type = RESPONDER_PAD_TYPE;
+ seed = state->responder_seed;
+ }
+
+ /* Generate our seed */
+ if (random_bytes(seed, OBFUSCATE_SEED_LENGTH) < 0) {
+ free(state);
+ return NULL;
+ }
+
+ /* Derive the key for what we're sending */
+ state->send_padding_crypto = derive_padding_key(state, seed, send_pad_type);
+ if (state->send_padding_crypto == NULL) {
+ free(state);
+ return NULL;
+ }
+
+ return state;
+}
+
+/** Set the shared secret to be used with this protocol state. */
+void
+obfs2_state_set_shared_secret(obfs2_state_t *state,
+ const char *secret, size_t secretlen)
+{
+ if (secretlen > SHARED_SECRET_LENGTH)
+ secretlen = SHARED_SECRET_LENGTH;
+ memcpy(state->secret_seed, secret, secretlen);
+}
+
+/**
+ Write the initial protocol setup and padding message for 'state' to
+ the evbuffer 'buf'. Return 0 on success, -1 on failure.
+ */
+int
+obfs2_send_initial_message(obfs2_state_t *state, struct evbuffer *buf)
+{
+ uint32_t magic = htonl(OBFUSCATE_MAGIC_VALUE), plength, send_plength;
+ uchar msg[OBFUSCATE_MAX_PADDING + OBFUSCATE_SEED_LENGTH + 8];
+ const uchar *seed;
+
+ /* We're going to send:
+ SEED | E_PAD_KEY( UINT32(MAGIC_VALUE) | UINT32(PADLEN) | WR(PADLEN) )
+ */
+
+ assert(sizeof(magic) == 4);
+
+ /* generate padlen */
+ if (random_bytes((uchar*)&plength, 4) < 0)
+ return -1;
+ plength %= OBFUSCATE_MAX_PADDING;
+ send_plength = htonl(plength);
+
+ if (state->we_are_initiator)
+ seed = state->initiator_seed;
+ else
+ seed = state->responder_seed;
+
+ /* Marshal the message, but with no parts encrypted */
+ memcpy(msg, seed, OBFUSCATE_SEED_LENGTH);
+ memcpy(msg+OBFUSCATE_SEED_LENGTH, &magic, 4);
+ memcpy(msg+OBFUSCATE_SEED_LENGTH+4, &send_plength, 4);
+ if (random_bytes(msg+OBFUSCATE_SEED_LENGTH+8, plength) < 0)
+ return -1;
+
+ /* Encrypt it */
+ stream_crypt(state->send_padding_crypto,
+ msg+OBFUSCATE_SEED_LENGTH, 8+plength);
+
+ /* Put it on the buffer */
+ evbuffer_add(buf, msg, OBFUSCATE_SEED_LENGTH+8+plength);
+ return 0;
+}
+
+/**
+ Helper: encrypt every byte from 'source' using the key in 'crypto',
+ and write those bytes onto 'dest'. Return 0 on success, -1 on failure.
+ */
+static int
+crypt_and_transmit(crypt_t *crypto,
+ struct evbuffer *source, struct evbuffer *dest)
+{
+ uchar data[1024];
+ while (1) {
+ int n = evbuffer_remove(source, data, 1024);
+ if (n <= 0)
+ return 0;
+ stream_crypt(crypto, data, n);
+ // printf("Message is: %s", data);
+ evbuffer_add(dest, data, n);
+ dbg(("Processed %d bytes.", n));
+ }
+}
+
+/**
+ Called when data arrives from the user side and we want to send the
+ obfuscated version. Copies and obfuscates data from 'source' into 'dest'
+ using the state in 'state'. Returns 0 on success, -1 on failure.
+ */
+int
+obfs2_send(obfs2_state_t *state,
+ struct evbuffer *source, struct evbuffer *dest)
+{
+ if (state->send_crypto) {
+ /* Our crypto is set up; just relay the bytes */
+ return crypt_and_transmit(state->send_crypto, source, dest);
+ } else {
+ /* Our crypto isn't set up yet, we'll have to queue the data */
+ if (evbuffer_get_length(source)) {
+ if (! state->pending_data_to_send) {
+ state->pending_data_to_send = evbuffer_new();
+ }
+ evbuffer_add_buffer(state->pending_data_to_send, source);
+ }
+ return 0;
+ }
+}
+
+/**
+ Helper: called after reciving our partner's setup message. Initializes all
+ keys. Returns 0 on success, -1 on failure.
+ */
+static int
+init_crypto(obfs2_state_t *state)
+{
+ const char *send_keytype;
+ const char *recv_keytype;
+ const char *recv_pad_keytype;
+ const uchar *recv_seed;
+
+ if (state->we_are_initiator) {
+ send_keytype = INITIATOR_SEND_TYPE;
+ recv_keytype = RESPONDER_SEND_TYPE;
+ recv_pad_keytype = RESPONDER_PAD_TYPE;
+ recv_seed = state->responder_seed;
+ } else {
+ send_keytype = RESPONDER_SEND_TYPE;
+ recv_keytype = INITIATOR_SEND_TYPE;
+ recv_pad_keytype = INITIATOR_PAD_TYPE;
+ recv_seed = state->initiator_seed;
+ }
+
+ /* Derive all of the keys that depend on our partner's seed */
+ state->send_crypto = derive_key(state, send_keytype);
+ state->recv_crypto = derive_key(state, recv_keytype);
+ state->recv_padding_crypto =
+ derive_padding_key(state, recv_seed, recv_pad_keytype);
+
+ if (state->send_crypto && state->recv_crypto && state->recv_padding_crypto)
+ return 0;
+ else
+ return -1;
+}
+
+/* Called when we receive data in an evbuffer 'source': deobfuscates that data
+ * and writes it to 'dest'.
+ *
+ * Returns x for "don't call again till you have x bytes". 0 for "all ok". -1
+ * for "fail, close" */
+int
+obfs2_recv(obfs2_state_t *state, struct evbuffer *source,
+ struct evbuffer *dest)
+{
+ if (state->state == ST_WAIT_FOR_KEY) {
+ /* We're waiting for the first OBFUSCATE_SEED_LENGTH+8 bytes to show up
+ * so we can learn the partner's seed and padding length */
+ uchar buf[OBFUSCATE_SEED_LENGTH+8], *other_seed;
+ uint32_t magic, plength;
+ if (evbuffer_get_length(source) < OBFUSCATE_SEED_LENGTH+8) {
+ /* data not here yet */
+ return OBFUSCATE_SEED_LENGTH+8;
+ }
+ evbuffer_remove(source, buf, OBFUSCATE_SEED_LENGTH+8);
+
+ if (state->we_are_initiator)
+ other_seed = state->responder_seed;
+ else
+ other_seed = state->initiator_seed;
+
+ memcpy(other_seed, buf, OBFUSCATE_SEED_LENGTH);
+
+ /* Now we can set up all the keys from the seed */
+ if (init_crypto(state) < 0)
+ return -1;
+
+ /* Decrypt the next 8 bytes */
+ stream_crypt(state->recv_padding_crypto, buf+OBFUSCATE_SEED_LENGTH, 8);
+ /* Check the magic number and extract the padding length */
+ memcpy(&magic, buf+OBFUSCATE_SEED_LENGTH, 4);
+ memcpy(&plength, buf+OBFUSCATE_SEED_LENGTH+4, 4);
+ magic = ntohl(magic);
+ plength = ntohl(plength);
+ if (magic != OBFUSCATE_MAGIC_VALUE)
+ return -1;
+ if (plength > OBFUSCATE_MAX_PADDING)
+ return -1;
+
+ /* Send any data that we've been waiting to send */
+ if (state->pending_data_to_send) {
+ crypt_and_transmit(state->send_crypto, state->pending_data_to_send, dest);
+ evbuffer_free(state->pending_data_to_send);
+ state->pending_data_to_send = NULL;
+ }
+
+ /* Now we're waiting for plength bytes of padding */
+ state->padding_left_to_read = plength;
+ state->state = ST_WAIT_FOR_PADDING;
+
+ /* Fall through here: if there is padding data waiting on the buffer, pull
+ it off immediately. */
+ dbg(("Received key, expecting %d bytes of padding\n", plength));
+ }
+
+ /* If we're still looking for padding, start pulling off bytes and
+ discarding them. */
+ while (state->padding_left_to_read) {
+ int n = state->padding_left_to_read;
+ size_t sourcelen = evbuffer_get_length(source);
+ if (!sourcelen)
+ return n;
+ if ((size_t) n > evbuffer_get_length(source))
+ n = evbuffer_get_length(source);
+ evbuffer_drain(source, n);
+ state->padding_left_to_read -= n;
+ dbg(("Received %d bytes of padding; %d left to read\n", n,
+ state->padding_left_to_read));
+ }
+
+ /* Okay; now we're definitely open. Process whatever data we have. */
+ state->state = ST_OPEN;
+
+ dbg(("Processing %d bytes data onto destination buffer\n",
+ (int) evbuffer_get_length(source)));
+ return crypt_and_transmit(state->recv_crypto, source, dest);
+}
+
+void
+obfs2_state_free(obfs2_state_t *s)
+{
+ if (s->send_crypto)
+ crypt_free(s->send_crypto);
+ if (s->send_padding_crypto)
+ crypt_free(s->send_padding_crypto);
+ if (s->recv_crypto)
+ crypt_free(s->recv_crypto);
+ if (s->recv_padding_crypto)
+ crypt_free(s->recv_padding_crypto);
+ if (s->pending_data_to_send)
+ evbuffer_free(s->pending_data_to_send);
+ memset(s, 0x0a, sizeof(obfs2_state_t));
+ free(s);
+}
diff --git a/src/plugins/obfs2.h b/src/plugins/obfs2.h
new file mode 100644
index 0000000..dd0c842
--- /dev/null
+++ b/src/plugins/obfs2.h
@@ -0,0 +1,88 @@
+/* Copyright 2011 Nick Mathewson
+
+ You may do anything with this work that copyright law would normally
+ restrict, so long as you retain the above notice(s) and this license
+ in all redistributed copies and derived works. There is no warranty.
+*/
+
+#ifndef OBFS2_H
+#define OBFS2_H
+
+#include <sys/types.h>
+
+typedef struct obfs2_state_t obfs2_state_t;
+struct evbuffer;
+struct protocol_t;
+
+#define SHARED_SECRET_LENGTH 16
+
+obfs2_state_t *obfs2_state_new(int *initiator);
+void obfs2_state_set_shared_secret(obfs2_state_t *state,
+ const char *secret, size_t secretlen);
+void obfs2_state_free(obfs2_state_t *state);
+int obfs2_send_initial_message(obfs2_state_t *state, struct evbuffer *buf);
+int obfs2_send(obfs2_state_t *state,
+ struct evbuffer *source, struct evbuffer *dest);
+int obfs2_recv(obfs2_state_t *state, struct evbuffer *source,
+ struct evbuffer *dest);
+
+void *obfs2_new(struct protocol_t *proto_struct);
+
+
+#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.
+ ==========
+*/
+/* from brl's obfuscated-ssh standard. */
+//#define OBFUSCATE_MAGIC_VALUE 0x0BF5CA7E
+
+/* our own, since we break brl's spec */
+#define OBFUSCATE_MAGIC_VALUE 0x2BF5CA7E
+#define OBFUSCATE_SEED_LENGTH 16
+#define OBFUSCATE_MAX_PADDING 8192
+#define OBFUSCATE_ZERO_SEED "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+
+#define INITIATOR_PAD_TYPE "Initiator obfuscation padding"
+#define RESPONDER_PAD_TYPE "Responder obfuscation padding"
+#define INITIATOR_SEND_TYPE "Initiator obfuscated data"
+#define RESPONDER_SEND_TYPE "Responder obfuscated data"
+
+struct obfs2_state_t {
+ /** Current protocol state. We start out waiting for key information. Then
+ we have a key and wait for padding to arrive. Finally, we are sending
+ and receiving bytes on the connection.
+ */
+ enum {
+ ST_WAIT_FOR_KEY,
+ ST_WAIT_FOR_PADDING,
+ ST_OPEN,
+ } state;
+ /** Random seed we generated for this stream */
+ uchar initiator_seed[OBFUSCATE_SEED_LENGTH];
+ /** Random seed the other side generated for this stream */
+ uchar responder_seed[OBFUSCATE_SEED_LENGTH];
+ /** Shared secret seed value. */
+ uchar secret_seed[SHARED_SECRET_LENGTH];
+ /** True iff we opened this connection */
+ int we_are_initiator;
+
+ /** key used to encrypt outgoing data */
+ crypt_t *send_crypto;
+ /** key used to encrypt outgoing padding */
+ crypt_t *send_padding_crypto;
+ /** key used to decrypt incoming data */
+ crypt_t *recv_crypto;
+ /** key used to decrypt incoming padding */
+ crypt_t *recv_padding_crypto;
+
+ /** Buffer full of data we'll send once the handshake is done. */
+ struct evbuffer *pending_data_to_send;
+
+ /** Number of padding bytes to read before we get to real data */
+ int padding_left_to_read;
+};
+#endif
+
+#endif
diff --git a/src/protocol.c b/src/protocol.c
new file mode 100644
index 0000000..c186857
--- /dev/null
+++ b/src/protocol.c
@@ -0,0 +1,31 @@
+#include "stdlib.h"
+#include "stdio.h"
+
+#include "protocol.h"
+#include "crypt.h"
+#include "network.h"
+
+#include "plugins/obfs2.h"
+
+/**
+ This function returns a protocol_t structure based on the mode
+ of obfsproxy
+*/
+struct protocol_t *
+set_up_protocol(int protocol) {
+ struct protocol_t *proto = calloc(1, sizeof(struct protocol_t));
+
+ if (protocol == BRL_PROTOCOL) {
+ proto->new = &obfs2_new;
+ proto->new(proto);
+ printf("Protocol constructed\n");
+
+ if (initialize_crypto() < 0) {
+ fprintf(stderr, "Can't initialize crypto; failing\n");
+ return NULL;
+ }
+ }
+ /* elif { other protocols } */
+
+ return proto;
+}
diff --git a/src/protocol.h b/src/protocol.h
new file mode 100644
index 0000000..159f3e3
--- /dev/null
+++ b/src/protocol.h
@@ -0,0 +1,32 @@
+#ifndef PROTOCOL_H
+#define PROTOCOL_H
+
+/* ASN I'm gonna be calling crypt_protocol.c BRL_RPOTOCOL for now. Yes. */
+#define BRL_PROTOCOL 1
+
+struct protocol_t *set_up_protocol(int protocol);
+
+/* ASN */
+struct protocol_t {
+ /* Constructor: creates the protocol; sets up functions etc. */
+ void *(*new)(struct protocol_t *self);
+ /* Destructor */
+ void (*destroy)(void *arg);
+
+ /* does nessesary initiation steps; like build a proto state etc. */
+ void *(*init)(void *arg);
+
+ /* does handshake. Supposedly all protocols have a handshake. */
+ void *(*handshake)(void *state, void *buf);
+ /* send data function */
+ int (*send)(void *state, void *source,
+ void *dest);
+ /* receive data function */
+ int (*recv)(void *state, void *source,
+ void *dest);
+
+ /* ASN do we need a proto_get_state()? */
+ void *state;
+};
+
+#endif
diff --git a/src/test/unittest_socks.c b/src/test/unittest_socks.c
index 2b4e38a..ec24e5f 100644
--- a/src/test/unittest_socks.c
+++ b/src/test/unittest_socks.c
@@ -11,7 +11,7 @@
#include "../socks.h"
#include "../crypt.h"
#include "../util.h"
-#include "../crypt_protocol.h"
+#include "../plugins/obfs2.h"
static void
test_socks_send_negotiation(void *data)
1
0

[obfsproxy/master] This commit attempts to abstract the whole obfsproxy thing.
by nickm@torproject.org 27 Apr '11
by nickm@torproject.org 27 Apr '11
27 Apr '11
commit 6575674cda96198692d610d90512ee939e2fc733
Author: George Kadianakis <desnacked(a)gmail.com>
Date: Thu Feb 24 17:21:19 2011 +0100
This commit attempts to abstract the whole obfsproxy thing.
This is an ugly commit.
What happened?
* Changed function names of crypt_protocol.c to brl_* instead of proto_*.
* Introduced a generic protocol_t struct with some operations that can be
considered generic. It's function pointer design practically works, but shouldn't
be quite right. I suck in C OO design.
* crypt_protocol.c module initializes it's protocol_t structure with new_brl().
* A module.c:set_up_module() was introduced that is called from network.c and
initializes the obfsproxy based on the active module.
* Changed a couple of names in network.c, as well.
* Disabled appropriate unit tests.
Of course everything is just a dirty little PoC and is to be changed, but like I
said I had some innocent fun.
Enjoy.
---
Makefile.am | 4 ++-
src/crypt_protocol.c | 42 ++++++++++++++++++++++------------
src/crypt_protocol.h | 19 +++++++++------
src/main.c | 10 ++------
src/module.c | 31 ++++++++++++++++++++++++++
src/module.h | 29 ++++++++++++++++++++++++
src/network.c | 50 ++++++++++++++++++++++++++++++-----------
src/network.h | 9 +++++--
src/test/unittest.c | 2 +-
src/test/unittest_protocol.c | 2 +
10 files changed, 149 insertions(+), 49 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 7b1bac6..430fd13 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4
-CFLAGS = -g -Wall -O2 -Werror @libevent_CFLAGS@ @openssl_CFLAGS@
+CFLAGS = -DDEBUG -g -Wall -O2 -Werror @libevent_CFLAGS@ @openssl_CFLAGS@
bin_PROGRAMS = obfsproxy
@@ -10,6 +10,7 @@ noinst_PROGRAMS = unittests
libobfsproxy_a_SOURCES = \
src/crypt.c \
src/crypt_protocol.c \
+ src/module.c \
src/network.c \
src/socks.c \
src/util.c
@@ -30,6 +31,7 @@ unittests_LDADD = @libevent_LIBS@ @openssl_LIBS@ libobfsproxy.a
noinst_HEADERS = \
src/crypt_protocol.h \
src/crypt.h \
+ src/module.h \
src/network.h \
src/socks.h \
src/util.h \
diff --git a/src/crypt_protocol.c b/src/crypt_protocol.c
index f499fbe..ce81a33 100644
--- a/src/crypt_protocol.c
+++ b/src/crypt_protocol.c
@@ -18,6 +18,18 @@
#include "crypt.h"
#include "crypt_protocol.h"
#include "util.h"
+#include "module.h"
+
+void *
+new_brl(struct protocol_t *proto_struct) {
+ proto_struct->destroy = (void *)brl_state_free;
+ proto_struct->init = (void *)brl_state_new;
+ proto_struct->handshake = (void *)brl_send_initial_message;
+ proto_struct->send = (void *)brl_send;
+ proto_struct->recv = (void *)brl_recv;
+
+ return NULL;
+}
/** Return true iff the OBFUSCATE_SEED_LENGTH-byte seed in 'seed' is nonzero */
static int
@@ -31,7 +43,7 @@ seed_nonzero(const uchar *seed)
'state'. Returns NULL on failure.
*/
static crypt_t *
-derive_key(protocol_state_t *state, const char *keytype)
+derive_key(brl_state_t *state, const char *keytype)
{
crypt_t *cryptstate;
uchar buf[32];
@@ -53,7 +65,7 @@ derive_key(protocol_state_t *state, const char *keytype)
}
static crypt_t *
-derive_padding_key(protocol_state_t *state, const uchar *seed,
+derive_padding_key(brl_state_t *state, const uchar *seed,
const char *keytype)
{
crypt_t *cryptstate;
@@ -78,18 +90,18 @@ derive_padding_key(protocol_state_t *state, const uchar *seed,
we're the handshake initiator. Otherwise, we're the responder. Return
NULL on failure.
*/
-protocol_state_t *
-protocol_state_new(int initiator)
+brl_state_t *
+brl_state_new(int *initiator)
{
- protocol_state_t *state = calloc(1, sizeof(protocol_state_t));
+ brl_state_t *state = calloc(1, sizeof(brl_state_t));
uchar *seed;
const char *send_pad_type;
if (!state)
return NULL;
state->state = ST_WAIT_FOR_KEY;
- state->we_are_initiator = initiator;
- if (initiator) {
+ state->we_are_initiator = *initiator;
+ if (*initiator) {
send_pad_type = INITIATOR_PAD_TYPE;
seed = state->initiator_seed;
} else {
@@ -115,7 +127,7 @@ protocol_state_new(int initiator)
/** Set the shared secret to be used with this protocol state. */
void
-protocol_state_set_shared_secret(protocol_state_t *state,
+brl_state_set_shared_secret(brl_state_t *state,
const char *secret, size_t secretlen)
{
if (secretlen > SHARED_SECRET_LENGTH)
@@ -128,7 +140,7 @@ protocol_state_set_shared_secret(protocol_state_t *state,
the evbuffer 'buf'. Return 0 on success, -1 on failure.
*/
int
-proto_send_initial_message(protocol_state_t *state, struct evbuffer *buf)
+brl_send_initial_message(brl_state_t *state, struct evbuffer *buf)
{
uint32_t magic = htonl(OBFUSCATE_MAGIC_VALUE), plength, send_plength;
uchar msg[OBFUSCATE_MAX_PADDING + OBFUSCATE_SEED_LENGTH + 8];
@@ -193,8 +205,8 @@ crypt_and_transmit(crypt_t *crypto,
using the state in 'state'. Returns 0 on success, -1 on failure.
*/
int
-proto_send(protocol_state_t *state,
- struct evbuffer *source, struct evbuffer *dest)
+brl_send(brl_state_t *state,
+ struct evbuffer *source, struct evbuffer *dest)
{
if (state->send_crypto) {
/* Our crypto is set up; just relay the bytes */
@@ -216,7 +228,7 @@ proto_send(protocol_state_t *state,
keys. Returns 0 on success, -1 on failure.
*/
static int
-init_crypto(protocol_state_t *state)
+init_crypto(brl_state_t *state)
{
const char *send_keytype;
const char *recv_keytype;
@@ -253,7 +265,7 @@ init_crypto(protocol_state_t *state)
* Returns x for "don't call again till you have x bytes". 0 for "all ok". -1
* for "fail, close" */
int
-proto_recv(protocol_state_t *state, struct evbuffer *source,
+brl_recv(brl_state_t *state, struct evbuffer *source,
struct evbuffer *dest)
{
if (state->state == ST_WAIT_FOR_KEY) {
@@ -330,7 +342,7 @@ proto_recv(protocol_state_t *state, struct evbuffer *source,
}
void
-protocol_state_free(protocol_state_t *s)
+brl_state_free(brl_state_t *s)
{
if (s->send_crypto)
crypt_free(s->send_crypto);
@@ -342,6 +354,6 @@ protocol_state_free(protocol_state_t *s)
crypt_free(s->recv_padding_crypto);
if (s->pending_data_to_send)
evbuffer_free(s->pending_data_to_send);
- memset(s, 0x0a, sizeof(protocol_state_t));
+ memset(s, 0x0a, sizeof(brl_state_t));
free(s);
}
diff --git a/src/crypt_protocol.h b/src/crypt_protocol.h
index b8694d3..e6e76d2 100644
--- a/src/crypt_protocol.h
+++ b/src/crypt_protocol.h
@@ -10,21 +10,24 @@
#include <sys/types.h>
-typedef struct protocol_state_t protocol_state_t;
+typedef struct brl_state_t brl_state_t;
struct evbuffer;
+struct protocol_t;
#define SHARED_SECRET_LENGTH 16
-protocol_state_t *protocol_state_new(int initiator);
-void protocol_state_set_shared_secret(protocol_state_t *state,
+brl_state_t *brl_state_new(int *initiator);
+void brl_state_set_shared_secret(brl_state_t *state,
const char *secret, size_t secretlen);
-void protocol_state_free(protocol_state_t *state);
-int proto_send_initial_message(protocol_state_t *state, struct evbuffer *buf);
-int proto_send(protocol_state_t *state,
+void brl_state_free(brl_state_t *state);
+int brl_send_initial_message(brl_state_t *state, struct evbuffer *buf);
+int brl_send(brl_state_t *state,
struct evbuffer *source, struct evbuffer *dest);
-int proto_recv(protocol_state_t *state, struct evbuffer *source,
+int brl_recv(brl_state_t *state, struct evbuffer *source,
struct evbuffer *dest);
+void *new_brl(struct protocol_t *proto_struct);
+
#ifdef CRYPT_PROTOCOL_PRIVATE
/* ==========
@@ -46,7 +49,7 @@ int proto_recv(protocol_state_t *state, struct evbuffer *source,
#define INITIATOR_SEND_TYPE "Initiator obfuscated data"
#define RESPONDER_SEND_TYPE "Responder obfuscated data"
-struct protocol_state_t {
+struct brl_state_t {
/** Current protocol state. We start out waiting for key information. Then
we have a key and wait for padding to arrive. Finally, we are sending
and receiving bytes on the connection.
diff --git a/src/main.c b/src/main.c
index 07b5bcc..94e8442 100644
--- a/src/main.c
+++ b/src/main.c
@@ -14,6 +14,7 @@
#include "crypt.h"
#include "network.h"
#include "util.h"
+#include "module.h"
#ifndef __GNUC__
#define __attribute__(x)
@@ -92,12 +93,6 @@ main(int argc, const char **argv)
sa_target = (struct sockaddr *)&ss_target;
}
- /* Initialize crypto */
- if (initialize_crypto() < 0) {
- fprintf(stderr, "Can't initialize crypto; failing\n");
- return 2;
- }
-
/* Initialize libevent */
base = event_base_new();
if (base == NULL) {
@@ -115,8 +110,9 @@ main(int argc, const char **argv)
sigevent = evsignal_new(base, SIGINT, handle_signal_cb, (void*) base);
/* start an evconnlistener on the appropriate port(s) */
+ /* ASN We hardcode BRL_PROTOCOL for now. */
listener = listener_new(base,
- mode,
+ mode, BRL_PROTOCOL,
(struct sockaddr *)&ss_listen, sl_listen,
sa_target, sl_target,
NULL, 0);
diff --git a/src/module.c b/src/module.c
new file mode 100644
index 0000000..51f91ac
--- /dev/null
+++ b/src/module.c
@@ -0,0 +1,31 @@
+#include "stdlib.h"
+#include "stdio.h"
+
+#include "module.h"
+#include "crypt_protocol.h"
+#include "crypt.h"
+#include "network.h"
+
+/**
+ This function returns a protocol_t structure based on the mode
+ of obfsproxy
+*/
+struct protocol_t *
+set_up_module(int protocol) {
+ struct protocol_t *proto = calloc(1, sizeof(struct protocol_t));
+
+ if (protocol == BRL_PROTOCOL) {
+ proto->new = &new_brl;
+ proto->new(proto);
+ printf("Protocol constructed\n");
+
+ if (initialize_crypto() < 0) {
+ fprintf(stderr, "Can't initialize crypto; failing\n");
+ return NULL;
+ }
+ }
+ /* elif { other protocols } */
+
+ return proto;
+}
+
diff --git a/src/module.h b/src/module.h
new file mode 100644
index 0000000..8302acf
--- /dev/null
+++ b/src/module.h
@@ -0,0 +1,29 @@
+#ifndef MODULE_H
+#define MODULE_H
+
+/* ASN I'm gonna be calling crypt_protocol.c BRL_RPOTOCOL for now. Yes. */
+#define BRL_PROTOCOL 1
+
+struct protocol_t *set_up_module(int protocol);
+
+/* ASN */
+struct protocol_t {
+ /* Constructor: creates the protocol; sets up functions etc. */
+ void *(*new)(struct protocol_t *self);
+ /* Destructor */
+ void (*destroy)(void *arg);
+
+ /* does nessesary initiation steps; like build a proto state etc. */
+ void *(*init)(void *arg);
+
+ /* does handshake. Supposedly all modules have a handshake. */
+ void *(*handshake)(void *state, void *buf);
+ /* send data function */
+ int (*send)(void *state, void *source,
+ void *dest);
+ /* receive data function */
+ int (*recv)(void *state, void *source,
+ void *dest);
+};
+
+#endif
diff --git a/src/network.c b/src/network.c
index 3ac45cf..882d352 100644
--- a/src/network.c
+++ b/src/network.c
@@ -10,6 +10,7 @@
#include "network.h"
#include "util.h"
#include "socks.h"
+#include "module.h"
#include <assert.h>
#include <stdlib.h>
@@ -27,6 +28,7 @@ struct listener_t {
struct evconnlistener *listener;
struct sockaddr_storage target_address;
int target_address_len;
+ struct protocol_t *proto; /* Protocol that this listener can speak. */
int mode;
char shared_secret[SHARED_SECRET_LENGTH];
unsigned int have_shared_secret : 1;
@@ -40,13 +42,15 @@ static void conn_free(conn_t *conn);
static void close_conn_on_flush(struct bufferevent *bev, void *arg);
static void plaintext_read_cb(struct bufferevent *bev, void *arg);
static void socks_read_cb(struct bufferevent *bev, void *arg);
-static void encrypted_read_cb(struct bufferevent *bev, void *arg);
+/* ASN Changed encrypted_read_cb() to obfuscated_read_cb(), it sounds
+ a bit more obfsproxy generic. I still don't like it though. */
+static void obfsucated_read_cb(struct bufferevent *bev, void *arg);
static void input_event_cb(struct bufferevent *bev, short what, void *arg);
static void output_event_cb(struct bufferevent *bev, short what, void *arg);
listener_t *
listener_new(struct event_base *base,
- int mode,
+ int mode, int protocol,
const struct sockaddr *on_address, int on_address_len,
const struct sockaddr *target_address, int target_address_len,
const char *shared_secret, size_t shared_secret_len)
@@ -55,10 +59,18 @@ listener_new(struct event_base *base,
LEV_OPT_CLOSE_ON_FREE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_REUSEABLE;
listener_t *lsn = calloc(1, sizeof(listener_t));
- lsn->mode = mode;
assert(mode == LSN_SIMPLE_CLIENT || mode == LSN_SIMPLE_SERVER ||
mode == LSN_SOCKS_CLIENT);
+ struct protocol_t *proto = set_up_module(protocol);
+ if (!proto) {
+ printf("This is just terrible. We can't even set up a module!Seppuku time!\n");
+ exit(-1);
+ }
+
+ lsn->proto = proto;
+ lsn->mode = mode;
+
if (target_address) {
assert(target_address_len <= sizeof(struct sockaddr_storage));
memcpy(&lsn->target_address, target_address, target_address_len);
@@ -107,7 +119,13 @@ simple_listener_cb(struct evconnlistener *evcl,
dbg(("Got a connection\n"));
conn->mode = lsn->mode;
- conn->proto_state = protocol_state_new(lsn->mode != LSN_SIMPLE_SERVER);
+ conn->proto = lsn->proto;
+
+ /* ASN Is this actually modular. Will all protocols need to init here?
+ I don't think so. I don't know. */
+ int is_initiator = (conn->mode != LSN_SIMPLE_SERVER) ? 1 : 0;
+ conn->proto_state = lsn->proto->init(&is_initiator);
+
if (!conn->proto_state)
goto err;
@@ -129,7 +147,7 @@ simple_listener_cb(struct evconnlistener *evcl,
if (conn->mode == LSN_SIMPLE_SERVER) {
bufferevent_setcb(conn->input,
- encrypted_read_cb, NULL, input_event_cb, conn);
+ obfsucated_read_cb, NULL, input_event_cb, conn);
} else if (conn->mode == LSN_SIMPLE_CLIENT) {
bufferevent_setcb(conn->input,
plaintext_read_cb, NULL, input_event_cb, conn);
@@ -153,13 +171,14 @@ simple_listener_cb(struct evconnlistener *evcl,
plaintext_read_cb, NULL, output_event_cb, conn);
else
bufferevent_setcb(conn->output,
- encrypted_read_cb, NULL, output_event_cb, conn);
+ obfsucated_read_cb, NULL, output_event_cb, conn);
/* Queue output right now. */
struct bufferevent *encrypted =
conn->mode == LSN_SIMPLE_SERVER ? conn->input : conn->output;
- if (proto_send_initial_message(conn->proto_state,
- bufferevent_get_output(encrypted))<0)
+ /* ASN Send handshake */
+ if (lsn->proto->handshake(conn->proto_state,
+ bufferevent_get_output(encrypted))<0)
goto err;
if (conn->mode == LSN_SIMPLE_SERVER || conn->mode == LSN_SIMPLE_CLIENT) {
@@ -184,7 +203,7 @@ static void
conn_free(conn_t *conn)
{
if (conn->proto_state)
- protocol_state_free(conn->proto_state);
+ conn->proto->destroy((void *)conn->proto_state);
if (conn->socks_state)
socks_state_free(conn->socks_state);
if (conn->input)
@@ -259,21 +278,21 @@ plaintext_read_cb(struct bufferevent *bev, void *arg)
other = (bev == conn->input) ? conn->output : conn->input;
dbg(("Got data on plaintext side\n"));
- if (proto_send(conn->proto_state,
+ if (conn->proto->send(conn->proto_state,
bufferevent_get_input(bev),
bufferevent_get_output(other)) < 0)
conn_free(conn);
}
static void
-encrypted_read_cb(struct bufferevent *bev, void *arg)
+obfsucated_read_cb(struct bufferevent *bev, void *arg)
{
conn_t *conn = arg;
struct bufferevent *other;
other = (bev == conn->input) ? conn->output : conn->input;
dbg(("Got data on encrypted side\n"));
- if (proto_recv(conn->proto_state,
+ if (conn->proto->recv(conn->proto_state,
bufferevent_get_input(bev),
bufferevent_get_output(other)) < 0)
conn_free(conn);
@@ -309,6 +328,8 @@ input_event_cb(struct bufferevent *bev, short what, void *arg)
assert(bev == conn->input);
if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
+ printf("Got error: %s\n",
+ evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()));
error_or_eof(conn, bev, conn->output);
}
/* XXX we don't expect any other events */
@@ -321,6 +342,8 @@ output_event_cb(struct bufferevent *bev, short what, void *arg)
assert(bev == conn->output);
if (conn->flushing || (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR))) {
+ printf("Got error: %s\n",
+ evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()));
error_or_eof(conn, bev, conn->input);
return;
}
@@ -341,7 +364,6 @@ output_event_cb(struct bufferevent *bev, short what, void *arg)
}
socks_send_reply(conn->socks_state, bufferevent_get_output(conn->input),
SOCKS5_REP_SUCCESS);
-
/* we sent a socks reply. We can finally move over to being a regular
input bufferevent. */
socks_state_free(conn->socks_state);
@@ -349,7 +371,7 @@ output_event_cb(struct bufferevent *bev, short what, void *arg)
bufferevent_setcb(conn->input,
plaintext_read_cb, NULL, input_event_cb, conn);
if (evbuffer_get_length(bufferevent_get_input(conn->input)) != 0)
- encrypted_read_cb(bev, conn->input);
+ obfsucated_read_cb(bev, conn->input);
}
}
/* XXX we don't expect any other events */
diff --git a/src/network.h b/src/network.h
index 6987bad..048f80c 100644
--- a/src/network.h
+++ b/src/network.h
@@ -13,7 +13,7 @@ typedef struct listener_t *listener;
struct sockaddr;
struct event_base;
struct socks_state_t;
-struct protocol_state_t;
+
#define LSN_SIMPLE_CLIENT 1
#define LSN_SIMPLE_SERVER 2
@@ -24,7 +24,7 @@ struct addrinfo;
listener_t *listener_new(
struct event_base *base,
- int mode,
+ int mode, int protocol,
const struct sockaddr *on_address, int on_address_len,
const struct sockaddr *target_address, int target_address_len,
const char *shared_secret, size_t shared_secret_len);
@@ -33,7 +33,10 @@ void listener_free(listener_t *listener);
#ifdef NETWORK_PRIVATE
typedef struct conn_t {
struct socks_state_t *socks_state;
- struct protocol_state_t *proto_state;
+ void *proto_state; /* ASN Is this correct?
+ Supposedly, it represents a generic proto state. */
+ struct protocol_t *proto; /* ASN Do we like this here? We probably don't.
+ But it's so convenient!! So convenient! */
int mode;
struct bufferevent *input;
struct bufferevent *output;
diff --git a/src/test/unittest.c b/src/test/unittest.c
index 4e1368c..c9c6e17 100644
--- a/src/test/unittest.c
+++ b/src/test/unittest.c
@@ -15,7 +15,7 @@ extern struct testcase_t socks_tests[];
struct testgroup_t groups[] = {
{ "crypt/", crypt_tests },
- { "proto/", protocol_tests },
+ /* { "proto/", protocol_tests }, */
{ "socks/", socks_tests },
END_OF_GROUPS
};
diff --git a/src/test/unittest_protocol.c b/src/test/unittest_protocol.c
index f9bf988..69dff6f 100644
--- a/src/test/unittest_protocol.c
+++ b/src/test/unittest_protocol.c
@@ -1,3 +1,4 @@
+#if 0
/* Copyright 2011 Nick Mathewson
You may do anything with this work that copyright law would normally
@@ -475,3 +476,4 @@ struct testcase_t protocol_tests[] = {
T(wrong_handshake_plength, 0),
END_OF_TESTCASES
};
+#endif
1
0

[tor/master] Expose a new process_signal(uintptr_t), not signal_callback()
by nickm@torproject.org 26 Apr '11
by nickm@torproject.org 26 Apr '11
26 Apr '11
commit f810a1afe990788cd8f944a515a493902df84ed1
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Apr 26 15:20:08 2011 -0400
Expose a new process_signal(uintptr_t), not signal_callback()
This is a tweak to the bug2917 fix. Basically, if we want to simulate
a signal arriving in the controller, we shouldn't have to pretend that
we're Libevent, or depend on how Tor sets up its Libevent callbacks.
---
src/or/control.c | 3 ++-
src/or/main.c | 10 +++++++++-
src/or/main.h | 2 +-
3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/or/control.c b/src/or/control.c
index bb1c330..9f7739a 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -1222,7 +1222,8 @@ handle_control_signal(control_connection_t *conn, uint32_t len,
/* Flush the "done" first if the signal might make us shut down. */
if (sig == SIGTERM || sig == SIGINT)
connection_handle_write(TO_CONN(conn), 1);
- signal_callback(0,0,(void*)(uintptr_t)sig);
+
+ process_signal(sig);
return 0;
}
diff --git a/src/or/main.c b/src/or/main.c
index 5e4d88c..1699568 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1578,12 +1578,20 @@ do_main_loop(void)
/** Libevent callback: invoked when we get a signal.
*/
-void
+static void
signal_callback(int fd, short events, void *arg)
{
uintptr_t sig = (uintptr_t)arg;
(void)fd;
(void)events;
+
+ process_signal(sig);
+}
+
+/** Do the work of acting on a signal received in <b>sig</b> */
+void
+process_signal(uintptr_t sig)
+{
switch (sig)
{
case SIGTERM:
diff --git a/src/or/main.h b/src/or/main.h
index 626bf1c..0551f7a 100644
--- a/src/or/main.h
+++ b/src/or/main.h
@@ -47,7 +47,7 @@ void ip_address_changed(int at_interface);
void dns_servers_relaunch_checks(void);
void handle_signals(int is_parent);
-void signal_callback(int fd, short events, void *arg);
+void process_signal(uintptr_t sig);
int try_locking(or_options_t *options, int err_if_locked);
int have_lockfile(void);
1
0

26 Apr '11
commit 3256627a4548c4977b834cc724689e0e9a960f06
Merge: 33f058a f810a1a
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Apr 26 15:30:51 2011 -0400
Merge remote-tracking branch 'origin/maint-0.2.2'
Conflicts:
src/or/main.h
changes/bug2917 | 4 ++++
src/or/control.c | 4 +++-
src/or/main.c | 49 ++++++++-----------------------------------------
src/or/main.h | 2 +-
src/or/or.h | 2 +-
5 files changed, 17 insertions(+), 44 deletions(-)
diff --cc src/or/main.h
index 67c3bb3,0551f7a..db97cf1
--- a/src/or/main.h
+++ b/src/or/main.h
@@@ -51,10 -46,8 +51,10 @@@ void directory_info_has_arrived(time_t
void ip_address_changed(int at_interface);
void dns_servers_relaunch_checks(void);
+long get_uptime(void);
+
- void control_signal_act(int the_signal);
void handle_signals(int is_parent);
+ void process_signal(uintptr_t sig);
int try_locking(or_options_t *options, int err_if_locked);
int have_lockfile(void);
1
0

[tor/master] Merge remote-tracking branch 'sebastian/bug2917' into maint-0.2.2
by nickm@torproject.org 26 Apr '11
by nickm@torproject.org 26 Apr '11
26 Apr '11
commit a7a906603e0c7e3c8519a948b5adf43bfecf6f66
Merge: b75d1da 5114e3e
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Apr 26 15:17:03 2011 -0400
Merge remote-tracking branch 'sebastian/bug2917' into maint-0.2.2
changes/bug2917 | 4 ++++
src/or/control.c | 3 ++-
src/or/main.c | 43 +------------------------------------------
src/or/main.h | 2 +-
src/or/or.h | 2 +-
5 files changed, 9 insertions(+), 45 deletions(-)
1
0
commit 5114e3e44235ea39447eea37213c65413cdb1a2c
Author: Sebastian Hahn <sebastian(a)torproject.org>
Date: Thu Apr 14 20:04:39 2011 -0700
Make SIGNAL DUMP work on FreeBSD
While doing so, get rid of the now unnecessary function
control_signal_act().
Fixes bug 2917, reported by Robert Ransom. Bugfix on commit
9b4aa8d2abbce71398e58188209a1b1d04885b96. This patch is loosely based on
a patch by Robert (Changelog entry).
---
changes/bug2917 | 4 ++++
src/or/control.c | 3 ++-
src/or/main.c | 43 +------------------------------------------
src/or/main.h | 2 +-
src/or/or.h | 2 +-
5 files changed, 9 insertions(+), 45 deletions(-)
diff --git a/changes/bug2917 b/changes/bug2917
new file mode 100644
index 0000000..6b1e643
--- /dev/null
+++ b/changes/bug2917
@@ -0,0 +1,4 @@
+ o Minor bugfixes
+ - Make the SIGNAL DUMP control-port command work on FreeBSD. Fixes
+ bug 2917. Bugfix on 0.1.1.1-alpha.
+
diff --git a/src/or/control.c b/src/or/control.c
index 8f3af0b..bb1c330 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -1222,7 +1222,8 @@ handle_control_signal(control_connection_t *conn, uint32_t len,
/* Flush the "done" first if the signal might make us shut down. */
if (sig == SIGTERM || sig == SIGINT)
connection_handle_write(TO_CONN(conn), 1);
- control_signal_act(sig);
+ signal_callback(0,0,(void*)(uintptr_t)sig);
+
return 0;
}
diff --git a/src/or/main.c b/src/or/main.c
index 83d1e1e..5e4d88c 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -64,7 +64,6 @@ static void dumpmemusage(int severity);
static void dumpstats(int severity); /* log stats */
static void conn_read_callback(int fd, short event, void *_conn);
static void conn_write_callback(int fd, short event, void *_conn);
-static void signal_callback(int fd, short events, void *arg);
static void second_elapsed_callback(periodic_timer_t *timer, void *args);
static int conn_close_if_marked(int i);
static void connection_start_reading_from_linked_conn(connection_t *conn);
@@ -1577,49 +1576,9 @@ do_main_loop(void)
}
}
-/** Used to implement the SIGNAL control command: if we accept
- * <b>the_signal</b> as a remote pseudo-signal, act on it. */
-/* We don't re-use catch() here because:
- * 1. We handle a different set of signals than those allowed in catch.
- * 2. Platforms without signal() are unlikely to define SIGfoo.
- * 3. The control spec is defined to use fixed numeric signal values
- * which just happen to match the Unix values.
- */
-void
-control_signal_act(int the_signal)
-{
- switch (the_signal)
- {
- case 1:
- signal_callback(0,0,(void*)(uintptr_t)SIGHUP);
- break;
- case 2:
- signal_callback(0,0,(void*)(uintptr_t)SIGINT);
- break;
- case 10:
- signal_callback(0,0,(void*)(uintptr_t)SIGUSR1);
- break;
- case 12:
- signal_callback(0,0,(void*)(uintptr_t)SIGUSR2);
- break;
- case 15:
- signal_callback(0,0,(void*)(uintptr_t)SIGTERM);
- break;
- case SIGNEWNYM:
- signal_callback(0,0,(void*)(uintptr_t)SIGNEWNYM);
- break;
- case SIGCLEARDNSCACHE:
- signal_callback(0,0,(void*)(uintptr_t)SIGCLEARDNSCACHE);
- break;
- default:
- log_warn(LD_BUG, "Unrecognized signal number %d.", the_signal);
- break;
- }
-}
-
/** Libevent callback: invoked when we get a signal.
*/
-static void
+void
signal_callback(int fd, short events, void *arg)
{
uintptr_t sig = (uintptr_t)arg;
diff --git a/src/or/main.h b/src/or/main.h
index ed0fb97..626bf1c 100644
--- a/src/or/main.h
+++ b/src/or/main.h
@@ -46,8 +46,8 @@ void directory_info_has_arrived(time_t now, int from_cache);
void ip_address_changed(int at_interface);
void dns_servers_relaunch_checks(void);
-void control_signal_act(int the_signal);
void handle_signals(int is_parent);
+void signal_callback(int fd, short events, void *arg);
int try_locking(or_options_t *options, int err_if_locked);
int have_lockfile(void);
diff --git a/src/or/or.h b/src/or/or.h
index 1688a08..06e6d7f 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -91,7 +91,7 @@
#include "compat_libevent.h"
#include "ht.h"
-/* These signals are defined to help control_signal_act work.
+/* These signals are defined to help handle_control_signal work.
*/
#ifndef SIGHUP
#define SIGHUP 1
1
0
commit 5114e3e44235ea39447eea37213c65413cdb1a2c
Author: Sebastian Hahn <sebastian(a)torproject.org>
Date: Thu Apr 14 20:04:39 2011 -0700
Make SIGNAL DUMP work on FreeBSD
While doing so, get rid of the now unnecessary function
control_signal_act().
Fixes bug 2917, reported by Robert Ransom. Bugfix on commit
9b4aa8d2abbce71398e58188209a1b1d04885b96. This patch is loosely based on
a patch by Robert (Changelog entry).
---
changes/bug2917 | 4 ++++
src/or/control.c | 3 ++-
src/or/main.c | 43 +------------------------------------------
src/or/main.h | 2 +-
src/or/or.h | 2 +-
5 files changed, 9 insertions(+), 45 deletions(-)
diff --git a/changes/bug2917 b/changes/bug2917
new file mode 100644
index 0000000..6b1e643
--- /dev/null
+++ b/changes/bug2917
@@ -0,0 +1,4 @@
+ o Minor bugfixes
+ - Make the SIGNAL DUMP control-port command work on FreeBSD. Fixes
+ bug 2917. Bugfix on 0.1.1.1-alpha.
+
diff --git a/src/or/control.c b/src/or/control.c
index 8f3af0b..bb1c330 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -1222,7 +1222,8 @@ handle_control_signal(control_connection_t *conn, uint32_t len,
/* Flush the "done" first if the signal might make us shut down. */
if (sig == SIGTERM || sig == SIGINT)
connection_handle_write(TO_CONN(conn), 1);
- control_signal_act(sig);
+ signal_callback(0,0,(void*)(uintptr_t)sig);
+
return 0;
}
diff --git a/src/or/main.c b/src/or/main.c
index 83d1e1e..5e4d88c 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -64,7 +64,6 @@ static void dumpmemusage(int severity);
static void dumpstats(int severity); /* log stats */
static void conn_read_callback(int fd, short event, void *_conn);
static void conn_write_callback(int fd, short event, void *_conn);
-static void signal_callback(int fd, short events, void *arg);
static void second_elapsed_callback(periodic_timer_t *timer, void *args);
static int conn_close_if_marked(int i);
static void connection_start_reading_from_linked_conn(connection_t *conn);
@@ -1577,49 +1576,9 @@ do_main_loop(void)
}
}
-/** Used to implement the SIGNAL control command: if we accept
- * <b>the_signal</b> as a remote pseudo-signal, act on it. */
-/* We don't re-use catch() here because:
- * 1. We handle a different set of signals than those allowed in catch.
- * 2. Platforms without signal() are unlikely to define SIGfoo.
- * 3. The control spec is defined to use fixed numeric signal values
- * which just happen to match the Unix values.
- */
-void
-control_signal_act(int the_signal)
-{
- switch (the_signal)
- {
- case 1:
- signal_callback(0,0,(void*)(uintptr_t)SIGHUP);
- break;
- case 2:
- signal_callback(0,0,(void*)(uintptr_t)SIGINT);
- break;
- case 10:
- signal_callback(0,0,(void*)(uintptr_t)SIGUSR1);
- break;
- case 12:
- signal_callback(0,0,(void*)(uintptr_t)SIGUSR2);
- break;
- case 15:
- signal_callback(0,0,(void*)(uintptr_t)SIGTERM);
- break;
- case SIGNEWNYM:
- signal_callback(0,0,(void*)(uintptr_t)SIGNEWNYM);
- break;
- case SIGCLEARDNSCACHE:
- signal_callback(0,0,(void*)(uintptr_t)SIGCLEARDNSCACHE);
- break;
- default:
- log_warn(LD_BUG, "Unrecognized signal number %d.", the_signal);
- break;
- }
-}
-
/** Libevent callback: invoked when we get a signal.
*/
-static void
+void
signal_callback(int fd, short events, void *arg)
{
uintptr_t sig = (uintptr_t)arg;
diff --git a/src/or/main.h b/src/or/main.h
index ed0fb97..626bf1c 100644
--- a/src/or/main.h
+++ b/src/or/main.h
@@ -46,8 +46,8 @@ void directory_info_has_arrived(time_t now, int from_cache);
void ip_address_changed(int at_interface);
void dns_servers_relaunch_checks(void);
-void control_signal_act(int the_signal);
void handle_signals(int is_parent);
+void signal_callback(int fd, short events, void *arg);
int try_locking(or_options_t *options, int err_if_locked);
int have_lockfile(void);
diff --git a/src/or/or.h b/src/or/or.h
index 1688a08..06e6d7f 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -91,7 +91,7 @@
#include "compat_libevent.h"
#include "ht.h"
-/* These signals are defined to help control_signal_act work.
+/* These signals are defined to help handle_control_signal work.
*/
#ifndef SIGHUP
#define SIGHUP 1
1
0

[tor/maint-0.2.2] Expose a new process_signal(uintptr_t), not signal_callback()
by nickm@torproject.org 26 Apr '11
by nickm@torproject.org 26 Apr '11
26 Apr '11
commit f810a1afe990788cd8f944a515a493902df84ed1
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Apr 26 15:20:08 2011 -0400
Expose a new process_signal(uintptr_t), not signal_callback()
This is a tweak to the bug2917 fix. Basically, if we want to simulate
a signal arriving in the controller, we shouldn't have to pretend that
we're Libevent, or depend on how Tor sets up its Libevent callbacks.
---
src/or/control.c | 3 ++-
src/or/main.c | 10 +++++++++-
src/or/main.h | 2 +-
3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/or/control.c b/src/or/control.c
index bb1c330..9f7739a 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -1222,7 +1222,8 @@ handle_control_signal(control_connection_t *conn, uint32_t len,
/* Flush the "done" first if the signal might make us shut down. */
if (sig == SIGTERM || sig == SIGINT)
connection_handle_write(TO_CONN(conn), 1);
- signal_callback(0,0,(void*)(uintptr_t)sig);
+
+ process_signal(sig);
return 0;
}
diff --git a/src/or/main.c b/src/or/main.c
index 5e4d88c..1699568 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1578,12 +1578,20 @@ do_main_loop(void)
/** Libevent callback: invoked when we get a signal.
*/
-void
+static void
signal_callback(int fd, short events, void *arg)
{
uintptr_t sig = (uintptr_t)arg;
(void)fd;
(void)events;
+
+ process_signal(sig);
+}
+
+/** Do the work of acting on a signal received in <b>sig</b> */
+void
+process_signal(uintptr_t sig)
+{
switch (sig)
{
case SIGTERM:
diff --git a/src/or/main.h b/src/or/main.h
index 626bf1c..0551f7a 100644
--- a/src/or/main.h
+++ b/src/or/main.h
@@ -47,7 +47,7 @@ void ip_address_changed(int at_interface);
void dns_servers_relaunch_checks(void);
void handle_signals(int is_parent);
-void signal_callback(int fd, short events, void *arg);
+void process_signal(uintptr_t sig);
int try_locking(or_options_t *options, int err_if_locked);
int have_lockfile(void);
1
0

[tor/maint-0.2.2] Merge remote-tracking branch 'sebastian/bug2917' into maint-0.2.2
by nickm@torproject.org 26 Apr '11
by nickm@torproject.org 26 Apr '11
26 Apr '11
commit a7a906603e0c7e3c8519a948b5adf43bfecf6f66
Merge: b75d1da 5114e3e
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Apr 26 15:17:03 2011 -0400
Merge remote-tracking branch 'sebastian/bug2917' into maint-0.2.2
changes/bug2917 | 4 ++++
src/or/control.c | 3 ++-
src/or/main.c | 43 +------------------------------------------
src/or/main.h | 2 +-
src/or/or.h | 2 +-
5 files changed, 9 insertions(+), 45 deletions(-)
1
0