[tor-commits] [stegotorus/master] Remove server-side steg detection.

zwol at torproject.org zwol at torproject.org
Fri Jul 20 23:17:06 UTC 2012


commit 61c716fe80544f8a4f252fa1a665c95b763468ad
Author: Zack Weinberg <zackw at cmu.edu>
Date:   Mon Jan 30 16:02:19 2012 -0800

    Remove server-side steg detection.
    
    The server for 'chop' protocol now expects to be told, on the command
    line, which steg to use with which ports, in the same fashion as the
    client.
---
 scripts/start-client.csh    |    4 +-
 scripts/start-server.csh    |    8 ++--
 scripts/start-stegotorus.sh |    2 +-
 src/protocol/chop.cc        |   34 ++++-----------
 src/steg.cc                 |   11 -----
 src/steg.h                  |   32 ++++----------
 src/steg/dummy.cc           |   22 +---------
 src/steg/dummy_rr.cc        |   24 +----------
 src/steg/embed.cc           |   32 ++------------
 src/steg/http.cc            |   97 +------------------------------------------
 src/test/test_tl.py         |    2 +-
 11 files changed, 36 insertions(+), 232 deletions(-)

diff --git a/scripts/start-client.csh b/scripts/start-client.csh
index c5062e1..9919eae 100644
--- a/scripts/start-client.csh
+++ b/scripts/start-client.csh
@@ -1,10 +1,10 @@
 #!/bin/csh
 # ./stegotorus --log-min-severity=debug x_dsteg socks 127.0.0.1:1080 x_http
 
-setenv EVENT_NOKQUEUE yes 
+setenv EVENT_NOKQUEUE yes
 #./stegotorus --log-min-severity=debug chop socks 127.0.0.1:1080 127.0.0.1:8080 http 127.0.0.1:8081 http
 # ./stegotorus --log-min-severity=warn chop socks 127.0.0.1:1080 127.0.0.1:8080 http 127.0.0.1:8081 http
 #./stegotorus --log-min-severity=error chop socks 127.0.0.1:1080 127.0.0.1:8080 http 127.0.0.1:8081 http
-./stegotorus --log-min-severity=error chop socks 127.0.0.1:1080 127.0.0.1:3333 dummy 
+./stegotorus --log-min-severity=error chop socks 127.0.0.1:1080 127.0.0.1:3333 dummy
 # 127.0.0.1:3333 dummy
 
diff --git a/scripts/start-server.csh b/scripts/start-server.csh
index e5e7876..2dfcd44 100644
--- a/scripts/start-server.csh
+++ b/scripts/start-server.csh
@@ -1,7 +1,7 @@
 #!/bin/csh
 setenv EVENT_NOKQUEUE yes 
-# ./stegotorus --log-min-severity=debug chop server 87.73.82.145:8080 127.0.0.1:8080 127.0.0.1:8081
-# ./stegotorus --log-min-severity=warn chop server 87.73.82.145:8080 127.0.0.1:8080 127.0.0.1:8081
-#./stegotorus --log-min-severity=error chop server 87.73.82.145:8080 127.0.0.1:8080 127.0.0.1:8081
-./stegotorus --log-min-severity=error chop server 87.73.82.145:8080 127.0.0.1:3333
+# ./stegotorus --log-min-severity=debug chop server 87.73.82.145:8080 127.0.0.1:8080 127.0.0.1:8081 http
+# ./stegotorus --log-min-severity=warn chop server 87.73.82.145:8080 127.0.0.1:8080 127.0.0.1:8081 http
+#./stegotorus --log-min-severity=error chop server 87.73.82.145:8080 127.0.0.1:8080 127.0.0.1:8081 http
+./stegotorus --log-min-severity=error chop server 87.73.82.145:8080 127.0.0.1:3333 dummy
 
diff --git a/scripts/start-stegotorus.sh b/scripts/start-stegotorus.sh
index 647bc85..9ea5be7 100644
--- a/scripts/start-stegotorus.sh
+++ b/scripts/start-stegotorus.sh
@@ -109,7 +109,7 @@ cd $ODIR
 export EVENT_NOKQUEUE=yes
 case $TYPE in
     server)
