don't drop privileges if _apt has not enough rights
Privilege dropping breaks download/source/changelog commands as they
require the _apt user to have write permissions in the current directory,
which is e.g. the case in /tmp, but not in /root, so we disable the
privilege dropping if we deal with such a directory based on idea and
code by Michael Vogt.
The alternative would be to download always to a temp directory and move
it then done, but this breaks partial file support. To resolve this, we
could move to one of our partial/ directories, but this would require a
lock which would block root from using two of these commands in
parallel. As both seems unacceptable we instead let the user choose what
to do: Either a directory is setupped for _apt, downloading as root is
accepted or – which is potentially even better – an unprivileged user is
used for the commands.
Michael Vogt [Tue, 14 Oct 2014 15:00:56 +0000 (17:00 +0200)]
Add new configallowinsecurerepositories to the test framework
Add a new configallowinsecurerepositories that controls the value
of Acquire::AllowInsecureRepositories for the tests. Set it to
"false" for most of the testsuite and only enable it where its
really needed. We want to switch the default for this post-jessie.
do not load filesize in pkgAcqIndexTrans explicitly
The constructor is calling the baseclass pkgAcqIndex which does this
already – and also does it correctly for compressed files which would
overwise lead to the size of uncompressed files to be expected.
Michael Vogt [Mon, 13 Oct 2014 08:57:30 +0000 (10:57 +0200)]
Fix backward compatiblity of the new pkgAcquireMethod::DropPrivsOrDie()
Do not drop privileges in the methods when using a older version of
libapt that does not support the chown magic in partial/ yet. To
do this DropPrivileges() now will ignore a empty Apt::Sandbox::User.
trusted=yes sources are secure, we just don't know why
Do not require a special flag to be present to update trusted=yes
sources as this flag in the sources.list is obviously special enough.
Note that this is just disabling the error message, the user will still
be warned about all the (possible) failures the repository generated, it
is just triggering the acceptance of the warnings on a source-by-source
level.
Similarily, the trusted=no flag doesn't require the user to pass
additional flags to update, if the repository looks fine in the view of
apt it will update just fine. The unauthenticated warnings will "just" be
presented then the data is used.
In case you wonder: Both was the behavior in previous versions, too.
Reimplementing an inline method is opening a can of worms we don't want
to open if we ever want to us a d-pointer in those classes, so we do the
only thing which can save us from hell: move the destructors into the cc
sources and we are good.
Technically not an ABI break as the methods inline or not do the same
(nothing), so a program compiled against the old version still works
with the new version (beside that this version is still in experimental,
so nothing really has been build against this library anyway).
The same message is used for InRelease if fails in gpgv, but the
Release/Release.gpg duo needs to handle the failing download case as
well (InRelease just defers to the duo if download fails) and print a
message accompaning the insecure error to provide a hint on what is
going on.
make --allow-insecure-repositories message an error
Not using this option, but using unsigned (and co) repositories will
cause these repositories to be ignored and data acquiring from them
fails, so this is very well in the realms of an error and helps in
making 'apt-get update' fail with a non-zero error code as well.
Michael Vogt [Wed, 8 Oct 2014 18:13:56 +0000 (20:13 +0200)]
Only rename StatError files in AbortTransaction()
This fixes a race that we see in travis when two copy operations
finish at about the same time but the bad one first. This lead to
a rename of the good one and triggers a error when apt tries to
verify the good version but can no longer find it.
Remove long obsolete (hold, hold-reinstreq, removal-failed) or just
wrong (post-inst-failed vs postinst-failed) values, that have been
autoconverted by dpkg at run-time to their new equivalents, so there
should not be any such instance in any recent system (removal-failed
since dpkg 1.1.4 in Apr 1996, hold and hold-reinstreq since dpkg
1.2.0 in May 1996). dpkg even stopped doing the mapping in 1.15.4
and 1.15.8 respectively.
At the same time sort the list in the same order as they appear in
the dpkg code.
Michael Vogt [Wed, 8 Oct 2014 06:32:42 +0000 (08:32 +0200)]
Fix http pipeline messup detection
The Maximum-Size protection breaks the http pipeline reorder code
because it relies on that the object got fetched entirely so that
it can compare the hash of the downloaded data. So instead of
stopping when the Maximum-Size of the expected item is reached we
only stop when the maximum size of the biggest item in the queue
is reached. This way the pipeline reoder code keeps working.
On travis-ci connect.cc detects a rotation, triggering it store the IP
which is later appended to the error message, which is all nice and
great if we deal with a real server, but in the testcases it just
triggers failures as strings do not match.
Changing user and co works only as root, but can do some things for
methods run as normal user as well to protect them from being able to
call setuid binaries like sudo to elevate their privileges.
Also uses a cheap trick now to build with old unsupporting kernels.
Some distributions (or repositories) do not have as much
"Ign-discipline" as I would like to, so that could be pretty distracting
for our users if enabled by default. It is handy for testcases though.
Michael Vogt [Tue, 7 Oct 2014 18:40:37 +0000 (20:40 +0200)]
Add new Acquire::MaxReleaseFileSize=10*1000*1000 option
This option controls the maximum size of Release/Release.gpg/InRelease
files. The rational is that we do not know the size of these files in
advance and we want to protect against a denial of service attack
where someone sends us endless amounts of data until the disk is full
(we do know the size all other files (Packages/Sources/debs)).
Michael Vogt [Tue, 7 Oct 2014 11:34:28 +0000 (13:34 +0200)]
Ignore EINVAL from prctl(PR_SET_NO_NEW_PRIVS)
Ignore a EINVAL error here as it means that the kernel is too old
to understand this option. We should not fail hard in this case
but just ignore the error.
consistently using Item::Failed in all specializec classes helps setting
up some information bits otherwise unset, so some errors had an empty
reason as an error. Ign is upgraded to display the error message we
ignored to further help in understanding what happens.
Using a different user for calling methods is intended to protect us
from methods running amok (via remotely exploited bugs) by limiting what
can be done by them. By using root:root for the final directories and
just have the files in partial writeable by the methods we enhance this
in sofar as a method can't modify already verified data in its parent
directory anymore.
As a side effect, this also clears most of the problems you could have
if the final directories are shared without user-sharing or if these
directories disappear as they are now again root owned and only the
partial directories contain _apt owned files (usually none if apt isn't
running) and the directory itself is autocreated with the right
permissions.
ensure partial dirs are 0700 and owned by _apt:root
Reworks the API involved in creating and setting up the fetcher to be a
bit more pleasent to look at and work with as e.g. an empty string for
no lock isn't very nice. With the lock we can also stop creating all our
partial directories "just in case". This way we can also be a bit more
aggressive with the partial directory itself as with a lock, we know we
will gone need it.
Guillem Jover [Thu, 2 Oct 2014 15:48:13 +0000 (17:48 +0200)]
apt-get: Create the temporary downloaded changelog inside tmpdir
The code is creating a secure temporary directory, but then creates
the changelog alongside the tmpdir in the same base directory. This
defeats the secure tmpdir creation, making the filename predictable.
Inject a '/' between the tmpdir and the changelog filename.
Having it in the header exposes some implementation details, namely
private methods and will cause problems for us if we ever want to change
the actions.
Guillem Jover [Thu, 2 Oct 2014 15:48:13 +0000 (17:48 +0200)]
apt-get: Create the temporary downloaded changelog inside tmpdir
The code is creating a secure temporary directory, but then creates
the changelog alongside the tmpdir in the same base directory. This
defeats the secure tmpdir creation, making the filename predictable.
Inject a '/' between the tmpdir and the changelog filename.
ensure world-readability for trusted.gpg in postinst
apt-key creates trusted.gpg if it needs it with 644 nowadays, but before
it ensured this, it was gpg creating it, which gives it by default 600.
Not a problem as long as our gpgv is run as root, but now that we drop
privileges we have to ensure that we can also read trusted.gpg files
created by earlier apt-key versions.
Michael Vogt [Wed, 1 Oct 2014 10:21:55 +0000 (12:21 +0200)]
Use Acquire::Allow{InsecureRepositories,DowngradeToInsecureRepositories}
The configuration key Acquire::AllowInsecureRepositories controls if
apt allows loading of unsigned repositories at all.
The configuration Acquire::AllowDowngradeToInsecureRepositories
controls if a signed repository can ever become unsigned. This
should really never be needed but we provide it to avoid having
to mess around in /var/lib/apt/lists if there is a use-case for
this (which I can't think of right now).
The fileformat of a pdiff index stores currently only SHA1 hashes. With
this change, we look for all other hashes we support as well and take
what we get, so that we can work after the release of jessie to get
right of SHA1 if we want to.
Note that the completely patched file is and was checked against the
hashes collected from the Release file, so this transition isn't mission
critical.
We are the only possible users of private methods, so we are also the
only users who can potentially export them via using them in inline
methods. The point is: We don't need these symbols exported if we don't
do this, so marking them as hidden removes some methods from the API
without breaking anything as nobody could have used them.