]> git.saurik.com Git - apt.git/commitdiff
allow methods to be disabled and redirected via config
authorDavid Kalnischkies <david@kalnischkies.de>
Sat, 6 Aug 2016 17:59:57 +0000 (19:59 +0200)
committerDavid Kalnischkies <david@kalnischkies.de>
Wed, 10 Aug 2016 21:19:44 +0000 (23:19 +0200)
To prevent accidents like adding http-sources while using tor+http it
can make sense to allow disabling methods. It might even make sense to
allow "redirections" and adding "symlinked" methods via configuration.
This could e.g. allow using different options for certain sources by
adding and configuring a "virtual" new method which picks up the config
based on the name it was called with like e.g. http does if called as
tor+http.

apt-pkg/acquire-worker.cc
test/integration/test-apt-https-no-redirect
test/integration/test-apt-update-failure-propagation
test/integration/test-bug-738785-switch-protocol
test/integration/test-different-methods-for-same-source

index 1ee78d07031a7dbe226c550e6a251d3e45a78b8f..7a4f8177fa609eaa9ef3a14d0a13f2ffee5c547d 100644 (file)
@@ -93,9 +93,22 @@ pkgAcquire::Worker::~Worker()
 bool pkgAcquire::Worker::Start()
 {
    // Get the method path
 bool pkgAcquire::Worker::Start()
 {
    // Get the method path
-   string Method = _config->FindDir("Dir::Bin::Methods") + Access;
+   constexpr char const * const methodsDir = "Dir::Bin::Methods";
+   std::string const confItem = std::string(methodsDir) + "::" + Access;
+   std::string Method;
+   if (_config->Exists(confItem))
+        Method = _config->FindFile(confItem.c_str());
+   else
+        Method = _config->FindDir(methodsDir) + Access;
    if (FileExists(Method) == false)
    {
    if (FileExists(Method) == false)
    {
+      if (flNotDir(Method) == "false")
+      {
+        _error->Error(_("The method '%s' is explicitly disabled via configuration."), Access.c_str());
+        if (Access == "http" || Access == "https")
+           _error->Notice(_("If you meant to use Tor remember to use %s instead of %s."), ("tor+" + Access).c_str(), Access.c_str());
+        return false;
+      }
       _error->Error(_("The method driver %s could not be found."),Method.c_str());
       std::string const A(Access.cbegin(), std::find(Access.cbegin(), Access.cend(), '+'));
       std::string pkg;
       _error->Error(_("The method driver %s could not be found."),Method.c_str());
       std::string const A(Access.cbegin(), std::find(Access.cbegin(), Access.cend(), '+'));
       std::string pkg;
@@ -103,9 +116,15 @@ bool pkgAcquire::Worker::Start()
       _error->Notice(_("Is the package %s installed?"), pkg.c_str());
       return false;
    }
       _error->Notice(_("Is the package %s installed?"), pkg.c_str());
       return false;
    }
+   std::string const Calling = _config->FindDir(methodsDir) + Access;
 
    if (Debug == true)
 
    if (Debug == true)
-      clog << "Starting method '" << Method << '\'' << endl;
+   {
+      std::clog << "Starting method '" << Calling << "'";
+      if (Calling != Method)
+        std::clog << " ( via " << Method << " )";
+      std::clog << endl;
+   }
 
    // Create the pipes
    int Pipes[4] = {-1,-1,-1,-1};
 
    // Create the pipes
    int Pipes[4] = {-1,-1,-1,-1};
@@ -130,11 +149,9 @@ bool pkgAcquire::Worker::Start()
       SetCloseExec(STDIN_FILENO,false);
       SetCloseExec(STDERR_FILENO,false);
 
       SetCloseExec(STDIN_FILENO,false);
       SetCloseExec(STDERR_FILENO,false);
 
-      const char *Args[2];
-      Args[0] = Method.c_str();
-      Args[1] = 0;
-      execv(Args[0],(char **)Args);
-      cerr << "Failed to exec method " << Args[0] << endl;
+      const char * const Args[] = { Calling.c_str(), nullptr };
+      execv(Method.c_str() ,const_cast<char **>(Args));
+      std::cerr << "Failed to exec method " << Calling << " ( via " << Method << ")" << endl;
       _exit(100);
    }
 
       _exit(100);
    }
 
