[tor-commits] [stegotorus/master] adding changes to Makefiles.am and http.cc
zwol at torproject.org
zwol at torproject.org
Fri Jul 20 23:17:07 UTC 2012
commit 7539220546986e3a5e35498ba6980f429da1427f
Author: Vinod Yegneswaran <vinod at safdef.isc.org>
Date: Tue Feb 14 15:30:47 2012 -0800
adding changes to Makefiles.am and http.cc
---
Makefile.am | 3 +
src/steg/http.cc | 245 ++++++++++++++++++++++++++++-------------------------
2 files changed, 132 insertions(+), 116 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 9affaed..d81d072 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,6 +19,9 @@ PROTOCOLS = \
src/protocol/null.cc
STEGANOGRAPHERS = \
+ src/steg/b64cookies.cc \
+ src/steg/b64encode.cc \
+ src/steg/b64decode.cc \
src/steg/cookies.cc \
src/steg/crc32.cc \
src/steg/embed.cc \
diff --git a/src/steg/http.cc b/src/steg/http.cc
index 3402ba7..3251995 100644
--- a/src/steg/http.cc
+++ b/src/steg/http.cc
@@ -40,6 +40,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "swfSteg.h"
#include "pdfSteg.h"
#include "jsSteg.h"
+#include "b64cookies.h"
#include <event2/buffer.h>
#include <stdio.h>
@@ -254,116 +255,135 @@ http_client_cookie_transmit (http *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
presently uses the URL. And it can't be binary. */
- // struct evbuffer *scratch;
- struct evbuffer_iovec *iv;
- int i, nv;
- struct evbuffer *dest = conn_get_outbound(conn);
- size_t sbuflen = evbuffer_get_length(source);
- char buf[10000];
- unsigned char data[(int) sbuflen*2];
- // unsigned char outbuf[MAX_COOKIE_SIZE];
- unsigned char outbuf[(int) sbuflen*8];
- int datalen;
-
-
- // size_t sofar = 0;
- size_t cookie_len;
-
-
- /* 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. */
+ struct evbuffer *dest = conn_get_outbound(conn);
+ size_t sbuflen = evbuffer_get_length(source);
+ int bufsize = 10000;
+ char* buf = (char*) xmalloc(bufsize);
- unsigned int len = 0;
- unsigned int cnt = 0;
+ char* data;
+ char* data2 = (char*) xmalloc (sbuflen*4);
+ char* cookiebuf = (char*) xmalloc (sbuflen*8);
+ int payload_len = 0;
+ int cnt = 0;
+ int cookie_len = 0;
+ int rval;
+ int len = 0;
+ base64::encoder E;
- datalen = 0;
- cookie_len = 4 * sbuflen + rand() % 4;
+ data = (char*) evbuffer_pullup(source, sbuflen);
+ if (data == NULL) {
+ log_debug("evbuffer_pullup failed");
+ goto err;
+ }
- nv = evbuffer_peek(source, sbuflen, NULL, NULL, 0);
- iv = (evbuffer_iovec*)xzalloc(sizeof(struct evbuffer_iovec) * nv);
- if (evbuffer_peek(source, sbuflen, NULL, iv, nv) != nv) {
- free(iv);
- return -1;
- }
// retry up to 10 times
- while (!len) {
- len = find_client_payload(buf, sizeof(buf), TYPE_HTTP_REQUEST);
- if (cnt++ == 10) return -1;
+ while (!payload_len) {
+ payload_len = find_client_payload(buf, bufsize, TYPE_HTTP_REQUEST);
+ if (cnt++ == 10) {
+ goto err;
+ }
}
-
+ buf[payload_len] = 0;
if (has_peer_name == 0 && lookup_peer_name_from_ip((char*) conn->peername, peername))
has_peer_name = 1;
- // if (find_uri_type(buf) != HTTP_CONTENT_SWF) {
- // fprintf(stderr, "%s\n", buf);
- // exit(-1);
- // }
+ bzero(data2, sbuflen*4);
+ E.encode((char*) data, sbuflen, (char*) data2);
+ E.encode_end(data2+strlen((char*) data2));
+ len = (int) strlen(data2) - 1;
+ // remove trailing newline
+ data2[len] = 0;
+
+ // substitute / with _, + with ., = with - that maybe inserted anywhere in the middle
+ sanitize_b64(data2, len);
- cnt = 0;
+
+ cookie_len = gen_b64_cookie_field(cookiebuf, data2, len);
+ cookiebuf[cookie_len] = 0;
- for (i = 0; i < nv; i++) {
- const unsigned char *p = (const unsigned char *)iv[i].iov_base;
- const unsigned char *limit = p + iv[i].iov_len;
- char c;
- while (p < limit && cnt < sbuflen) {
- c = *p++;
- data[datalen] = "0123456789abcdef"[(c & 0xF0) >> 4];
- data[datalen+1] = "0123456789abcdef"[(c & 0x0F) >> 0];
- datalen += 2;
- cnt++;
- }
+
+
+ if (cookie_len < 0) {
+ log_debug("cookie generation failed\n");
+ return -1;
}
+
- free(iv);
+ // add uri field
+ rval = evbuffer_add(dest, buf, strstr(buf, "\r\n") - buf + 2);
+ if (rval) {
+ log_warn("error adding uri field\n");
+ goto err;
+ }
- if (cookie_len < 4) cookie_len = 4;
+ rval = evbuffer_add(dest, "Host: ", 6);
+ if (rval) {
+ log_warn("error adding host field\n");
+ goto err;
+ }
- datalen = gen_cookie_field(outbuf, cookie_len, data, datalen);
- log_debug("CLIENT: sending cookie of length = %d %d\n", datalen, (int) cookie_len);
- // fprintf(stderr, "CLIENT: sending cookie of length = %d %d\n", datalen, (int) cookie_len);
+ rval = evbuffer_add(dest, peername, strlen(peername));
+ if (rval) {
+ log_warn("error adding peername field\n");
+ goto err;
+ }
- if (datalen < 0) {
- log_debug("cookie generation failed\n");
- return -1;
+
+ rval = evbuffer_add(dest, strstr(buf, "\r\n"), payload_len - (unsigned int) (strstr(buf, "\r\n") - buf));
+ if (rval) {
+ log_warn("error adding HTTP fields\n");
+ goto err;
}
+ rval = evbuffer_add(dest, "Cookie: ", 8);
+ if (rval) {
+ log_warn("error adding cookie fields\n");
+ goto err;
+ }
+ rval = evbuffer_add(dest, cookiebuf, cookie_len);
- if (evbuffer_add(dest, buf, strstr(buf, "\r\n") - buf + 2) || // add uri field
- evbuffer_add(dest, "Host: ", 6) ||
- 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, "Cookie: ", 8) ||
- evbuffer_add(dest, outbuf, cookie_len) ||
- evbuffer_add(dest, "\r\n\r\n", 4)) {
- log_debug("error ***********************");
- return -1;
- }
+ if (rval) {
+ log_warn("error adding cookie buf\n");
+ goto err;
+ }
- // debug
- // log_warn("CLIENT HTTP request header:");
- // buf_dump((unsigned char*)buf, len, stderr);
- // sofar += datalen/2;
- evbuffer_drain(source, datalen/2);
+ rval = evbuffer_add(dest, "\r\n\r\n", 4);
+
+ if (rval) {
+ log_warn("error adding terminators \n");
+ goto err;
+ }
- log_debug("CLIENT TRANSMITTED payload %d\n", (int) sbuflen);
+
+ evbuffer_drain(source, sbuflen);
+ log_debug("CLIENT TRANSMITTED payload %d\n", (int) sbuflen);
conn_cease_transmission(conn);
- s->type = find_uri_type(buf, sizeof(buf));
+ s->type = find_uri_type(buf, bufsize);
s->have_transmitted = true;
+
+
+ free(buf);
+ free(data2);
return 0;
+
+err:
+ free(buf);
+ free(data2);
+ return -1;
+
}
@@ -547,11 +567,13 @@ http::transmit(struct evbuffer *source, conn_t *conn)
if (is_clientside) {
/* 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
- presently uses the URL. And it can't be binary. */
+ the only plausible places to put it are the URL and cookies. */
- if (evbuffer_get_length(source) < 72)
- return http_client_uri_transmit(this, source, conn); //@@
+ /* if (evbuffer_get_length(source) < 72)
+ return http_client_uri_transmit(this, source, conn);
+ */
+
+ //@@
return http_client_cookie_transmit(this, source, conn); //@@
}
else {
@@ -588,15 +610,16 @@ http::transmit(struct evbuffer *source, conn_t *conn)
int
http_server_receive(http *s, conn_t *conn, struct evbuffer *dest, struct evbuffer* source) {
- int cnt = 0;
- unsigned char* data;
+ char* data;
int type;
do {
struct evbuffer_ptr s2 = evbuffer_search(source, "\r\n\r\n", sizeof ("\r\n\r\n") -1 , NULL);
- unsigned char *p;
- unsigned char c, h, secondhalf;
+ char *p;
+ char *pend;
+
char outbuf[MAX_COOKIE_SIZE];
+ char outbuf2[MAX_COOKIE_SIZE];
int sofar = 0;
int cookie_mode = 0;
@@ -609,7 +632,7 @@ http_server_receive(http *s, conn_t *conn, struct evbuffer *dest, struct evbuffe
log_debug("SERVER received request header of length %d", (int)s2.pos);
- data = evbuffer_pullup(source, s2.pos+4);
+ data = (char*) evbuffer_pullup(source, s2.pos+4);
if (data == NULL) {
log_debug("SERVER evbuffer_pullup fails");
@@ -622,54 +645,45 @@ http_server_receive(http *s, conn_t *conn, struct evbuffer *dest, struct evbuffe
type = find_uri_type((char *)data, s2.pos+4);
if (strstr((char*) data, "Cookie") != NULL) {
- p = (unsigned char*) strstr((char*) data, "Cookie:") + sizeof "Cookie: "-1;
+ p = strstr((char*) data, "Cookie:") + sizeof "Cookie: "-1;
cookie_mode = 1;
}
else
p = data + sizeof "GET /" -1;
+ pend = strstr(p, "\r\n");
- secondhalf = 0;
- c = 0;
+ if (pend == NULL || (pend - p > MAX_COOKIE_SIZE)) {
+ fprintf(stderr, "incorrect cookie recovery \n");
+ exit(-1);
+
+ }
- while (strncmp((char*) p, "\r\n", 2) != 0 && (cookie_mode != 0 || p[0] != '.') && sofar < MAX_COOKIE_SIZE) {
- 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;
- }
- c = (c << 4) + h;
- if (secondhalf) {
- outbuf[sofar++] = c;
- cnt++;
- }
- secondhalf = !secondhalf;
- p++;
- }
+ bzero(outbuf, sizeof(outbuf));
+ int cookielen = unwrap_b64_cookie((char*) p, (char*) outbuf, pend - p);
- if (sofar >= MAX_COOKIE_SIZE) {
- fprintf(stderr, "cookie buffer overflow\n");
- exit(-1);
- }
+ desanitize_b64(outbuf, cookielen);
+ outbuf[cookielen] = '\n';
+ bzero(outbuf2, sizeof(outbuf2));
- outbuf[sofar] = 0;
+ base64::decoder D;
+ sofar = D.decode(outbuf, cookielen+1, outbuf2);
- if (secondhalf) {
- fprintf(stderr, "incorrect cookie or uri recovery \n");
- exit(-1);
- }
+ if (sofar <= 0)
+ log_warn("decode failed\n");
+
+
+ if (sofar >= MAX_COOKIE_SIZE) {
+ log_warn("cookie buffer overflow????\n");
+ exit(-1);
+ }
- if (evbuffer_add(dest, outbuf, sofar)) {
+ if (evbuffer_add(dest, outbuf2, sofar)) {
log_debug("Failed to transfer buffer");
return RECV_BAD;
}
@@ -679,7 +693,6 @@ http_server_receive(http *s, conn_t *conn, struct evbuffer *dest, struct evbuffe
s->have_received = 1;
s->type = type;
- // fprintf(stderr, "SERVER RECEIVED payload %d %d\n", cnt, type);
conn_transmit_soon(conn, 100);
return RECV_GOOD;
More information about the tor-commits
mailing list