-	./stegotorus --log-min-severity=$LOG chop server $BRIDGE_IP:$BRIDGE_PORT $IP:$PORT
+	./stegotorus --log-min-severity=$LOG chop server $BRIDGE_IP:$BRIDGE_PORT $IP:$PORT http
 	;;
     client)
 	IPS=""
diff --git a/src/protocol/chop.cc b/src/protocol/chop.cc
index 348f610..71437eb 100644
--- a/src/protocol/chop.cc
+++ b/src/protocol/chop.cc
@@ -871,8 +871,7 @@ chop_config_t::init(int n_options, const char *const *options)
     goto usage;
 
   /* From here on out, arguments alternate between downstream
-     addresses and steg targets, if we're the client.  If we're not
-     the client, the arguments are just downstream addresses. */
+     addresses and steg targets. */
   for (i = 2; i < n_options; i++) {
     struct evutil_addrinfo *addr =
       resolve_address_port(options[i], 1, !listen_up, NULL);
@@ -880,8 +879,6 @@ chop_config_t::init(int n_options, const char *const *options)
       goto usage;
     this->down_addresses.push_back(addr);
 
-    if (this->mode == LSN_SIMPLE_SERVER)
-      continue;
     i++;
     if (i == n_options)
       goto usage;
@@ -897,14 +894,13 @@ chop_config_t::init(int n_options, const char *const *options)
            "\tchop <mode> <up_address> (<down_address> [<steg>])...\n"
            "\t\tmode ~ server|client|socks\n"
            "\t\tup_address, down_address ~ host:port\n"
-           "\t\ta steg target is required for each down_address,\n"
-           "\t\tin client and socks mode, and forbidden otherwise.\n"
+           "\t\tA steg target is required for each down_address.\n"
            "\t\tThe down_address list is still required in socks mode.\n"
            "Examples:\n"
            "\tstegotorus chop client 127.0.0.1:5000 "
            "192.168.1.99:11253 http 192.168.1.99:11254 skype\n"
            "\tstegotorus chop server 127.0.0.1:9005 "
-           "192.168.1.99:11253 192.168.1.99:11254");
+           "192.168.1.99:11253 http 192.168.1.99:11254 skype");
   return false;
 }
 
@@ -1043,13 +1039,12 @@ chop_config_t::conn_create(size_t index)
 {
   chop_conn_t *conn = new chop_conn_t;
   conn->cfg = this;
-  if (this->mode != LSN_SIMPLE_SERVER) {
-    conn->steg = steg_new(this->steg_targets.at(index));
-    if (!conn->steg) {
-      free(conn);
-      return 0;
-    }
+  conn->steg = steg_new(this->steg_targets.at(index));
+  if (!conn->steg) {
+    free(conn);
+    return 0;
   }
+
   conn->recv_pending = evbuffer_new();
   return conn;
 }
@@ -1157,19 +1152,6 @@ chop_conn_t::recv()
   size_t avail;
   uint8_t decodebuf[CHOP_MAX_DATA + CHOP_WIRE_HDR_LEN];
 
-  if (!this->steg) {
-    log_assert(this->cfg->mode == LSN_SIMPLE_SERVER);
-    if (evbuffer_get_length(conn_get_inbound(this)) == 0)
-      return 0; /* need more data */
-    this->steg = steg_detect(this);
-    if (!this->steg) {
-      log_debug(this, "no recognized steg pattern detected");
-      return -1;
-    } else {
-      log_debug(this, "detected steg pattern %s", this->steg->name());
-    }
-  }
-
   if (this->steg->receive(this, this->recv_pending))
     return -1;
 
diff --git a/src/steg.cc b/src/steg.cc
index 97de9f7..768a6d8 100644
--- a/src/steg.cc
+++ b/src/steg.cc
@@ -28,17 +28,6 @@ steg_new(const char *name)
   return NULL;
 }
 
-/* Instantiate a steg module by detection. */
-steg_t *
-steg_detect(conn_t *conn)
-{
-  const steg_module *const *s;
-  for (s = supported_stegs; *s; s++)
-    if ((**s).detect(conn))
-      return (**s).new_(/*is_clientside=*/false);
-  return NULL;
-}
-
 /* Define this here rather than in the class definition so that the
    vtable will be emitted in only one place. */
 steg_t::~steg_t() {}