index 69e2ba57f3ba497e036f81b418d432b81c9da7a5..d6c630d5fda8c717efc8d438d6374ebfc7548b0a 100755 (executable)
@@ -14,6 +14,7 @@ echo 'alright' > aptarchive/working
 changetohttpswebserver
 webserverconfig 'aptwebserver::redirect::replace::/redirectme/' "http://localhost:${APTHTTPPORT}/"
 webserverconfig 'aptwebserver::redirect::replace::/redirectme2/' "https://localhost:${APTHTTPSPORT}/"
 changetohttpswebserver
 webserverconfig 'aptwebserver::redirect::replace::/redirectme/' "http://localhost:${APTHTTPPORT}/"
 webserverconfig 'aptwebserver::redirect::replace::/redirectme2/' "https://localhost:${APTHTTPSPORT}/"
+echo 'Dir::Bin::Methods::https+http "https";' > rootdir/etc/apt/apt.conf.d/99add-https-http-method
 
 msgtest 'download of a file works via' 'http'
 testsuccess --nomsg downloadfile "http://localhost:${APTHTTPPORT}/working" httpfile
 
 msgtest 'download of a file works via' 'http'
 testsuccess --nomsg downloadfile "http://localhost:${APTHTTPPORT}/working" httpfile
@@ -22,9 +23,23 @@ testfileequal httpfile 'alright'
 msgtest 'download of a file works via' 'https'
 testsuccess --nomsg downloadfile "https://localhost:${APTHTTPSPORT}/working" httpsfile
 testfileequal httpsfile 'alright'
 msgtest 'download of a file works via' 'https'
 testsuccess --nomsg downloadfile "https://localhost:${APTHTTPSPORT}/working" httpsfile
 testfileequal httpsfile 'alright'
+rm -f httpfile httpsfile
+
+msgtest 'download of http file works via' 'https+http'
+testsuccess --nomsg downloadfile "http://localhost:${APTHTTPPORT}/working" httpfile
+testfileequal httpfile 'alright'
+
+msgtest 'download of https file works via' 'https+http'
+testsuccess --nomsg downloadfile "https://localhost:${APTHTTPSPORT}/working" httpsfile
+testfileequal httpsfile 'alright'
+rm -f httpfile httpsfile
 
 msgtest 'download of a file does not work if' 'https redirected to http'
 testfailure --nomsg downloadfile "https://localhost:${APTHTTPSPORT}/redirectme/working" redirectfile
 
 msgtest 'libcurl has forbidden access in last request to' 'http resource'
 testsuccess --nomsg grep -q -E -- "Redirection from https to 'http://.*' is forbidden" rootdir/tmp/testfailure.output
 
 msgtest 'download of a file does not work if' 'https redirected to http'
 testfailure --nomsg downloadfile "https://localhost:${APTHTTPSPORT}/redirectme/working" redirectfile
 
 msgtest 'libcurl has forbidden access in last request to' 'http resource'
 testsuccess --nomsg grep -q -E -- "Redirection from https to 'http://.*' is forbidden" rootdir/tmp/testfailure.output
