Browse Source

allow methods to be disabled and redirected via config

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.
tags/debian/1.3_rc1
David Kalnischkies 4 years ago
parent
commit
c9c9106951
5 changed files with 58 additions and 44 deletions
  1. +24
    -7
      apt-pkg/acquire-worker.cc
  2. +15
    -0
      test/integration/test-apt-https-no-redirect
  3. +15
    -6
      test/integration/test-apt-update-failure-propagation
  4. +2
    -18
      test/integration/test-bug-738785-switch-protocol
  5. +2
    -13
      test/integration/test-different-methods-for-same-source

+ 24
- 7
apt-pkg/acquire-worker.cc View File

@@ -93,9 +93,22 @@ pkgAcquire::Worker::~Worker()
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 (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;
@@ -103,9 +116,15 @@ bool pkgAcquire::Worker::Start()
_error->Notice(_("Is the package %s installed?"), pkg.c_str());
return false;
}
std::string const Calling = _config->FindDir(methodsDir) + Access;

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};
@@ -130,11 +149,9 @@ bool pkgAcquire::Worker::Start()
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);
}



+ 15
- 0
test/integration/test-apt-https-no-redirect View File

@@ -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}/"
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
@@ -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'
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 work if' 'https+http redirected to https'
testsuccess --nomsg downloadfile "https+http://localhost:${APTHTTPPORT}/redirectme2/working" redirectfile
testfileequal redirectfile 'alright'

+ 15
- 6
test/integration/test-apt-update-failure-propagation View File

@@ -27,10 +27,11 @@ for FILE in rootdir/etc/apt/sources.list.d/*-sid-* ; do
done

pretest() {
msgmsg "$@"
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)
@@ -41,7 +42,7 @@ testsuccessequal "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.
@@ -76,7 +77,16 @@ 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?
@@ -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

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
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


+ 2
- 18
test/integration/test-bug-738785-switch-protocol View File

@@ -38,28 +38,12 @@ cd - >/dev/null
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
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

# 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/*


+ 2
- 13
test/integration/test-different-methods-for-same-source View File

@@ -10,21 +10,10 @@ insertpackage 'stable' 'foo' 'all' '1'
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}/"

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


Loading…
Cancel
Save