summaryrefslogtreecommitdiff
path: root/methods
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2018-08-17 16:33:41 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2018-09-11 13:16:11 +0200
commit8375d5b58038fc026098dcccc3de87cd9d740334 (patch)
treea7a746154a32e6370293c4bc693692dcdc796dc7 /methods
parentff8fa4ab4b80384a9240f0df63181f71077a8d83 (diff)
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.cc40
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())