+
+msgtest 'download of a file does work if' 'https+http redirected to https'
+testsuccess --nomsg downloadfile "https+http://localhost:${APTHTTPPORT}/redirectme2/working" redirectfile
+testfileequal redirectfile 'alright'
index ec6bf4a48bcaf50cfbcf4384505ed1f4301d05d4..1361b1b9339bca4bfaaf084881a48f291a6276a9 100755 (executable)
@@ -27,10 +27,11 @@ for FILE in rootdir/etc/apt/sources.list.d/*-sid-* ; do
 done
 
 pretest() {
 done
 
 pretest() {
+       msgmsg "$@"
        rm -rf rootdir/var/lib/apt/lists
        testsuccessequal 'N: Unable to locate package foo' aptcache policy foo
 }
        rm -rf rootdir/var/lib/apt/lists
        testsuccessequal 'N: Unable to locate package foo' aptcache policy foo
 }
-pretest
+pretest 'initialize test' 'update'
 testsuccess aptget update
 testsuccessequal "foo:
   Installed: (none)
 testsuccess aptget update
 testsuccessequal "foo:
   Installed: (none)
@@ -41,7 +42,7 @@ testsuccessequal "foo:
      1 500
         500 https://localhost:${APTHTTPSPORT} stable/main all Packages" aptcache policy foo
 
      1 500
         500 https://localhost:${APTHTTPSPORT} stable/main all Packages" aptcache policy foo
 
-pretest
+pretest 'not found' 'release files'
 mv aptarchive/dists/stable aptarchive/dists/stable.good
 testfailuremsg "E: The repository 'https://localhost:${APTHTTPSPORT} stable Release' does not have a Release file.
 N: Updating from such a repository can't be done securely, and is therefore disabled by default.
 mv aptarchive/dists/stable aptarchive/dists/stable.good
 testfailuremsg "E: The repository 'https://localhost:${APTHTTPSPORT} stable Release' does not have a Release file.
 N: Updating from such a repository can't be done securely, and is therefore disabled by default.
@@ -76,7 +77,16 @@ posttest() {
 }
 posttest
 
 }
 posttest
 
-pretest
+pretest 'method disabled' 'https'
+echo 'Dir::Bin::Methods::https "false";' > rootdir/etc/apt/apt.conf.d/99disable-https
+testfailuremsg "E: The method 'https' is explicitly disabled via configuration.
+N: If you meant to use Tor remember to use tor+https instead of https.
+E: Failed to fetch https://localhost:${APTHTTPSPORT}/dists/stable/InRelease  
+E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update
+rm -f rootdir/etc/apt/apt.conf.d/99disable-https
+posttest
+
+pretest 'method not installed' 'https'
 rm "${NEWMETHODS}/https"
 testfailuremsg "E: The method driver ${TMPWORKINGDIRECTORY}/rootdir/usr/lib/apt/methods/https could not be found.
 N: Is the package apt-transport-https installed?
 rm "${NEWMETHODS}/https"
 testfailuremsg "E: The method driver ${TMPWORKINGDIRECTORY}/rootdir/usr/lib/apt/methods/https could not be found.
 N: Is the package apt-transport-https installed?
@@ -84,13 +94,12 @@ E: Failed to fetch https://localhost:${APTHTTPSPORT}/dists/stable/InRelease
 E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update
 posttest
 
 E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update
 posttest
 
-ln -s "$OLDMETHODS/https" "$NEWMETHODS"
-pretest
+pretest 'https connection refused' 'doom port'
 for FILE in rootdir/etc/apt/sources.list.d/*-stable-* ; do
        # lets see how many testservers run also Doom
        sed -i -e "s#:${APTHTTPSPORT}/#:666/#" "$FILE"
 done
 for FILE in rootdir/etc/apt/sources.list.d/*-stable-* ; do
        # lets see how many testservers run also Doom
        sed -i -e "s#:${APTHTTPSPORT}/#:666/#" "$FILE"
 done
-testwarning aptget update
+testwarning aptget update -o Dir::Bin::Methods::https="${OLDMETHODS}/https"
 testequalor2 "W: Failed to fetch https://localhost:666/dists/stable/InRelease  Failed to connect to localhost port 666: Connection refused
 W: Some index files failed to download. They have been ignored, or old ones used instead." "W: Failed to fetch https://localhost:666/dists/stable/InRelease  couldn't connect to host
 W: Some index files failed to download. They have been ignored, or old ones used instead." tail -n 2 rootdir/tmp/testwarning.output
 testequalor2 "W: Failed to fetch https://localhost:666/dists/stable/InRelease  Failed to connect to localhost port 666: Connection refused
 W: Some index files failed to download. They have been ignored, or old ones used instead." "W: Failed to fetch https://localhost:666/dists/stable/InRelease  couldn't connect to host
 W: Some index files failed to download. They have been ignored, or old ones used instead." tail -n 2 rootdir/tmp/testwarning.output
index fa6702eb07040a5bf165b20828aab14876ccc243..690e8727ed6067333cb1abbae3cbd1a4bbe7e894 100755 (executable)
@@ -38,28 +38,12 @@ cd - >/dev/null
 testsuccess aptget install apt -y
 testdpkginstalled 'apt'
 
 testsuccess aptget install apt -y
 testdpkginstalled 'apt'
 
-# install a slowed down file: otherwise its to fast to reproduce combining
-NEWMETHODS="$(readlink -f rootdir)/usr/lib/apt/methods"
-OLDMETHODS="$(readlink -f rootdir/usr/lib/apt/methods)"
-rm "$NEWMETHODS"
-mkdir "$NEWMETHODS"
-backupIFS="$IFS"
-IFS="$(printf "\n\b")"
-for METH in $(find "$OLDMETHODS" -maxdepth 1 ! -type d); do
-       ln -s "$OLDMETHODS/$(basename "$METH")" "$NEWMETHODS"
-done
-IFS="$backupIFS"
-rm "$NEWMETHODS/https"
-
 cd downloaded
 cd downloaded
-testfailureequal "E: The method driver $(readlink -f './../')/rootdir/usr/lib/apt/methods/https could not be found.
-N: Is the package apt-transport-https installed?" aptget download apt
+testfailureequal "E: The method 'https' is explicitly disabled via configuration.
+N: If you meant to use Tor remember to use tor+https instead of https." aptget download apt -o Dir::Bin::Methods::https=false
 testfailure test -e apt_1.0_all.deb
 cd - >/dev/null
 
 testfailure test -e apt_1.0_all.deb
 cd - >/dev/null
 
-# revert to all methods
-ln -s "$OLDMETHODS/https" "$NEWMETHODS"
-
 # check that downgrades from https to http are not allowed
 webserverconfig 'aptwebserver::support::http' 'true'
 sed -i -e "s#:${APTHTTPPORT}/redirectme#:${APTHTTPSPORT}/downgrademe#" -e 's# http:# https:#' rootdir/etc/apt/sources.list.d/*
 # check that downgrades from https to http are not allowed
 webserverconfig 'aptwebserver::support::http' 'true'
 sed -i -e "s#:${APTHTTPPORT}/redirectme#:${APTHTTPSPORT}/downgrademe#" -e 's# http:# https:#' rootdir/etc/apt/sources.list.d/*
index 40138ad5db108d190889c49001ef6a597276c5a6..791a84cb7e2bf9ad12db28d6f559d064a9e5d9b7 100755 (executable)
@@ -10,21 +10,10 @@ insertpackage 'stable' 'foo' 'all' '1'
 insertsource 'stable' 'foo' 'all' '1'
 setupaptarchive --no-update
 
 insertsource 'stable' 'foo' 'all' '1'
 setupaptarchive --no-update
 
-# install a slowed down file: otherwise its to fast to reproduce combining
-NEWMETHODS="$(readlink -f rootdir)/usr/lib/apt/methods"
-OLDMETHODS="$(readlink -f rootdir/usr/lib/apt/methods)"
-rm "$NEWMETHODS"
-mkdir "$NEWMETHODS"
-backupIFS="$IFS"
-IFS="$(printf "\n\b")"
-for METH in $(find "$OLDMETHODS" -maxdepth 1 ! -type d); do
-       ln -s "$OLDMETHODS/$(basename "$METH")" "$NEWMETHODS"
-done
-IFS="$backupIFS"
-ln -s "${OLDMETHODS}/http" "${NEWMETHODS}/http-ng"
-
 changetowebserver
 webserverconfig 'aptwebserver::redirect::replace::/redirectme/' "http://localhost:${APTHTTPPORT}/"
 changetowebserver
 webserverconfig 'aptwebserver::redirect::replace::/redirectme/' "http://localhost:${APTHTTPPORT}/"
+
+echo 'Dir::Bin::Methods::http-ng "http";' > rootdir/etc/apt/apt.conf.d/99add-http-ng-method
 sed -i -e 's# http:# http-ng:#' $(find rootdir/etc/apt/sources.list.d -name '*-deb-src.list')
 
 testsuccess apt update -o Debug::Acquire::http-ng=1
 sed -i -e 's# http:# http-ng:#' $(find rootdir/etc/apt/sources.list.d -name '*-deb-src.list')
 
 testsuccess apt update -o Debug::Acquire::http-ng=1