diff options
author | David Kalnischkies <david@kalnischkies.de> | 2018-08-17 16:33:41 +0200 |
---|---|---|
committer | David Kalnischkies <david@kalnischkies.de> | 2018-09-11 13:16:11 +0200 |
commit | 8375d5b58038fc026098dcccc3de87cd9d740334 (patch) | |
tree | a7a746154a32e6370293c4bc693692dcdc796dc7 /methods | |
parent | ff8fa4ab4b80384a9240f0df63181f71077a8d83 (diff) | |
download | apt-8375d5b58038fc026098dcccc3de87cd9d740334.tar.gz |
Support multiple keyrings in sources.list Signed-By
A user can specify multiple fingerprints for a while now, so its seems
counter-intuitive to support only one keyring, especially if this isn't
really checked or enforced and while unlikely mixtures of both should
work properly, too, instead of a kinda random behaviour.
Diffstat (limited to 'methods')
-rw-r--r-- | methods/gpgv.cc | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/methods/gpgv.cc b/methods/gpgv.cc index e2a20722b..9135b49c5 100644 --- a/methods/gpgv.cc +++ b/methods/gpgv.cc @@ -106,7 +106,8 @@ class GPGVMethod : public aptMethod { private: string VerifyGetSigners(const char *file, const char *outfile, - std::string const &key, + vector<string> const &keyFpts, + vector<string> const &keyFiles, vector<string> &GoodSigners, vector<string> &BadSigners, vector<string> &WorthlessSigners, @@ -146,7 +147,8 @@ static void PushEntryWithUID(std::vector<std::string> &Signers, char * const buf Signers.push_back(msg); } string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, - std::string const &key, + vector<string> const &keyFpts, + vector<string> const &keyFiles, vector<string> &GoodSigners, vector<string> &BadSigners, vector<string> &WorthlessSigners, @@ -159,7 +161,6 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, std::clog << "inside VerifyGetSigners" << std::endl; int fd[2]; - bool const keyIsID = (key.empty() == false && key[0] != '/'); if (pipe(fd) < 0) return "Couldn't create pipe"; @@ -168,7 +169,15 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, if (pid < 0) return string("Couldn't spawn new process") + strerror(errno); else if (pid == 0) - ExecGPGV(outfile, file, 3, fd, (keyIsID ? "" : key)); + { + std::ostringstream keys; + if (keyFiles.empty() == false) + { + std::copy(keyFiles.begin(), keyFiles.end()-1, std::ostream_iterator<std::string>(keys, ",")); + keys << *keyFiles.rbegin(); + } + ExecGPGV(outfile, file, 3, fd, keys.str()); + } close(fd[1]); FILE *pipein = fdopen(fd[0], "r"); @@ -259,18 +268,21 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, // apt-key has a --keyid parameter, but this requires gpg, so we call it without it // and instead check after the fact which keyids where used for verification - if (keyIsID == true) + if (keyFpts.empty() == false) { if (Debug == true) - std::clog << "GoodSigs needs to be limited to keyid(s) " << key << std::endl; - auto const limitedTo = VectorizeString(key, ','); + { + std::clog << "GoodSigs needs to be limited to keyid(s): "; + std::copy(keyFpts.begin(), keyFpts.end(), std::ostream_iterator<std::string>(std::clog, ", ")); + std::clog << "\n"; + } std::vector<std::string> filteredGood; for (auto &&good: GoodSigners) { if (Debug == true) std::clog << "Key " << good << " is good sig, is it also a valid and allowed one? "; bool found = false; - for (auto l : limitedTo) + for (auto l : keyFpts) { bool exactKey = false; if (APT::String::Endswith(l, "!")) @@ -353,7 +365,7 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, } else if (WEXITSTATUS(status) == 0) { - if (keyIsID) + if (keyFpts.empty() == false) { // gpgv will report success, but we want to enforce a certain keyring // so if we haven't found the key the valid we found is in fact invalid @@ -379,7 +391,6 @@ bool GPGVMethod::URIAcquire(std::string const &Message, FetchItem *Itm) { URI const Get = Itm->Uri; string const Path = Get.Host + Get.Path; // To account for relative paths - std::string const key = LookupTag(Message, "Signed-By"); vector<string> GoodSigners; vector<string> BadSigners; // a worthless signature is a expired or revoked one @@ -391,8 +402,15 @@ bool GPGVMethod::URIAcquire(std::string const &Message, FetchItem *Itm) Res.Filename = Itm->DestFile; URIStart(Res); + std::vector<std::string> keyFpts, keyFiles; + for (auto &&key : VectorizeString(LookupTag(Message, "Signed-By"), ',')) + if (key.empty() == false && key[0] == '/') + keyFiles.emplace_back(std::move(key)); + else + keyFpts.emplace_back(std::move(key)); + // Run apt-key on file, extract contents and get the key ID of the signer - string const msg = VerifyGetSigners(Path.c_str(), Itm->DestFile.c_str(), key, + string const msg = VerifyGetSigners(Path.c_str(), Itm->DestFile.c_str(), keyFpts, keyFiles, GoodSigners, BadSigners, WorthlessSigners, SoonWorthlessSigners, NoPubKeySigners); if (_error->PendingError()) |