[tor-commits] [tor/master] Write function that parses ServerTransportOptions torrc lines.

nickm at torproject.org nickm at torproject.org
Thu Jul 18 12:48:29 UTC 2013


commit 08d98071252995d586f0ac3cef82f6ec46fc9347
Author: George Kadianakis <desnacked at riseup.net>
Date:   Wed Jun 12 15:28:31 2013 +0300

    Write function that parses ServerTransportOptions torrc lines.
    
    And use it to validate them.
---
 src/or/config.c |   71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/or/config.h |    3 +++
 src/or/or.h     |    3 +++
 3 files changed, 77 insertions(+)

diff --git a/src/or/config.c b/src/or/config.c
index 6d3b133..1f6d1db 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -280,6 +280,7 @@ static config_var_t option_vars_[] = {
   V(IPv6Exit,                    BOOL,     "0"),
   VAR("ServerTransportPlugin",   LINELIST, ServerTransportPlugin,  NULL),
   V(ServerTransportListenAddr,   LINELIST, NULL),
+  V(ServerTransportOptions,      LINELIST, NULL),
   V(Socks4Proxy,                 STRING,   NULL),
   V(Socks5Proxy,                 STRING,   NULL),
   V(Socks5ProxyUsername,         STRING,   NULL),
@@ -3147,6 +3148,19 @@ options_validate(or_options_t *old_options, or_options_t *options,
                "ServerTransportListenAddr line will be ignored.");
   }
 
+  for (cl = options->ServerTransportOptions; cl; cl = cl->next) {
+    /** If get_options_from_transport_options_line() fails with
+        'transport' being NULL, it means that something went wrong
+        while parsing the ServerTransportOptions line. */
+    smartlist_t *options_sl =
+      get_options_from_transport_options_line(cl->value, NULL);
+    if (!options_sl)
+      REJECT("ServerTransportOptions did not parse. See logs for details.");
+
+    SMARTLIST_FOREACH(options_sl, char *, cp, tor_free(cp));
+    smartlist_free(options_sl);
+  }
+
   if (options->ConstrainedSockets) {
     /* If the user wants to constrain socket buffer use, make sure the desired
      * limit is between MIN|MAX_TCPSOCK_BUFFER in k increments. */
@@ -4580,6 +4594,63 @@ get_bindaddr_from_transport_listen_line(const char *line,const char *transport)
   return addrport;
 }
 
+/** Given a ServerTransportOptions <b>line</b>, return a smartlist
+ *  with the options. Return NULL if the line was not well-formed.
+ *
+ *  If <b>transport</b> is set, return NULL if the line is not
+ *  referring to <b>transport</b>.
+ *
+ *  The returned smartlist and its strings are allocated on the heap
+ *  and it's the responsibility of the caller to free it. */
+smartlist_t *
+get_options_from_transport_options_line(const char *line,const char *transport)
+{
+  smartlist_t *items = smartlist_new();
+  smartlist_t *options = smartlist_new();
+  const char *parsed_transport = NULL;
+
+  smartlist_split_string(items, line, NULL,
+                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
+
+  if (smartlist_len(items) < 2) {
+    log_warn(LD_CONFIG,"Too few arguments on ServerTransportOptions line.");
+    goto err;
+  }
+
+  parsed_transport = smartlist_get(items, 0);
+  /* If 'transport' is given, check if it matches the one on the line */
+  if (transport && strcmp(transport, parsed_transport))
+    goto err;
+
+  SMARTLIST_FOREACH_BEGIN(items, const char *, option) {
+    if (option_sl_idx == 0) /* skip the transport field (first field)*/
+      continue;
+
+    /* validate that it's a k=v value */
+    if (!string_is_key_value(LOG_WARN, option)) {
+      log_warn(LD_CONFIG, "%s is not a k=v value.", escaped(option));
+      goto err;
+    }
+
+    /* add it to the options smartlist */
+    smartlist_add(options, tor_strdup(option));
+    log_debug(LD_CONFIG, "Added %s to the list of options", escaped(option));
+  } SMARTLIST_FOREACH_END(option);
+
+  goto done;
+
+ err:
+  SMARTLIST_FOREACH(options, char*, s, tor_free(s));
+  smartlist_free(options);
+  options = NULL;
+
+ done:
+  SMARTLIST_FOREACH(items, char*, s, tor_free(s));
+  smartlist_free(items);
+
+  return options;
+}
+
 /** Given the name of a pluggable transport in <b>transport</b>, check
  *  the configuration file to see if the user has explicitly asked for
  *  it to listen on a specific port. Return a <address:port> string if
diff --git a/src/or/config.h b/src/or/config.h
index c35214c..11e8109 100644
--- a/src/or/config.h
+++ b/src/or/config.h
@@ -112,6 +112,9 @@ typedef struct bridge_line_t {
 
 void bridge_line_free(bridge_line_t *bridge_line);
 bridge_line_t *parse_bridge_line(const char *line);
+smartlist_t *get_options_from_transport_options_line(const char *line,
+                                                     const char *transport);
+
 
 #endif
 
diff --git a/src/or/or.h b/src/or/or.h
index 568958d..b8c4279 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -3500,6 +3500,9 @@ typedef struct {
   /** List of TCP/IP addresses that transports should listen at. */
   config_line_t *ServerTransportListenAddr;
 
+  /** List of options that must be passed to pluggable transports. */
+  config_line_t *ServerTransportOptions;
+
   int BridgeRelay; /**< Boolean: are we acting as a bridge relay? We make
                     * this explicit so we can change how we behave in the
                     * future. */





More information about the tor-commits mailing list