]> git.saurik.com Git - apt.git/commitdiff
block direct connections to .onion domains (RFC7687)
authorDavid Kalnischkies <david@kalnischkies.de>
Sat, 6 Aug 2016 11:53:05 +0000 (13:53 +0200)
committerDavid Kalnischkies <david@kalnischkies.de>
Wed, 10 Aug 2016 23:34:39 +0000 (01:34 +0200)
Doing a direct connect to an .onion address (if you don't happen to use
it as a local domain, which you shouldn't) is bound to fail and does
leak the information that you do use Tor and which hidden service you
wanted to connect to to a DNS server. Worse, if the DNS is poisoned and
actually resolves tricking a user into believing the setup would work
correctly…

This does block also the usage of wrappers like torsocks with apt, but
with native support available and advertised in the error message this
shouldn't really be an issue.

Inspired-by: https://bugzilla.mozilla.org/show_bug.cgi?id=1228457
methods/connect.cc
test/integration/test-method-connect [new file with mode: 0755]

index f768169d1aceec08cb8d7a1458ccfcd80dc82ed2..c819c1dfb01886bd09976d76ee98aa240c71ac34 100644 (file)
@@ -61,10 +61,23 @@ void RotateDNS()
       LastUsed = LastHostAddr;
 }
                                                                        /*}}}*/
+static bool ConnectionAllowed(char const * const Service, std::string const &Host)/*{{{*/
+{
+   if (APT::String::Endswith(Host, ".onion") && _config->FindB("Acquire::BlockDotOnion", true))
+   {
+      // TRANSLATOR: %s is e.g. Tor's ".onion" which would likely fail or leak info (RFC7686)
+      _error->Error(_("Direct connection to %s domains is blocked by default."), ".onion");
+      if (strcmp(Service, "http") == 0)
+       _error->Error(_("If you meant to use Tor remember to use %s instead of %s."), "tor+http", "http");
+      return false;
+   }
+   return true;
+}
+                                                                       /*}}}*/
 // DoConnect - Attempt a connect operation                             /*{{{*/
 // ---------------------------------------------------------------------
 /* This helper function attempts a connection to a single address. */
-static bool DoConnect(struct addrinfo *Addr,std::string Host,
+static bool DoConnect(struct addrinfo *Addr,std::string const &Host,
                      unsigned long TimeOut,int &Fd,pkgAcqMethod *Owner)
 {
    // Show a status indicator
@@ -138,6 +151,8 @@ static bool ConnectToHostname(std::string const &Host, int const Port,
       const char * const Service, int DefPort, int &Fd,
       unsigned long const TimeOut, pkgAcqMethod * const Owner)
 {
+   if (ConnectionAllowed(Service, Host) == false)
+      return false;
    // Convert the port name/number
    char ServStr[300];
    if (Port != 0)
@@ -274,6 +289,9 @@ bool Connect(std::string Host,int Port,const char *Service,
    if (_error->PendingError() == true)
       return false;
 
+   if (ConnectionAllowed(Service, Host) == false)
+      return false;
+
    if(LastHost != Host || LastPort != Port)
    {
       SrvRecords.clear();
diff --git a/test/integration/test-method-connect b/test/integration/test-method-connect
new file mode 100755 (executable)
index 0000000..b35f96d
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/sh
+set -e
+
+TESTDIR="$(readlink -f "$(dirname "$0")")"
+. "$TESTDIR/framework"
+
+setupenvironment
+
+cd downloaded
+testfailureequal 'Err:1 http://vwakviie2ienjx6t.onion/
+  Direct connection to .onion domains is blocked by default. If you meant to use Tor remember to use tor+http instead of http.
+E: Failed to fetch http://vwakviie2ienjx6t.onion/  Direct connection to .onion domains is blocked by default. If you meant to use Tor remember to use tor+http instead of http.
+E: Download Failed' apthelper download-file 'http://vwakviie2ienjx6t.onion/' ftp.debian.org.html