dirmngr: Forbid redirects from .onion to clearnet URIs.
authorJustus Winter <justus@g10code.com>
Wed, 19 Jul 2017 14:02:05 +0000 (16:02 +0200)
committerJustus Winter <justus@g10code.com>
Wed, 19 Jul 2017 15:02:25 +0000 (17:02 +0200)
* dirmngr/ks-engine-hkp.c (send_request): Forbid redirects from .onion
to clearnet URIs.
* dirmngr/ks-engine-http.c (ks_http_fetch): Likewise.
--
This protects users from misconfigured .onion services.

GnuPG-bug-id: 3087
Signed-off-by: Justus Winter <justus@g10code.com>
dirmngr/ks-engine-hkp.c
dirmngr/ks-engine-http.c

index aa98b37..4a0b08f 100644 (file)
@@ -1162,9 +1162,16 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
   int redirects_left = MAX_REDIRECTS;
   estream_t fp = NULL;
   char *request_buffer = NULL;
+  parsed_uri_t uri = NULL;
+  int is_onion;
 
   *r_fp = NULL;
 
+  err = http_parse_uri (&uri, request, 0);
+  if (err)
+    goto leave;
+  is_onion = uri->onion;
+
   err = http_session_new (&session, httphost,
                           ((ctrl->http_no_crl? HTTP_FLAG_NO_CRL : 0)
                            | HTTP_FLAG_TRUST_DEF),
@@ -1250,6 +1257,23 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
                   request, s?s:"[none]", http_get_status_code (http));
         if (s && *s && redirects_left-- )
           {
+            if (is_onion)
+              {
+                /* Make sure that an onion address only redirects to
+                 * another onion address.  */
+                http_release_parsed_uri (uri);
+                uri = NULL;
+                err = http_parse_uri (&uri, s, 0);
+                if (err)
+                  goto leave;
+
+                if (! uri->onion)
+                  {
+                    err = gpg_error (GPG_ERR_FORBIDDEN);
+                    goto leave;
+                  }
+              }
+
             xfree (request_buffer);
             request_buffer = xtrystrdup (s);
             if (request_buffer)
@@ -1298,6 +1322,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
   http_close (http, 0);
   http_session_release (session);
   xfree (request_buffer);
+  http_release_parsed_uri (uri);
   return err;
 }
 
index 95fa34c..7fb7731 100644 (file)
@@ -72,6 +72,13 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
   int redirects_left = MAX_REDIRECTS;
   estream_t fp = NULL;
   char *request_buffer = NULL;
+  parsed_uri_t uri = NULL;
+  int is_onion;
+
+  err = http_parse_uri (&uri, url, 0);
+  if (err)
+    goto leave;
+  is_onion = uri->onion;
 
  once_more:
   /* Note that we only use the system provided certificates with the
@@ -145,6 +152,23 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
                   url, s?s:"[none]", http_get_status_code (http));
         if (s && *s && redirects_left-- )
           {
+            if (is_onion)
+              {
+                /* Make sure that an onion address only redirects to
+                 * another onion address.  */
+                http_release_parsed_uri (uri);
+                uri = NULL;
+                err = http_parse_uri (&uri, s, 0);
+                if (err)
+                  goto leave;
+
+                if (! uri->onion)
+                  {
+                    err = gpg_error (GPG_ERR_FORBIDDEN);
+                    goto leave;
+                  }
+              }
+
             xfree (request_buffer);
             request_buffer = xtrystrdup (s);
             if (request_buffer)
@@ -186,5 +210,6 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
   http_close (http, 0);
   http_session_release (session);
   xfree (request_buffer);
+  http_release_parsed_uri (uri);
   return err;
 }