diff --git a/src/steg.h b/src/steg.h
index 1ad5f82..03096f1 100644
--- a/src/steg.h
+++ b/src/steg.h
@@ -7,15 +7,15 @@
 
 /** A steganography instance must define a private subclass of this
     type, that implements all of the methods below, plus a descendant
-    constructor and a static 'detect' method (see steg_module).  The
-    subclass must have exactly the same name that you use for the
-    module name in STEG_DEFINE_MODULE, and should be declared inside an
-    anonymous namespace.  Use STEG_DECLARE_METHODS in the declaration. */
+    constructor.  The subclass must have exactly the same name that
+    you use for the module name in STEG_DEFINE_MODULE, and should be
+    declared inside an anonymous namespace.  Use STEG_DECLARE_METHODS
+    in the declaration. */
 struct steg_t
 {
   bool is_clientside : 1;
 
-  steg_t() {}
+  steg_t(bool is_clientside) : is_clientside(is_clientside) {}
   virtual ~steg_t();
 
   /** Report the name of this steg module.  You do not have to define
@@ -43,24 +43,16 @@ struct steg_t
   virtual int receive(conn_t *conn, struct evbuffer *dest) = 0;
 };
 
-/** STEG_DEFINE_MODULE defines an object with this type, plus the two
-    functions that it points to.  You don't ever manipulate this object
+/** STEG_DEFINE_MODULE defines an object with this type, plus the
+    function that it points to.  You don't ever manipulate this object
     directly; however, read its documentation to understand the
-    arguments to STEG_DEFINE_MODULE and the requirements on the
-    'detect' method. */
+    arguments to STEG_DEFINE_MODULE. */
 
 struct steg_module
 {
   /** Name of the steganography module. Must be a valid C identifier. */
   const char *name;
 
-  /** Detect whether the inbound traffic from CONN is disguised using
-      the steganography this module implements.  Do not consume any
-      data from CONN's inbound buffer, regardless of success or
-      failure.  Return true if your brand of steg is detected,
-      false if not.  */
-  bool (*detect)(conn_t *conn);
-
   /** Create an appropriate steg_t subclass for this module.
       More arguments may be added later.  */
   steg_t *(*new_)(bool is_clientside);
@@ -70,14 +62,11 @@ extern const steg_module *const supported_stegs[];
 
 int steg_is_supported(const char *name);
 steg_t *steg_new(const char *name);
-steg_t *steg_detect(conn_t *conn);
 
 /* Macros for use in defining steg modules. */
 
 #define STEG_DEFINE_MODULE(mod)                 \
-  /* detect and new_ dispatchers */             \
-  static bool mod##_detect(conn_t *conn)        \
-  { return mod::detect(conn); }                 \
+  /* new_ dispatchers */                        \
   static steg_t *mod##_new(bool is_clientside)  \
   { return new mod(is_clientside); }            \
                                                 \
@@ -86,11 +75,10 @@ steg_t *steg_detect(conn_t *conn);
                                                 \
   /* module object */                           \
   extern const steg_module s_mod_##mod = {      \
-    #mod, mod##_detect, mod##_new               \
+    #mod, mod##_new                             \
   } /* deliberate absence of semicolon */
 
 #define STEG_DECLARE_METHODS(mod)                               \
-  static bool detect(conn_t *conn);                             \
   mod(bool is_clientside);                                      \
   virtual ~mod();                                               \
   virtual const char *name();                                   \
diff --git a/src/steg/dummy.cc b/src/steg/dummy.cc
index c81b53f..7033042 100644
--- a/src/steg/dummy.cc
+++ b/src/steg/dummy.cc
@@ -38,8 +38,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "steg.h"
 #include <event2/buffer.h>
 
-#define DUMMY_PORT 3333
-
 namespace {
 struct dummy : steg_t
 {
@@ -50,32 +48,14 @@ struct dummy : steg_t
 STEG_DEFINE_MODULE(dummy);
 
 dummy::dummy(bool is_clientside)
+  : steg_t(is_clientside)
 {
-  this->is_clientside = is_clientside;
 }
 
 dummy::~dummy()
 {
 }
 
-/** Determine whether a connection should be processed by this
-    steganographer. */
-bool
-dummy::detect(conn_t *conn)
-{
-  struct evutil_addrinfo *addrs = conn->cfg->get_listen_addrs(0);
-  if (!addrs) {
-    log_debug("no listen addrs\n");
-    return 0;
-  }
-
-  struct sockaddr_in* sin = (struct sockaddr_in*) addrs->ai_addr;
-  if (sin->sin_port == htons(DUMMY_PORT))
-    return 1;
-
-  return 0;
-}
-
 size_t
 dummy::transmit_room(conn_t *)
 {
diff --git a/src/steg/dummy_rr.cc b/src/steg/dummy_rr.cc
index 010b91e..705a42c 100644
--- a/src/steg/dummy_rr.cc
+++ b/src/steg/dummy_rr.cc
@@ -38,8 +38,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "steg.h"
 #include <event2/buffer.h>
 
-#define DUMMY_RR_PORT 3334
-
 namespace {
 struct dummy_rr : steg_t
 {
@@ -51,33 +49,15 @@ struct dummy_rr : steg_t
 STEG_DEFINE_MODULE(dummy_rr);
 
 dummy_rr::dummy_rr(bool is_clientside)
+  : steg_t(is_clientside),
+    can_transmit(is_clientside)
 {
-  this->is_clientside = is_clientside;
-  this->can_transmit = is_clientside;
 }
 
 dummy_rr::~dummy_rr()
 {
 }
 
-/** Determine whether a connection should be processed by this
-    steganographer. */
-bool
-dummy_rr::detect(conn_t *conn)
-{
-  struct evutil_addrinfo *addrs = conn->cfg->get_listen_addrs(0);
-  if (!addrs) {
-    log_debug("no listen addrs\n");
-    return 0;
-  }
-
-  struct sockaddr_in* sin = (struct sockaddr_in*) addrs->ai_addr;
-  if (sin->sin_port == htons(DUMMY_RR_PORT))
-    return 1;
-
-  return 0;
-}
-
 size_t
 dummy_rr::transmit_room(conn_t *)
 {
diff --git a/src/steg/embed.cc b/src/steg/embed.cc
index ae1a7fa..3cac635 100644
--- a/src/steg/embed.cc
+++ b/src/steg/embed.cc
@@ -105,10 +105,11 @@ bool embed::is_finished() {
   return cur_pkt >= cur->num_pkt;
 }
 
-embed::embed(bool is_clientside) {
+embed::embed(bool is_clientside)
+  : steg_t(is_clientside)
+{
   if (!embed_init) init_embed_traces();
 
-  this->is_clientside = is_clientside;
   cur_idx = -1;
   if (is_clientside) {
     cur_idx = get_random_trace();
@@ -118,31 +119,8 @@ embed::embed(bool is_clientside) {
   gettimeofday(&last_pkt, NULL);
 }
 
-embed::~embed() { }
-
-bool embed::detect(conn_t *conn) {
-  if (!embed_init) init_embed_traces();
-
-  struct evbuffer *source = conn_get_inbound(conn);
-  size_t src_len = evbuffer_get_length(source);
-
-  log_debug("detecting buffer of length %lu", (unsigned long)src_len);
-
-  int cur_idx;
-  if (evbuffer_copyout(source, &cur_idx, 4) != 4) return 0;
-  if (cur_idx < 0 || cur_idx >= embed_num_traces) return 0;
-
-  trace_t *cur = &embed_traces[cur_idx];
-  size_t tot_len = 0;
-  int idx = 0;
-  while (idx < cur->num_pkt && cur->pkt_sizes[idx] >= 0) {
-    tot_len += cur->pkt_sizes[idx++];
-    if (src_len == tot_len) {
-      log_debug("detected embed trace %d", cur_idx);
-      return 1;
-    }
-  }
-  return 0;
+embed::~embed()
+{
 }
 
 size_t embed::transmit_room(conn_t * /* conn */) {
diff --git a/src/steg/http.cc b/src/steg/http.cc
index 70d5014..3402ba7 100644
--- a/src/steg/http.cc
+++ b/src/steg/http.cc
@@ -127,9 +127,9 @@ buf_dump(unsigned char* buf, int len, FILE *out)
 
 
 http::http(bool is_clientside)
-  : have_transmitted(false), have_received(false)
+  : steg_t(is_clientside),
+    have_transmitted(false), have_received(false)
 {
-  this->is_clientside = is_clientside;
   if (is_clientside)
     load_payloads("traces/client.out");
   else {
@@ -146,99 +146,6 @@ http::~http()
 {
 }
 
-/** Determine whether a connection should be processed by this
-    steganographer. */
-bool
-http::detect(conn_t *conn)
-{
-  struct evbuffer *buf = conn_get_inbound(conn);
-  unsigned char *data;
-
-  //return 0;
-/*****
- Here is a list of HTTP response codes extracted from the
- server-portals.out trace
-
-7369 HTTP/1.1 200 OK
- 470 HTTP/1.1 302 Found
- 350 HTTP/1.1 304 Not Modified
- 212 HTTP/1.1 302 Moved Temporarily
- 184 HTTP/1.1 204 No Content
- 451 HTTP/1.0 200 OK
-  36 HTTP/1.0 204 No Content
-  21 HTTP/1.1 301 Moved Permanently
-  19 HTTP/1.1 302 Object moved
-  15 HTTP/1.1 404 Not Found
-
-   7 HTTP/1.0 304 Not Modified
-   6 HTTP/1.1 302 Redirect
-   3 HTTP/1.0 200 Ok
-   2 HTTP/1.1 303 Object Moved
-   2 HTTP/1.0 301 Moved Permanently
-   2 HTTP/1.0 302 Moved Temporarily
-   2 HTTP/1.0 400 Bad request
-   2 HTTP/1.0 403 Forbidden
-   1 HTTP/1.0 404 Not Found
-   1 HTTP/1.1 200
-   1 HTTP/1.1 302 FOUND
-   1 HTTP/1.1 304
-   1 HTTP/1.1 400 Bad Request
-   1 HTTP/1.1 403 Forbidden
-   1 HTTP/1.1 503 Service Unavailable.
- *****/
-
-  // The first part of a valid HTTP response should be of the form
-  // HTTP/1.x nnn
-
-  if (evbuffer_get_length(buf) >= 12) {
-    data = evbuffer_pullup(buf, 12);
-
-    if (data != NULL &&
-         ((!memcmp(data, "HTTP/1.1 200", 12)) ||
-          (!memcmp(data, "HTTP/1.1 302", 12)) ||
-          (!memcmp(data, "HTTP/1.1 304", 12)) ||
-          (!memcmp(data, "HTTP/1.1 204", 12)) ||
-          (!memcmp(data, "HTTP/1.0 200", 12)) ||
-          (!memcmp(data, "HTTP/1.0 204", 12)) ||
-          (!memcmp(data, "HTTP/1.1 301", 12)) ||
-          (!memcmp(data, "HTTP/1.1 302", 12)) ||
-          (!memcmp(data, "HTTP/1.1 404", 12)))) {
-      log_debug("http_detect: valid response");
-      return 1;
-    }
-  }
-
-
-
-
-
-  // SC: if we are only interested in jsSteg, we may want to
-  // consider HTTP/1.1 and HTTP/1.0 responses whose code is 200 only
-
-  // check to see if this is a valid HTTP request
-  //
-  // the following is for HTTP requests used by the http2 steg module
-  // The client always transmits "GET /" followed by at least four
-  // characters that are either lowercase hex digits or equals
-  // signs, so we need nine bytes of incoming data.
-
-
-
-  if (evbuffer_get_length(buf) >= 9) {
-    data = evbuffer_pullup(buf, 9);
-    if (data != NULL && (!memcmp(data, "GET /", 5) ||
-                         !memcmp(data, "POST /", 5) ||
-                         !memcmp(data, "Cookie", 6))) {
-      log_debug("http_detect: valid request");
-      return true;
-    }
-  }
-
-  log_debug("http_detect: didn't find either HTTP request or response");
-  /* Didn't find either the client or the server pattern. */
-  return false;
-}
-
 size_t
 http::transmit_room(conn_t *)
 {
diff --git a/src/test/test_tl.py b/src/test/test_tl.py
index 2c54228..dfa4128 100644
--- a/src/test/test_tl.py
+++ b/src/test/test_tl.py
@@ -49,7 +49,7 @@ class TimelineTest(object):
     def test_chop(self):
         self.doTest("chop",
            ("chop", "server", "127.0.0.1:5001",
-            "127.0.0.1:5010","127.0.0.1:5011",
+            "127.0.0.1:5010","http","127.0.0.1:5011","http",
             "chop", "client", "127.0.0.1:4999",
             "127.0.0.1:5010","http","127.0.0.1:5011","http",
             ))





More information about the tor-commits mailing list