[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