[tor-commits] [stegotorus/master] added uri steg support to x_http2
zwol at torproject.org
zwol at torproject.org
Fri Jul 20 23:17:06 UTC 2012
commit 451f65972456021ebc3722e8383e0809fab0374f
Author: Vinod Yegneswaran <vinod at csl.sri.com>
Date: Fri Nov 4 17:38:21 2011 +0000
added uri steg support to x_http2
git-svn-id: svn+ssh://spartan.csl.sri.com/svn/private/DEFIANCE@119 a58ff0ac-194c-e011-a152-003048836090
---
src/steg/x_http.c | 2 +-
src/steg/x_http2.c | 251 +++++++++++++++++++++++++++++++++++++++------------
start-client.csh | 4 +-
3 files changed, 195 insertions(+), 62 deletions(-)
diff --git a/src/steg/x_http.c b/src/steg/x_http.c
index c26fe1f..eb08401 100644
--- a/src/steg/x_http.c
+++ b/src/steg/x_http.c
@@ -71,7 +71,7 @@ x_http_detect(conn_t *conn)
{
struct evbuffer *buf = conn_get_inbound(conn);
unsigned char *data;
- return 0;
+ return 0;
/* Look for the text of http_response_1. */
if (evbuffer_get_length(buf) >= sizeof http_response_1 - 1) {
diff --git a/src/steg/x_http2.c b/src/steg/x_http2.c
index f3789b2..1359238 100644
--- a/src/steg/x_http2.c
+++ b/src/steg/x_http2.c
@@ -87,11 +87,12 @@ STEG_DEFINE_MODULE(x_http2,
-int x_http2_client_transmit (steg_t *s, struct evbuffer *source, conn_t *conn);
+int x_http2_client_uri_transmit (steg_t *s, struct evbuffer *source, conn_t *conn);
+int x_http2_client_cookie_transmit (steg_t *s, struct evbuffer *source, conn_t *conn);
void evbuffer_dump(struct evbuffer *buf, FILE *out);
void buf_dump(unsigned char* buf, int len, FILE *out);
-
+int gen_uri_field(char* uri, unsigned int uri_sz, char* data, int datalen);
void
@@ -156,6 +157,7 @@ x_http2_new(rng_t *rng, unsigned int is_clientside)
else {
load_payloads("traces/server.out");
init_JS_payload_pool(HTTP_MSG_BUF_SIZE, TYPE_HTTP_RESPONSE, JS_MIN_AVAIL_SIZE);
+ // init_JS_payload_pool(HTTP_MSG_BUF_SIZE, TYPE_HTTP_RESPONSE, JS_MIN_AVAIL_SIZE, HTTP_CONTENT_HTML);
init_HTML_payload_pool(HTTP_MSG_BUF_SIZE, TYPE_HTTP_RESPONSE, HTML_MIN_AVAIL_SIZE);
// init_PDF_payload_pool(HTTP_MSG_BUF_SIZE, TYPE_HTTP_RESPONSE, PDF_MIN_AVAIL_SIZE);
init_SWF_payload_pool(HTTP_MSG_BUF_SIZE, TYPE_HTTP_RESPONSE, 0);
@@ -376,7 +378,7 @@ lookup_peer_name_from_ip(char* p_ip, char* p_name) {
int
-x_http2_client_transmit (steg_t *s, struct evbuffer *source, conn_t *conn) {
+x_http2_client_cookie_transmit (steg_t *s, struct evbuffer *source, conn_t *conn) {
/* On the client side, we have to embed the data in a GET query somehow;
the only plausible places to put it are the URL and cookies. This
@@ -496,6 +498,153 @@ x_http2_client_transmit (steg_t *s, struct evbuffer *source, conn_t *conn) {
+int gen_uri_field(char* uri, unsigned int uri_sz, char* data, int datalen) {
+ unsigned int so_far = 0;
+ uri[0] = 0;
+
+ strcat(uri, "GET /");
+ so_far = 5;
+
+ while (datalen > 0) {
+ unsigned int r = rand() % 4;
+
+ if (r == 1) {
+ r = rand() % 46;
+ if (r < 20)
+ uri[so_far++] = 'g' + r;
+ else
+ uri[so_far++] = 'A' + r - 20;
+ }
+ else {
+ uri[so_far++] = data[0];
+ data++;
+ datalen--;
+ }
+
+
+
+ r = rand() % 8;
+
+ if (r == 0 && datalen > 0)
+ uri[so_far++] = '/';
+
+ if (so_far > uri_sz - 6) {
+ fprintf(stderr, "too small\n");
+ return 0;
+ }
+ }
+
+ switch(rand()%4){
+ case 1:
+ memcpy(uri+so_far, ".htm ", 6);
+ break;
+ case 2:
+ memcpy(uri+so_far, ".html ", 7);
+ break;
+ case 3:
+ memcpy(uri+so_far, ".js ", 5);
+ break;
+ case 0:
+ memcpy(uri+so_far, ".swf ", 6);
+ break;
+
+ }
+
+ return strlen(uri);
+
+}
+
+
+
+
+
+int
+x_http2_client_uri_transmit (steg_t *s, struct evbuffer *source, conn_t *conn) {
+
+
+ struct evbuffer *dest = conn_get_outbound(conn);
+
+
+ struct evbuffer_iovec *iv;
+ int i, nv;
+
+ /* Convert all the data in 'source' to hexadecimal and write it to
+ 'scratch'. Data is padded to a multiple of four characters with
+ equals signs. */
+ size_t slen = evbuffer_get_length(source);
+ size_t datalen = 0;
+ int cnt = 0;
+ char data[2*slen];
+
+ char outbuf[1024];
+ int len =0;
+ char buf[10000];
+
+
+ if (has_peer_name == 0 && lookup_peer_name_from_ip((char*) conn->peername, peername))
+ has_peer_name = 1;
+
+
+
+ nv = evbuffer_peek(source, slen, NULL, NULL, 0);
+ iv = xzalloc(sizeof(struct evbuffer_iovec) * nv);
+ if (evbuffer_peek(source, slen, NULL, iv, nv) != nv) {
+ free(iv);
+ return -1;
+ }
+
+ for (i = 0; i < nv; i++) {
+ const unsigned char *p = iv[i].iov_base;
+ const unsigned char *limit = p + iv[i].iov_len;
+ char c;
+ while (p < limit) {
+ c = *p++;
+ data[datalen++] = "0123456789abcdef"[(c & 0xF0) >> 4];
+ data[datalen++] = "0123456789abcdef"[(c & 0x0F) >> 0];
+ }
+ }
+ free(iv);
+
+
+
+ do {
+ datalen = gen_uri_field(outbuf, sizeof(outbuf), data, datalen);
+ } while (datalen == 0);
+
+
+
+
+ // retry up to 10 times
+ while (!len) {
+ len = find_client_payload(buf, sizeof(buf), TYPE_HTTP_REQUEST);
+ if (cnt++ == 10) return -1;
+ }
+
+
+ // fprintf(stderr, "outbuf = %s\n", outbuf);
+
+ if (evbuffer_add(dest, outbuf, datalen) || // add uri field
+ evbuffer_add(dest, "HTTP 1.1\r\nHost: ", 19) ||
+ evbuffer_add(dest, peername, strlen(peername)) ||
+ evbuffer_add(dest, strstr(buf, "\r\n"), len - (unsigned int) (strstr(buf, "\r\n") - buf)) || // add everything but first line
+ evbuffer_add(dest, "\r\n", 2)) {
+ log_debug("error ***********************");
+ return -1;
+ }
+
+
+
+ evbuffer_drain(source, slen);
+ conn_cease_transmission(conn);
+ downcast_steg(s)->type = find_uri_type(outbuf);
+ downcast_steg(s)->have_transmitted = 1;
+ return 0;
+
+}
+
+
+
+
@@ -526,7 +675,9 @@ x_http2_transmit(steg_t *s, struct evbuffer *source, conn_t *conn)
the only plausible places to put it are the URL and cookies. This
presently uses the URL. And it can't be binary. */
- return x_http2_client_transmit(s, source, conn); //@@
+ if (evbuffer_get_length(source) < 256)
+ return x_http2_client_uri_transmit(s, source, conn); //@@
+ return x_http2_client_cookie_transmit(s, source, conn); //@@
}
else {
int rval = -1;
@@ -570,10 +721,10 @@ x_http2_server_receive(steg_t *s, conn_t *conn, struct evbuffer *dest, struct ev
struct evbuffer_ptr s2 = evbuffer_search(source, "\r\n\r\n", sizeof ("\r\n\r\n") -1 , NULL);
unsigned char* limit;
unsigned char *p;
- int unwrapped_cookie_len;
- struct evbuffer *scratch;
unsigned char c, h, secondhalf;
- unsigned char buf[evbuffer_get_length(source)];
+ char outbuf[MAX_COOKIE_SIZE];
+ int sofar = 0;
+ int cookie_mode = 0;
if (s2.pos == -1) {
@@ -584,7 +735,7 @@ x_http2_server_receive(steg_t *s, conn_t *conn, struct evbuffer *dest, struct ev
log_debug("SERVER received request header of length %d", (int)s2.pos);
- data = evbuffer_pullup(source, s2.pos);
+ data = evbuffer_pullup(source, s2.pos+4);
if (data == NULL) {
log_debug("SERVER evbuffer_pullup fails");
return RECV_BAD;
@@ -593,81 +744,60 @@ x_http2_server_receive(steg_t *s, conn_t *conn, struct evbuffer *dest, struct ev
limit = data + s2.pos;
type = find_uri_type((char *)data);
- log_warn ("*** Got type %d", type);
- /* if (type != 3) {
- fprintf(stderr, "type != 3, %d, data = %s \n", find_uri_type2((char *) data), data);
- exit(-1);
- }*/
+ data[s2.pos+4] = 0;
+ // fprintf(stderr, "data = %s\n", data);
- data = (unsigned char*) strstr((char*) data, "Cookie:");
-
- if (data == NULL || memcmp(data, "Cookie:", sizeof "Cookie:"-1)) {
- log_debug("Unexpected HTTP verb: %.*s", 5, data);
- return RECV_BAD;
+ if (strstr((char*) data, "Cookie") != NULL) {
+ data = (unsigned char*) strstr((char*) data, "Cookie:");
+ p = data + sizeof "Cookie: "-1;
+ cookie_mode = 1;
}
-
- p = data + sizeof "Cookie: "-1;
- unwrapped_cookie_len = unwrap_cookie(p, buf, (int) (limit - p));
-
- log_debug("SERVER: received cookie of length = %d %d\n", unwrapped_cookie_len, (int) (limit-p));
- // buf_dump(buf, unwrapped_cookie_len, stderr);
- // fprintf(stderr, "==========================\n");
- // buf_dump(p, (int) (limit-p), stderr);
-
-
- // log_debug("hello SERVER received %d cnt = %d\n", (int) (limit - p), cnt);
- // buf_dump(p, (int) (limit-p), stderr);
-
- /* We need a scratch buffer here because the contract is that if
- we hit a decode error we *don't* write anything to 'dest'. */
- scratch = evbuffer_new();
-
- if (!scratch) return RECV_BAD;
-
-
- if (evbuffer_expand(scratch, unwrapped_cookie_len/2)) {
- log_debug("Evbuffer expand failed \n");
- evbuffer_free(scratch);
- return RECV_BAD;
- }
- p = buf;
+ else
+ p = data + sizeof "GET /" -1;
secondhalf = 0;
- while ((int) (p - buf) < unwrapped_cookie_len) {
- if (!secondhalf) c = 0;
- if ('0' <= *p && *p <= '9') h = *p - '0';
- else if ('a' <= *p && *p <= 'f') h = *p - 'a' + 10;
- else if ('A' <= *p && *p <= 'F') h = *p - 'A' + 10;
- else if (*p == '=' && !secondhalf) {
+ c = 0;
+
+
+ while (strncmp((char*) p, "\r\n", 4) != 0 && (cookie_mode != 0 || p[0] != '.')) {
+ if (!secondhalf)
+ c = 0;
+ if ('0' <= *p && *p <= '9')
+ h = *p - '0';
+ else if ('a' <= *p && *p <= 'f')
+ h = *p - 'a' + 10;
+ else {
p++;
continue;
- } else {
- evbuffer_free(scratch);
- log_debug("Decode error: unexpected URI characterasdfaf %d", *p);
- return RECV_BAD;
}
c = (c << 4) + h;
if (secondhalf) {
- evbuffer_add(scratch, &c, 1);
- // log_debug("adding to scratch");
+ outbuf[sofar++] = c;
cnt++;
}
secondhalf = !secondhalf;
p++;
}
+ outbuf[sofar] = 0;
+
+ // fprintf(stderr, "recvd = %d\n", sofar);
+
+ if (secondhalf) {
+ fprintf(stderr, "incorrect cookie or uri recovery \n");
+ exit(-1);
+ }
+
- if (evbuffer_add_buffer(dest, scratch)) {
- evbuffer_free(scratch);
+ if (evbuffer_add(dest, outbuf, sofar)) {
log_debug("Failed to transfer buffer");
return RECV_BAD;
}
evbuffer_drain(source, s2.pos + sizeof("\r\n\r\n") - 1);
- evbuffer_free(scratch);
} while (evbuffer_get_length(source));
@@ -686,6 +816,9 @@ x_http2_server_receive(steg_t *s, conn_t *conn, struct evbuffer *dest, struct ev
+
+
+
static int
x_http2_receive(steg_t *s, conn_t *conn, struct evbuffer *dest)
{
diff --git a/start-client.csh b/start-client.csh
index a09302e..65f4465 100644
--- a/start-client.csh
+++ b/start-client.csh
@@ -2,7 +2,7 @@
# ./obfsproxy --log-min-severity=debug x_dsteg socks 127.0.0.1:1080 x_http
setenv EVENT_NOKQUEUE yes
-./obfsproxy --log-min-severity=debug chop socks 127.0.0.1:1080 127.0.0.1:8080 x_http2 127.0.0.1:8081 x_http2
+#./obfsproxy --log-min-severity=debug chop socks 127.0.0.1:1080 127.0.0.1:8080 x_http2 127.0.0.1:8081 x_http2
# ./obfsproxy --log-min-severity=warn chop socks 127.0.0.1:1080 127.0.0.1:8080 x_http2 127.0.0.1:8081 x_http2
-#./obfsproxy --log-min-severity=error chop socks 127.0.0.1:1080 127.0.0.1:8080 x_http2 127.0.0.1:8081 x_http2
+./obfsproxy --log-min-severity=error chop socks 127.0.0.1:1080 127.0.0.1:8080 x_http2 127.0.0.1:8081 x_http2
More information about the tor-commits
mailing list