]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Add support for PT STATUS TYPE=version messages.
authorAlexander Færøy <ahf@torproject.org>
Thu, 24 Mar 2022 19:13:41 +0000 (19:13 +0000)
committerDavid Goulet <dgoulet@torproject.org>
Tue, 18 Jun 2024 19:15:20 +0000 (15:15 -0400)
This patch adds support for handling the version status message. Once we
receive such message, we add the given version string to the
managed_proxy_t instance. Note this value can be NULL and the value can
change throughout the lifetime of the PT as multiple status version
messages are handled.

See: tpo/core/tor#11101

src/feature/client/transports.c
src/feature/client/transports.h
src/test/test_pt.c

index 4d92a2a67aac862c4e376174dd8db6f35405c9cb..7c5132695a1696e8a09173ea28434cf997e3990b 100644 (file)
@@ -741,6 +741,9 @@ managed_proxy_destroy(managed_proxy_t *mp,
   /* free the outgoing proxy URI */
   tor_free(mp->proxy_uri);
 
+  /* free our version, if any is set. */
+  tor_free(mp->version);
+
   /* do we want to terminate our process if it's still running? */
   if (also_terminate_process && mp->process) {
     /* Note that we do not call process_free(mp->process) here because we let
@@ -1293,6 +1296,9 @@ parse_status_line(const char *line, managed_proxy_t *mp)
     goto done;
   }
 
+  /* Handle the different messages. */
+  handle_status_message(values, mp);
+
   /* Prepend the PT name. */
   config_line_prepend(&values, "PT", mp->argv[0]);
   status_message = kvline_encode(values, KV_QUOTED);
@@ -1306,6 +1312,36 @@ parse_status_line(const char *line, managed_proxy_t *mp)
   tor_free(status_message);
 }
 
+STATIC void
+handle_status_message(const config_line_t *values,
+                      managed_proxy_t *mp)
+{
+  const config_line_t *message_type = config_line_find(values, "TYPE");
+
+  /* Check if we have a TYPE field? */
+  if (message_type == NULL) {
+    log_debug(LD_PT, "Managed proxy \"%s\" wrote a STATUS line without "
+                     "a defined message TYPE", mp->argv[0]);
+    return;
+  }
+
+  /* Handle VERSION messages. */
+  if (! strcasecmp(message_type->value, "version")) {
+    const config_line_t *version = config_line_find(values, "VERSION");
+
+    if (version == NULL) {
+      log_warn(LD_PT, "Managed proxy \"%s\" wrote a STATUS TYPE=version line "
+                      "with a missing VERSION field", mp->argv[0]);
+      return;
+    }
+
+    tor_free(mp->version);
+    mp->version = tor_strdup(version->value);
+
+    return;
+  }
+}
+
 /** Return a newly allocated string that tor should place in
  * TOR_PT_SERVER_TRANSPORT_OPTIONS while configuring the server
  * manged proxy in <b>mp</b>. Return NULL if no such options are found. */
index 535689537c16bbf279cac0d0c055f928bec8a621..1f6c10961d180f3f96c76e1777635d9154dc5125 100644 (file)
@@ -114,11 +114,16 @@ typedef struct {
   /* transports to-be-launched by this proxy */
   smartlist_t *transports_to_launch;
 
+  /** Version as set by STATUS TYPE=version messages. */
+  char *version;
+
   /* The 'transports' list contains all the transports this proxy has
      launched. */
   smartlist_t *transports;
 } managed_proxy_t;
 
+struct config_line_t;
+
 STATIC transport_t *transport_new(const tor_addr_t *addr, uint16_t port,
                                   const char *name, int socks_ver,
                                   const char *extra_info_args);
@@ -131,6 +136,8 @@ STATIC void parse_proxy_error(const char *line);
 STATIC void handle_proxy_line(const char *line, managed_proxy_t *mp);
 STATIC void parse_log_line(const char *line, managed_proxy_t *mp);
 STATIC void parse_status_line(const char *line, managed_proxy_t *mp);
+STATIC void handle_status_message(const struct config_line_t *values,
+                                  managed_proxy_t *mp);
 STATIC char *get_transport_options_for_server_proxy(const managed_proxy_t *mp);
 
 STATIC void managed_proxy_destroy(managed_proxy_t *mp,
index 07c5032933034d7935e751ad4c867f77c22e51ab..e97b0b2087f915a6ff587c53e7d2b26d3c255947 100644 (file)
@@ -142,6 +142,40 @@ test_pt_parsing(void *arg)
   tor_free(mp);
 }
 
+static void
+test_pt_status_parsing(void *arg)
+{
+  char line[200];
+  char *test_binary = tor_strdup("test-pt");
+  char *argv[] = {
+    test_binary,
+    NULL,
+  };
+
+  managed_proxy_t *mp = tor_malloc_zero(sizeof(managed_proxy_t));
+  (void)arg;
+  mp->conf_state = PT_PROTO_INFANT;
+  mp->transports = smartlist_new();
+  mp->argv = argv;
+
+  /* STATUS TYPE=version messages. */
+  tt_ptr_op(mp->version, OP_EQ, NULL);
+  strlcpy(line, "STATUS TRANSPORT=x "
+                "TYPE=version "
+                "VERSION=\"1.33.7-hax beta\"",
+                sizeof(line));
+  handle_proxy_line(line, mp);
+  tt_str_op(mp->version, OP_EQ, "1.33.7-hax beta");
+
+  reset_mp(mp);
+
+ done:
+  reset_mp(mp);
+  smartlist_free(mp->transports);
+  tor_free(mp);
+  tor_free(test_binary);
+}
+
 static void
 test_pt_get_transport_options(void *arg)
 {
@@ -590,6 +624,7 @@ test_get_pt_proxy_uri(void *arg)
 
 struct testcase_t pt_tests[] = {
   PT_LEGACY(parsing),
+  PT_LEGACY(status_parsing),
   PT_LEGACY(protocol),
   { "get_transport_options", test_pt_get_transport_options, TT_FORK,
     NULL, NULL },