#include <config.h>
-#include <apt-pkg/acquire-method.h>
#include <apt-pkg/configuration.h>
#include <apt-pkg/error.h>
#include <apt-pkg/gpgv.h>
#define GNUPGEXPSIG "[GNUPG:] EXPSIG"
#define GNUPGREVKEYSIG "[GNUPG:] REVKEYSIG"
#define GNUPGNODATA "[GNUPG:] NODATA"
+#define APTKEYWARNING "[APTKEY:] WARNING"
+#define APTKEYERROR "[APTKEY:] ERROR"
struct Digest {
enum class State {
vector<Signer> &SoonWorthlessSigners,
vector<string> &NoPubKeySigners)
{
- bool const Debug = _config->FindB("Debug::Acquire::gpgv", false);
+ bool const Debug = DebugEnabled();
if (Debug == true)
std::clog << "inside VerifyGetSigners" << std::endl;
std::vector<std::string> ErrSigners;
size_t buffersize = 0;
char *buffer = NULL;
+ bool gotNODATA = false;
while (1)
{
if (getline(&buffer, &buffersize, pipein) == -1)
ErrSigners.erase(std::remove_if(ErrSigners.begin(), ErrSigners.end(), [&](std::string const &errsig) {
return errsig.compare(strlen("ERRSIG "), 16, buffer, sizeof(GNUPGNOPUBKEY), 16) == 0; }), ErrSigners.end());
}
- else if (strncmp(buffer, GNUPGNODATA, sizeof(GNUPGBADSIG)-1) == 0)
- PushEntryWithUID(BadSigners, buffer, Debug);
+ else if (strncmp(buffer, GNUPGNODATA, sizeof(GNUPGNODATA)-1) == 0)
+ gotNODATA = true;
else if (strncmp(buffer, GNUPGEXPKEYSIG, sizeof(GNUPGEXPKEYSIG)-1) == 0)
PushEntryWithUID(WorthlessSigners, buffer, Debug);
else if (strncmp(buffer, GNUPGEXPSIG, sizeof(GNUPGEXPSIG)-1) == 0)
ValidSigners.push_back(sig);
}
+ else if (strncmp(buffer, APTKEYWARNING, sizeof(APTKEYWARNING)-1) == 0)
+ Warning("%s", buffer + sizeof(APTKEYWARNING));
+ else if (strncmp(buffer, APTKEYERROR, sizeof(APTKEYERROR)-1) == 0)
+ _error->Error("%s", buffer + sizeof(APTKEYERROR));
}
fclose(pipein);
free(buffer);
if (std::find(ValidSigners.begin(), ValidSigners.end(), k) == ValidSigners.end())
continue;
// we look for GOODSIG here as well as an expired sig is a valid sig as well (but not a good one)
+ std::string const goodfingerprint = "GOODSIG " + k;
std::string const goodlongkeyid = "GOODSIG " + k.substr(24, 16);
- foundGood = std::find(GoodSigners.begin(), GoodSigners.end(), goodlongkeyid) != GoodSigners.end();
+ foundGood = std::find(GoodSigners.begin(), GoodSigners.end(), goodfingerprint) != GoodSigners.end();
if (Debug == true)
- std::clog << "Key " << k << " is valid sig, is " << goodlongkeyid << " also a good one? " << (foundGood ? "yes" : "no") << std::endl;
+ std::clog << "Key " << k << " is valid sig, is " << goodfingerprint << " also a good one? " << (foundGood ? "yes" : "no") << std::endl;
+ std::string goodsig;
+ if (foundGood == false)
+ {
+ foundGood = std::find(GoodSigners.begin(), GoodSigners.end(), goodlongkeyid) != GoodSigners.end();
+ if (Debug == true)
+ std::clog << "Key " << k << " is valid sig, is " << goodlongkeyid << " also a good one? " << (foundGood ? "yes" : "no") << std::endl;
+ goodsig = goodlongkeyid;
+ }
+ else
+ goodsig = goodfingerprint;
if (foundGood == false)
continue;
std::copy(GoodSigners.begin(), GoodSigners.end(), std::back_insert_iterator<std::vector<std::string> >(NoPubKeySigners));
GoodSigners.clear();
- GoodSigners.push_back(goodlongkeyid);
- NoPubKeySigners.erase(std::remove(NoPubKeySigners.begin(), NoPubKeySigners.end(), goodlongkeyid), NoPubKeySigners.end());
+ GoodSigners.push_back(goodsig);
+ NoPubKeySigners.erase(
+ std::remove(NoPubKeySigners.begin(),
+ std::remove(NoPubKeySigners.begin(), NoPubKeySigners.end(), goodfingerprint),
+ goodlongkeyid),
+ NoPubKeySigners.end()
+ );
break;
}
if (foundGood == false)
std::for_each(SoonWorthlessSigners.begin(), SoonWorthlessSigners.end(), [](Signer const &sig) { std::cerr << sig.key << ", "; });
std::cerr << std::endl << " NoPubKey: ";
std::copy(NoPubKeySigners.begin(), NoPubKeySigners.end(), std::ostream_iterator<std::string>(std::cerr, ", "));
- std::cerr << std::endl;
+ std::cerr << std::endl << " NODATA: " << (gotNODATA ? "yes" : "no") << std::endl;
}
- if (WEXITSTATUS(status) == 0)
+ if (WEXITSTATUS(status) == 112)
+ {
+ // acquire system checks for "NODATA" to generate GPG errors (the others are only warnings)
+ std::string errmsg;
+ //TRANSLATORS: %s is a single techy word like 'NODATA'
+ strprintf(errmsg, _("Clearsigned file isn't valid, got '%s' (does the network require authentication?)"), "NODATA");
+ return errmsg;
+ }
+ else if (gotNODATA)
+ {
+ // acquire system checks for "NODATA" to generate GPG errors (the others are only warnings)
+ std::string errmsg;
+ //TRANSLATORS: %s is a single techy word like 'NODATA'
+ strprintf(errmsg, _("Signed file isn't valid, got '%s' (does the network require authentication?)"), "NODATA");
+ return errmsg;
+ }
+ else if (WEXITSTATUS(status) == 0)
{
if (keyIsID)
{
return _("At least one invalid signature was encountered.");
else if (WEXITSTATUS(status) == 111)
return _("Could not execute 'apt-key' to verify signature (is gnupg installed?)");
- else if (WEXITSTATUS(status) == 112)
- {
- // acquire system checks for "NODATA" to generate GPG errors (the others are only warnings)
- std::string errmsg;
- //TRANSLATORS: %s is a single techy word like 'NODATA'
- strprintf(errmsg, _("Clearsigned file isn't valid, got '%s' (does the network require authentication?)"), "NODATA");
- return errmsg;
- }
else
return _("Unknown error executing apt-key");
}
URIStart(Res);
// Run apt-key on file, extract contents and get the key ID of the signer
- string msg = VerifyGetSigners(Path.c_str(), Itm->DestFile.c_str(), key,
+ string const msg = VerifyGetSigners(Path.c_str(), Itm->DestFile.c_str(), key,
GoodSigners, BadSigners, WorthlessSigners,
SoonWorthlessSigners, NoPubKeySigners);
+ if (_error->PendingError())
+ return false;
// Check if all good signers are soon worthless and warn in that case
if (std::all_of(GoodSigners.begin(), GoodSigners.end(), [&](std::string const &good) {
std::move(NoPubKeySigners.begin(), NoPubKeySigners.end(), std::back_inserter(Res.GPGVOutput));
URIDone(Res);
- if (_config->FindB("Debug::Acquire::gpgv", false))
- {
+ if (DebugEnabled())
std::clog << "apt-key succeeded\n";
- }
return true;
}
int main()
{
- setlocale(LC_ALL, "");
-
- GPGVMethod Mth;
-
- return Mth.Run();
+ return GPGVMethod().Run();
}