diff options
| author | Julian Andres Klode <jak@debian.org> | 2024-11-28 18:25:02 +0000 |
|---|---|---|
| committer | Julian Andres Klode <jak@debian.org> | 2024-11-28 18:25:02 +0000 |
| commit | 46e45bf1f4658075f87985d543414e45186e72d2 (patch) | |
| tree | 7259447c78be773163b348c196f9a59577f40427 | |
| parent | 8d66ab29191c59baac04ef89fac30630cf9535e9 (diff) | |
| parent | 86f8353ce7a343db7b19422db0d37379ac45ff4e (diff) | |
Merge branch 'prep-bye-apt-key' into 'main'
Stop using apt-key
See merge request apt-team/apt!407
| -rw-r--r-- | apt-pkg/contrib/fileutl.cc | 2 | ||||
| -rw-r--r-- | apt-pkg/contrib/gpgv.cc | 254 | ||||
| -rw-r--r-- | apt-pkg/contrib/gpgv.h | 10 | ||||
| -rw-r--r-- | apt-pkg/contrib/strutl.cc | 67 | ||||
| -rw-r--r-- | apt-pkg/contrib/strutl.h | 1 | ||||
| -rw-r--r-- | cmdline/apt-key.in | 6 | ||||
| -rw-r--r-- | methods/gpgv.cc | 9 | ||||
| -rw-r--r-- | test/integration/framework | 9 | ||||
| -rwxr-xr-x | test/integration/test-method-gpgv | 22 | ||||
| -rw-r--r-- | test/libapt/fileutl_test.cc | 2 | ||||
| -rw-r--r-- | test/libapt/strutil_test.cc | 21 |
11 files changed, 313 insertions, 90 deletions
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index a45069ee9..67c5acee2 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -3232,7 +3232,7 @@ bool Popen(const char *Args[], FileFd &Fd, pid_t &Child, FileFd::OpenMode Mode, } else if(Mode == FileFd::WriteOnly) dup2(fd, 0); - execv(Args[0], (char**)Args); + execvp(Args[0], (char **)Args); _exit(100); } if(Mode == FileFd::ReadOnly) diff --git a/apt-pkg/contrib/gpgv.cc b/apt-pkg/contrib/gpgv.cc index 147f15d9d..43c634dde 100644 --- a/apt-pkg/contrib/gpgv.cc +++ b/apt-pkg/contrib/gpgv.cc @@ -18,11 +18,13 @@ #include <unistd.h> #include <algorithm> +#include <forward_list> #include <fstream> #include <iostream> #include <memory> #include <sstream> #include <string> +#include <unordered_map> #include <vector> #include <apti18n.h> @@ -112,7 +114,9 @@ static bool operator!=(LineBuffer const &buf, std::string_view const exp) noexce And as a cherry on the cake, we use our apt-key wrapper to do part of the lifting in regards to merging keyrings. Fun for the whole family. */ -static void APT_PRINTF(4) apt_error(std::ostream &outterm, int const statusfd, int fd[2], const char *format, ...) +#define apt_error(...) apt_msg("ERROR", __VA_ARGS__) +#define apt_warning(...) apt_msg("WARNING", __VA_ARGS__) +static void APT_PRINTF(5) apt_msg(std::string const &tag, std::ostream &outterm, int const statusfd, int fd[2], const char *format, ...) { std::ostringstream outstr; std::ostream &out = (statusfd == -1) ? outterm : outstr; @@ -128,53 +132,197 @@ static void APT_PRINTF(4) apt_error(std::ostream &outterm, int const statusfd, i } if (statusfd != -1) { - auto const errtag = "[APTKEY:] ERROR "; + auto const errtag = "[APTKEY:] " + tag + " "; outstr << '\n'; auto const errtext = outstr.str(); - if (not FileFd::Write(fd[1], errtag, strlen(errtag)) || + if (not FileFd::Write(fd[1], errtag.data(), errtag.size()) || not FileFd::Write(fd[1], errtext.data(), errtext.size())) outterm << errtext << std::flush; } } + +static bool CheckGPGV(std::unordered_map<std::string, std::forward_list<std::string>> &checkedCommands, std::string gpgv, bool Debug) +{ + if (checkedCommands.find(gpgv) == checkedCommands.end()) + { + // Create entry + checkedCommands[gpgv]; + FileFd dumpOptions; + pid_t child; + const char *argv[] = {gpgv.c_str(), "--dump-options", nullptr}; + if (unlikely(Debug)) + std::clog << "Executing " << gpgv << " --dump-options" << std::endl; + if (not Popen(argv, dumpOptions, child, FileFd::ReadOnly) && Debug) + return false; + + for (std::string line; dumpOptions.ReadLine(line);) + { + if (unlikely(Debug)) + std::clog << "Read line: " << line << std::endl; + checkedCommands[gpgv].push_front(APT::String::Strip(line)); + } + dumpOptions.Close(); + waitpid(child, NULL, 0); + } + return not checkedCommands[gpgv].empty(); +} + +std::pair<std::string, std::forward_list<std::string>> APT::Internal::FindGPGV(bool Debug) +{ + static thread_local std::unordered_map<std::string, std::forward_list<std::string>> checkedCommands; + const std::string gpgvVariants[] = { + _config->Find("Apt::Key::gpgvcommand"), + // Prefer absolute path + "/usr/bin/gpgv-sq", + "/usr/bin/gpgv", + "/usr/bin/gpgv2", + "/usr/bin/gpgv1", + "gpgv-sq", + "gpgv", + "gpgv2", + "gpgv1", + }; + for (auto gpgv : gpgvVariants) + if (CheckGPGV(checkedCommands, gpgv, Debug)) + return std::make_pair(gpgv, checkedCommands[gpgv]); + return {}; +} + void ExecGPGV(std::string const &File, std::string const &FileGPG, int const &statusfd, int fd[2], std::string const &key) { - #define EINTERNAL 111 - std::string const aptkey = _config->Find("Dir::Bin::apt-key", CMAKE_INSTALL_FULL_BINDIR "/apt-key"); + auto const keyFiles = VectorizeString(key, ','); + ExecGPGV(File, FileGPG, statusfd, fd, keyFiles); +} +void ExecGPGV(std::string const &File, std::string const &FileGPG, + int const &statusfd, int fd[2], std::vector<std::string> const &KeyFiles) +{ +#define EINTERNAL 111 bool const Debug = _config->FindB("Debug::Acquire::gpgv", false); struct exiter { - std::vector<const char *> files; + std::vector<std::string> files; void operator ()(int code) APT_NORETURN { - std::for_each(files.begin(), files.end(), unlink); + std::for_each(files.begin(), files.end(), [](auto f) + { unlink(f.c_str()); }); exit(code); } } local_exit; + auto [gpgv, supportedOptions] = APT::Internal::FindGPGV(Debug); + if (gpgv.empty()) + { + apt_error(std::cerr, statusfd, fd, "Couldn't find a gpgv binary"); + local_exit(EINTERNAL); + } - std::vector<const char *> Args; + std::vector<std::string> Args; Args.reserve(10); - Args.push_back(aptkey.c_str()); - Args.push_back("--quiet"); - Args.push_back("--readonly"); - auto const keysFileFpr = VectorizeString(key, ','); - for (auto const &k: keysFileFpr) + Args.push_back(gpgv); + Args.push_back("--ignore-time-conflict"); + + auto dearmorKeyOrCheckFormat = [&](std::string const &k) -> std::string + { + FileFd keyFd(k, FileFd::ReadOnly); + if (not keyFd.IsOpen()) + { + apt_warning(std::cerr, statusfd, fd, "The key(s) in the keyring %s are ignored as the file is not readable by user executing apt-key.\n", k.c_str()); + return ""; + } + if (APT::String::Endswith(k, ".gpg") || APT::String::Endswith(k, ".pub")) + { + unsigned char c; + if (not keyFd.Read(&c, sizeof(c))) + goto err; + // Identify the leading byte of an OpenPGP public key packet + // 0x98 -- old-format OpenPGP public key packet, up to 255 octets + // 0x99 -- old-format OpenPGP public key packet, 256-65535 octets + // 0xc6 -- new-format OpenPGP public key packet, any length + if (c == 0x98 || c == 0x99 || c == 0xc6) + return k; + } + else if (APT::String::Endswith(k, ".asc")) + { + std::string b64msg; + int state = 0; + for (std::string line; keyFd.ReadLine(line);) + { + line = APT::String::Strip(line); + if (APT::String::Startswith(line, "-----BEGIN PGP PUBLIC KEY BLOCK-----")) + state = 1; + else if (state == 1 && line == "") + state = 2; + else if (state == 2 && line != "" && line[0] != '=' && line[0] != '-') + b64msg += line; + else if (APT::String::Startswith(line, "-----END")) + state = 3; + } + if (state != 3) + goto err; + + FileFd dearmoredFd; + if (GetTempFile("apt.XXXXXX.gpg", false, &dearmoredFd) == nullptr) + local_exit(EINTERNAL); + if (auto decoded = Base64Decode(b64msg); not decoded.empty()) + dearmoredFd.Write(decoded.data(), decoded.size()); + local_exit.files.push_back(dearmoredFd.Name()); + return dearmoredFd.Name(); + } + err: + apt_warning(std::cerr, statusfd, fd, "The key(s) in the keyring %s are ignored as the file has an unsupported filetype.", k.c_str()); + return ""; + }; + auto maybeAddKeyring = [&](std::string const &k) + { + if (struct stat st; stat(k.c_str(), &st) != 0 || st.st_size == 0) + return; + if (auto cleanKey = dearmorKeyOrCheckFormat(k); not cleanKey.empty()) + { + Args.push_back("--keyring"); + Args.push_back(cleanKey); + } + return; + }; + + for (auto const &k : KeyFiles) { if (unlikely(k.empty())) continue; if (k[0] == '/') { - Args.push_back("--keyring"); - Args.push_back(k.c_str()); + if (Debug) + std::clog << "Trying Signed-By: " << k << std::endl; + + maybeAddKeyring(k); } else { Args.push_back("--keyid"); - Args.push_back(k.c_str()); + Args.push_back(k); } } - Args.push_back("verify"); + + std::vector<std::string> Parts; + if (std::find(Args.begin(), Args.end(), "--keyring") == Args.end()) + { + Parts = GetListOfFilesInDir(_config->FindDir("Dir::Etc::TrustedParts"), std::vector<std::string>{"gpg", "asc"}, true); + if (char *env = getenv("APT_KEY_NO_LEGACY_KEYRING"); env == nullptr || not StringToBool(env, false)) + Parts.insert(Parts.begin(), _config->FindFile("Dir::Etc::Trusted")); + for (auto &Part : Parts) + { + if (Debug) + std::clog << "Trying TrustedPart: " << Part << std::endl; + maybeAddKeyring(Part); + } + } + + // If we do not give it any keyring, gpgv shouts keydb errors at us + if (std::find(Args.begin(), Args.end(), "--keyring") == Args.end()) + { + Args.push_back("--keyring"); + Args.push_back("/dev/null"); + } char statusfdstr[10]; if (statusfd != -1) @@ -184,6 +332,12 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG, Args.push_back(statusfdstr); } + if (auto assertPubkeyAlgo = _config->Find("Apt::Key::assert-pubkey-algo"); not assertPubkeyAlgo.empty()) + { + if (std::find(supportedOptions.begin(), supportedOptions.end(), "--assert-pubkey-algo") != supportedOptions.end()) + Args.push_back("--assert-pubkey-algo=" + assertPubkeyAlgo); + } + Configuration::Item const *Opts; Opts = _config->Tree("Acquire::gpgv::Options"); if (Opts != 0) @@ -193,42 +347,11 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG, { if (Opts->Value.empty()) continue; - Args.push_back(Opts->Value.c_str()); + Args.push_back(Opts->Value); } } enum { DETACHED, CLEARSIGNED } releaseSignature = (FileGPG != File) ? DETACHED : CLEARSIGNED; - std::unique_ptr<char, FreeDeleter> sig; - std::unique_ptr<char, FreeDeleter> data; - std::unique_ptr<char, FreeDeleter> conf; - - // Dump the configuration so apt-key picks up the correct Dir values - { - { - std::string tmpfile; - strprintf(tmpfile, "%s/apt.conf.XXXXXX", GetTempDir().c_str()); - conf.reset(strdup(tmpfile.c_str())); - } - if (conf == nullptr) { - apt_error(std::cerr, statusfd, fd, "Couldn't create tempfile names for passing config to apt-key"); - local_exit(EINTERNAL); - } - int confFd = mkstemp(conf.get()); - if (confFd == -1) { - apt_error(std::cerr, statusfd, fd, "Couldn't create temporary file %s for passing config to apt-key", conf.get()); - local_exit(EINTERNAL); - } - local_exit.files.push_back(conf.get()); - - std::ofstream confStream(conf.get()); - close(confFd); - _config->Dump(confStream); - confStream.close(); - setenv("APT_CONFIG", conf.get(), 1); - } - - // Tell apt-key not to emit warnings - setenv("APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE", "1", 1); if (releaseSignature == DETACHED) { @@ -307,21 +430,19 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG, local_exit(112); } - Args.push_back(FileGPG.c_str()); - Args.push_back(File.c_str()); + Args.push_back(FileGPG); + Args.push_back(File); } else // clear-signed file { FileFd signature; if (GetTempFile("apt.sig", false, &signature) == nullptr) local_exit(EINTERNAL); - sig.reset(strdup(signature.Name().c_str())); - local_exit.files.push_back(sig.get()); + local_exit.files.push_back(signature.Name()); FileFd message; if (GetTempFile("apt.data", false, &message) == nullptr) local_exit(EINTERNAL); - data.reset(strdup(message.Name().c_str())); - local_exit.files.push_back(data.get()); + local_exit.files.push_back(message.Name()); if (signature.Failed() || message.Failed() || not SplitClearSignedFile(File, &message, nullptr, &signature)) @@ -329,17 +450,15 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG, apt_error(std::cerr, statusfd, fd, "Splitting up %s into data and signature failed", File.c_str()); local_exit(112); } - Args.push_back(sig.get()); - Args.push_back(data.get()); + Args.push_back(signature.Name()); + Args.push_back(message.Name()); } - Args.push_back(NULL); - if (Debug) { std::clog << "Preparing to exec: "; - for (std::vector<const char *>::const_iterator a = Args.begin(); *a != NULL; ++a) - std::clog << " " << *a; + for (auto const &a : Args) + std::clog << " " << a; std::clog << std::endl; } @@ -360,20 +479,27 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG, putenv((char *)"LC_MESSAGES="); } + // Translate the argument list to a C array. This should happen before + // the fork so we don't allocate money between fork() and execvp(). + std::vector<const char *> cArgs; + cArgs.reserve(Args.size() + 1); + for (auto const &arg : Args) + cArgs.push_back(arg.c_str()); + cArgs.push_back(nullptr); // We have created tempfiles we have to clean up // and we do an additional check, so fork yet another time … pid_t pid = ExecFork(); if(pid < 0) { - apt_error(std::cerr, statusfd, fd, "Fork failed for %s to check %s", Args[0], File.c_str()); + apt_error(std::cerr, statusfd, fd, "Fork failed for %s to check %s", Args[0].c_str(), File.c_str()); local_exit(EINTERNAL); } if(pid == 0) { if (statusfd != -1) dup2(fd[1], statusfd); - execvp(Args[0], (char **) &Args[0]); - apt_error(std::cerr, statusfd, fd, "Couldn't execute %s to check %s", Args[0], File.c_str()); + execvp(cArgs[0], (char **) &cArgs[0]); + apt_error(std::cerr, statusfd, fd, "Couldn't execute %s to check %s", Args[0].c_str(), File.c_str()); local_exit(EINTERNAL); } diff --git a/apt-pkg/contrib/gpgv.h b/apt-pkg/contrib/gpgv.h index 1f3ef26f9..d4520f3a2 100644 --- a/apt-pkg/contrib/gpgv.h +++ b/apt-pkg/contrib/gpgv.h @@ -11,12 +11,20 @@ #include <apt-pkg/macros.h> +#include <forward_list> #include <string> #include <vector> class FileFd; +#ifdef APT_COMPILING_APT +namespace APT::Internal +{ +APT_PUBLIC std::pair<std::string, std::forward_list<std::string>> FindGPGV(bool Debug); +} +#endif + /** \brief generates and run the command to verify a file with gpgv * * If File and FileSig specify the same file it is assumed that we @@ -40,6 +48,8 @@ class FileFd; * @param key is the specific one to be used instead of using all */ APT_PUBLIC void ExecGPGV(std::string const &File, std::string const &FileSig, + int const &statusfd, int fd[2], std::vector<std::string> const &KeyFiles) APT_NORETURN; +APT_PUBLIC void ExecGPGV(std::string const &File, std::string const &FileSig, int const &statusfd, int fd[2], std::string const &Key = "") APT_NORETURN; inline APT_NORETURN void ExecGPGV(std::string const &File, std::string const &FileSig, int const &statusfd = -1) { diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index ec61c7e2b..69a67188e 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -625,6 +625,73 @@ string Base64Encode(const string &S) return Final; } /*}}}*/ +// Base64Decode - Base64 decoding routine for short strings /*{{{*/ +// --------------------------------------------------------------------- +// Taken from mjg59's dpkg code: https://lists.debian.org/debian-dpkg/2018/05/msg00002.html +std::string Base64Decode(const std::string_view in) +{ + constexpr std::array<unsigned char, 256> mime_base64_rank{ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 0, 255, 255, + 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, + 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}; + std::string out; + unsigned char rank; + unsigned char last[2]; + unsigned int v; + int i; + + /* convert 4 base64 bytes to 3 normal bytes */ + v = 0; + i = 0; + + last[0] = last[1] = 0; + + /* we use the sign in the state to determine if we got a padding character + in the previous sequence */ + if (i < 0) + { + i = -i; + last[0] = '='; + } + + for (const unsigned char c : in) + { + rank = mime_base64_rank[c]; + if (rank != 0xff) + { + last[1] = last[0]; + last[0] = c; + v = (v << 6) | rank; + i++; + if (i == 4) + { + out += v >> 16; + if (last[1] != '=') + out += v >> 8; + if (last[0] != '=') + out += v; + i = 0; + } + } + } + + return out; +} + + /*}}}*/ // stringcmp - Arbitrary string compare /*{{{*/ // --------------------------------------------------------------------- /* This safely compares two non-null terminated strings of arbitrary diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index 90d9674fd..91f5fe44b 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -69,6 +69,7 @@ APT_PUBLIC std::string DeEscapeString(const std::string &input); APT_PUBLIC std::string SizeToStr(double Bytes); APT_PUBLIC std::string TimeToStr(unsigned long Sec); APT_PUBLIC std::string Base64Encode(const std::string &Str); +APT_PUBLIC std::string Base64Decode(const std::string_view in); APT_PUBLIC std::string OutputInDepth(const unsigned long Depth, const char* Separator=" "); APT_PUBLIC std::string URItoFileName(const std::string &URI); /** returns a datetime string as needed by HTTP/1.1 and Debian files. diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 99a31bdd1..dd1c52ab0 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -312,7 +312,7 @@ is_supported_keyring() { return 0 fi local FILEEXT="${1##*.}" - if [ "$FILEEXT" = 'gpg' ]; then + if [ "$FILEEXT" = 'gpg' -o "$FILEEXT" = 'pub' ]; then # 0x98, 0x99 and 0xC6 via octal as hex isn't supported by dashs printf if printf '\231' | cmp -s -n 1 - "$1"; then true @@ -470,7 +470,9 @@ dearmor_filename() { fi } catfile() { - cat "$(dearmor_filename "$1")" >> "$2" + if accessible_file_exists "$1" && is_supported_keyring "$1"; then + cat "$(dearmor_filename "$1")" >> "$2" + fi } merge_all_trusted_keyrings_into_pubring() { diff --git a/methods/gpgv.cc b/methods/gpgv.cc index 4a0866555..947b585da 100644 --- a/methods/gpgv.cc +++ b/methods/gpgv.cc @@ -190,6 +190,12 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, if (Debug == true) std::clog << "inside VerifyGetSigners" << std::endl; + // Abort early if we can't find gpgv, before forking further. This also + // caches the invocation of --dump-options to find the working gpgv across + // our fork() below. + if (APT::Internal::FindGPGV(Debug).first.empty()) + return "Internal error: Cannot find gpgv"; + int fd[2]; if (pipe(fd) < 0) @@ -201,9 +207,8 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, else if (pid == 0) { std::ostringstream keys; - implodeVector(keyFiles, keys, ","); setenv("APT_KEY_NO_LEGACY_KEYRING", "1", true); - ExecGPGV(outfile, file, 3, fd, keys.str()); + ExecGPGV(outfile, file, 3, fd, keyFiles); } close(fd[1]); diff --git a/test/integration/framework b/test/integration/framework index ad87d17c7..a64488f0e 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -457,15 +457,8 @@ _setupprojectenvironment() { echo "APT::Get::Show-User-Simulation-Note \"false\";" >> aptconfig.conf echo "Binary::apt::APT::Output-Version \"0\";" >> aptconfig.conf echo "Dir::Bin::Methods \"${TMPWORKINGDIRECTORY}/rootdir/usr/lib/apt/methods\";" >> aptconfig.conf - # either store apt-key were we can access it, even if we run it as a different user - #cp "${APTCMDLINEBINDIR}/apt-key" "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/" - #chmod o+rx "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/apt-key" - #echo "Dir::Bin::apt-key \"${TMPWORKINGDIRECTORY}/rootdir/usr/bin/apt-key\";" >> aptconfig.conf - # destroys coverage reporting though, so we disable changing user for the calling gpgv - echo "Dir::Bin::apt-key \"${APTCMDLINEBINDIR}/apt-key\";" >> aptconfig.conf if [ "$(id -u)" = '0' ]; then - echo 'Binary::gpgv::APT::Sandbox::User "root";' >> aptconfig.conf - # same for the solver executables + # run the solvers as root so we don't lose coverage data echo 'APT::Solver::RunAsUser "root";' >> aptconfig.conf echo 'APT::Planner::RunAsUser "root";' >> aptconfig.conf fi diff --git a/test/integration/test-method-gpgv b/test/integration/test-method-gpgv index ffaa72c8f..5ce685c8b 100755 --- a/test/integration/test-method-gpgv +++ b/test/integration/test-method-gpgv @@ -7,7 +7,7 @@ TESTDIR="$(readlink -f "$(dirname "$0")")" setupenvironment configarchitecture 'i386' -cat > faked-apt-key <<EOF +cat > faked-gpgv <<EOF #!/bin/sh set -e find_gpgv_status_fd() { @@ -24,7 +24,7 @@ GPGSTATUSFD="\$(find_gpgv_status_fd "\$@")" cat >&\${GPGSTATUSFD} gpgv.output cat gpgv.output EOF -chmod +x faked-apt-key +chmod +x faked-gpgv testgpgv() { echo "$4" > gpgv.output @@ -114,7 +114,7 @@ EOF gpgvmethod() { echo "601 Configuration Config-Item: Debug::Acquire::gpgv=1 -Config-Item: Dir::Bin::apt-key=./faked-apt-key +Config-Item: APT::Key::GPGVCommand=$PWD/faked-gpgv Config-Item: APT::Hashes::SHA1::Weak=true Config-Item: APT::Key::Assert-Pubkey-Algo=>=rsa2048,nistp256,brainpoolP256r1 Config-Item: APT::Key::Assert-Pubkey-Algo::Next=>=rsa2048,nistp256 @@ -130,7 +130,7 @@ testrun gpgvmethod() { echo "601 Configuration Config-Item: Debug::Acquire::gpgv=1 -Config-Item: Dir::Bin::apt-key=./faked-apt-key +Config-Item: APT::Key::GPGVCommand=$PWD/faked-gpgv Config-Item: APT::Hashes::SHA1::Weak=true Config-Item: APT::Key::Assert-Pubkey-Algo=>=rsa2048,nistp256,brainpoolP256r1 Config-Item: APT::Key::Assert-Pubkey-Algo::Next=>=rsa2048,nistp256 @@ -147,7 +147,7 @@ testrun gpgvmethod() { echo "601 Configuration Config-Item: Debug::Acquire::gpgv=1 -Config-Item: Dir::Bin::apt-key=./faked-apt-key +Config-Item: APT::Key::GPGVCommand=$PWD/faked-gpgv Config-Item: APT::Hashes::SHA1::Weak=true Config-Item: APT::Key::Assert-Pubkey-Algo=>=rsa2048,nistp256,brainpoolP256r1 Config-Item: APT::Key::Assert-Pubkey-Algo::Next=>=rsa2048,nistp256 @@ -173,7 +173,7 @@ testsuccess grep 'verified because the public key is not available: GOODSIG' met gpgvmethod() { echo "601 Configuration Config-Item: Debug::Acquire::gpgv=1 -Config-Item: Dir::Bin::apt-key=./faked-apt-key +Config-Item: APT::Key::GPGVCommand=$PWD/faked-gpgv Config-Item: APT::Hashes::SHA1::Weak=true Config-Item: APT::Key::Assert-Pubkey-Algo=>=rsa2048,nistp256,brainpoolP256r1 Config-Item: APT::Key::Assert-Pubkey-Algo::Next=>=rsa2048,nistp256 @@ -204,26 +204,26 @@ setupaptarchive --no-update echo '[GNUPG:] GOODSIG 5A90D141DBAC8DAE Sebastian Subkey <subkey@example.org> [GNUPG:] VALIDSIG 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE 2018-08-16 1534459673 0 4 0 1 11 00 4281DEDBD466EAE8C1F4157E5B6896415D44C43E' > gpgv.output -testsuccess apt update -o Dir::Bin::apt-key="./faked-apt-key" -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::gpgv=1 +testsuccess apt update -o APT::Key::GPGVCommand="$PWD/faked-gpgv" -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::gpgv=1 rm -rf rootdir/var/lib/apt/lists echo '[GNUPG:] GOODSIG 5A90D141DBAC8DAE Sebastian Subkey <subkey@example.org>' > gpgv.output -testfailure apt update -o Dir::Bin::apt-key="./faked-apt-key" -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::gpgv=1 +testfailure apt update -o APT::Key::GPGVCommand="$PWD/faked-gpgv" -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::gpgv=1 rm -rf rootdir/var/lib/apt/lists echo '[GNUPG:] VALIDSIG 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE 2018-08-16 1534459673 0 4 0 1 11 00 4281DEDBD466EAE8C1F4157E5B6896415D44C43E' > gpgv.output -testfailure apt update -o Dir::Bin::apt-key="./faked-apt-key" -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::gpgv=1 +testfailure apt update -o APT::Key::GPGVCommand="$PWD/faked-gpgv" -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::gpgv=1 rm -rf rootdir/var/lib/apt/lists echo '[GNUPG:] GOODSIG 5A90D141DBAC8DAE Sebastian Subkey <subkey@example.org> [GNUPG:] VALIDSIG 0000000000000000000000000000000000000000 2018-08-16 1534459673 0 4 0 1 11 00 4281DEDBD466EAE8C1F4157E5B6896415D44C43E' > gpgv.output -testfailure apt update -o Dir::Bin::apt-key="./faked-apt-key" -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::gpgv=1 +testfailure apt update -o APT::Key::GPGVCommand="$PWD/faked-gpgv" -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::gpgv=1 rm -rf rootdir/var/lib/apt/lists gpgvmethod() { echo "601 Configuration Config-Item: Debug::Acquire::gpgv=1 -Config-Item: Dir::Bin::apt-key=./faked-apt-key +Config-Item: APT::Key::GPGVCommand=$PWD/faked-gpgv Config-Item: APT::Hashes::SHA1::Weak=true Config-Item: APT::Key::Assert-Pubkey-Algo::Next=>=invalid diff --git a/test/libapt/fileutl_test.cc b/test/libapt/fileutl_test.cc index b35a2d45e..2badf5465 100644 --- a/test/libapt/fileutl_test.cc +++ b/test/libapt/fileutl_test.cc @@ -288,7 +288,7 @@ TEST(FileUtlTest, Popen) OpenFds = Glob("/proc/self/fd/*"); // output something - const char* Args[10] = {"/bin/echo", "meepmeep", NULL}; + const char* Args[10] = {"echo", "meepmeep", NULL}; EXPECT_TRUE(Popen(Args, Fd, Child, FileFd::ReadOnly)); EXPECT_TRUE(Fd.Read(buf, sizeof(buf)-1, &n)); buf[n] = 0; diff --git a/test/libapt/strutil_test.cc b/test/libapt/strutil_test.cc index 500ba98da..9320f8fa9 100644 --- a/test/libapt/strutil_test.cc +++ b/test/libapt/strutil_test.cc @@ -179,6 +179,24 @@ TEST(StrUtilTest,Base64Encode) EXPECT_EQ("/A==", Base64Encode("\xfc")); EXPECT_EQ("//8=", Base64Encode("\xff\xff")); } +TEST(StrUtilTest,Base64Decode) +{ + EXPECT_EQ(Base64Decode("QWxhZGRpbjpvcGVuIHNlc2FtZQ=="), "Aladdin:open sesame"); + EXPECT_EQ(Base64Decode("cGxlYXN1cmUu"), "pleasure."); + EXPECT_EQ(Base64Decode("bGVhc3VyZS4="), "leasure."); + EXPECT_EQ(Base64Decode("ZWFzdXJlLg=="), "easure."); + EXPECT_EQ(Base64Decode("YXN1cmUu"), "asure."); + EXPECT_EQ(Base64Decode("c3VyZS4="), "sure."); + EXPECT_EQ(Base64Decode("dXJlLg=="), "ure."); + EXPECT_EQ(Base64Decode("cmUu"), "re."); + EXPECT_EQ(Base64Decode("ZS4="), "e."); + EXPECT_EQ(Base64Decode("Lg=="), "."); + EXPECT_EQ(Base64Decode(""), ""); + EXPECT_EQ(Base64Decode("IA=="), "\x20"); + EXPECT_EQ(Base64Decode("/w=="), "\xff"); + EXPECT_EQ(Base64Decode("/A=="), "\xfc"); + EXPECT_EQ(Base64Decode("//8="), "\xff\xff"); +} static void ReadMessagesTestWithNewLine(char const * const nl, char const * const ab) { SCOPED_TRACE(SubstVar(SubstVar(nl, "\n", "n"), "\r", "r") + " # " + ab); @@ -318,7 +336,8 @@ TEST(StrUtilTest,RFC1123StrToTime) time_t t; EXPECT_TRUE(RFC1123StrToTime("Sun, 06 Nov 1994 08:49:37 GMT", t)); EXPECT_EQ(784111777, t); - } { + } + { time_t t; EXPECT_TRUE(RFC1123StrToTime("Sun, 6 Nov 1994 08:49:37 UTC", t)); EXPECT_EQ(784111777, t); |
