From f674884648fa1ef5e3b1322d2ac96888ee9fa241 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Mon, 28 Oct 2024 12:55:43 +0200 Subject: [PATCH] Turn keystore into an interface class Add an abstract rpm::keystore class and port our existing rpmdb and fs keystores to that. The keystore code as such doesn't really change at all in here, the bigger change is the way it's initialized because it's an object instead of just an integer in the rpmts struct. As a kind of side-effect, we introduce the rpm:: namespace here. Fixes: #3342 --- lib/keystore.cc | 71 +++++++++---------------------------------- lib/keystore.hh | 40 ++++++++++++++++++------ lib/rpmts.cc | 38 ++++++++++++----------- lib/rpmts_internal.hh | 3 +- 4 files changed, 69 insertions(+), 83 deletions(-) diff --git a/lib/keystore.cc b/lib/keystore.cc index 2ff02aa0bc..01fc81cee6 100644 --- a/lib/keystore.cc +++ b/lib/keystore.cc @@ -15,16 +15,16 @@ #include #include -#include "keystore.hh" #include "rpmts_internal.hh" #include "debug.h" using std::string; +using namespace rpm; static int makePubkeyHeader(rpmts ts, rpmPubkey key, Header * hdrp); -static rpmRC rpmtsLoadKeyringFromFiles(rpmtxn txn, rpmKeyring keyring) +rpmRC keystore_fs::load_keys(rpmtxn txn, rpmKeyring keyring) { ARGV_t files = NULL; /* XXX TODO: deal with chroot path issues */ @@ -55,7 +55,7 @@ static rpmRC rpmtsLoadKeyringFromFiles(rpmtxn txn, rpmKeyring keyring) return RPMRC_OK; } -static rpmRC rpmtsDeleteFSKey(rpmtxn txn, const string & keyid, const string & newname = "") +rpmRC keystore_fs::delete_key(rpmtxn txn, const string & keyid, const string & newname) { rpmRC rc = RPMRC_NOTFOUND; string keyglob = "gpg-pubkey-" + keyid + "*.key"; @@ -74,12 +74,12 @@ static rpmRC rpmtsDeleteFSKey(rpmtxn txn, const string & keyid, const string & n return rc; } -static rpmRC rpmtsDeleteFSKey(rpmtxn txn, rpmPubkey key) +rpmRC keystore_fs::delete_key(rpmtxn txn, rpmPubkey key) { - return rpmtsDeleteFSKey(txn, rpmPubkeyFingerprintAsHex(key)); + return delete_key(txn, rpmPubkeyFingerprintAsHex(key)); } -static rpmRC rpmtsImportFSKey(rpmtxn txn, rpmPubkey key, rpmFlags flags, int replace) +rpmRC keystore_fs::import_key(rpmtxn txn, rpmPubkey key, rpmFlags flags, int replace) { rpmRC rc = RPMRC_FAIL; const char *fp = rpmPubkeyFingerprintAsHex(key); @@ -117,9 +117,9 @@ static rpmRC rpmtsImportFSKey(rpmtxn txn, rpmPubkey key, rpmFlags flags, int rep if (!rc && replace) { /* find and delete the old pubkey entry */ - if (rpmtsDeleteFSKey(txn, fp, keyfmt) == RPMRC_NOTFOUND) { + if (delete_key(txn, fp, keyfmt) == RPMRC_NOTFOUND) { /* make sure an old, short keyid version gets removed */ - rpmtsDeleteFSKey(txn, fp+32, keyfmt); + delete_key(txn, fp+32, keyfmt); } } @@ -131,7 +131,7 @@ static rpmRC rpmtsImportFSKey(rpmtxn txn, rpmPubkey key, rpmFlags flags, int rep return rc; } -static rpmRC rpmtsLoadKeyringFromDB(rpmtxn txn, rpmKeyring keyring) +rpmRC keystore_rpmdb::load_keys(rpmtxn txn, rpmKeyring keyring) { Header h; rpmdbMatchIterator mi; @@ -170,7 +170,7 @@ static rpmRC rpmtsLoadKeyringFromDB(rpmtxn txn, rpmKeyring keyring) return RPMRC_OK; } -static rpmRC rpmtsDeleteDBKey(rpmtxn txn, const string & keyid, unsigned int newinstance = 0) +rpmRC keystore_rpmdb::delete_key(rpmtxn txn, const string & keyid, unsigned int newinstance) { rpmts ts = rpmtxnTs(txn); if (rpmtsOpenDB(ts, (O_RDWR|O_CREAT))) @@ -194,12 +194,12 @@ static rpmRC rpmtsDeleteDBKey(rpmtxn txn, const string & keyid, unsigned int new return rc; } -static rpmRC rpmtsDeleteDBKey(rpmtxn txn, rpmPubkey key) +rpmRC keystore_rpmdb::delete_key(rpmtxn txn, rpmPubkey key) { - return rpmtsDeleteDBKey(txn, rpmPubkeyFingerprintAsHex(key)); + return delete_key(txn, rpmPubkeyFingerprintAsHex(key)); } -static rpmRC rpmtsImportDBKey(rpmtxn txn, rpmPubkey key, rpmFlags flags, int replace) +rpmRC keystore_rpmdb::import_key(rpmtxn txn, rpmPubkey key, rpmFlags flags, int replace) { Header h = NULL; rpmRC rc = RPMRC_FAIL; @@ -213,9 +213,9 @@ static rpmRC rpmtsImportDBKey(rpmtxn txn, rpmPubkey key, rpmFlags flags, int rep /* find and delete the old pubkey entry */ unsigned int newinstance = headerGetInstance(h); char *keyid = headerFormat(h, "%{version}", NULL); - if (rpmtsDeleteDBKey(txn, keyid, newinstance) == RPMRC_NOTFOUND) { + if (delete_key(txn, keyid, newinstance) == RPMRC_NOTFOUND) { /* make sure an old, short keyid version gets removed */ - rpmtsDeleteDBKey(txn, keyid+32, newinstance); + delete_key(txn, keyid+32, newinstance); } free(keyid); } @@ -372,44 +372,3 @@ static int makePubkeyHeader(rpmts ts, rpmPubkey key, Header * hdrp) return rc; } - -rpmRC rpmKeystoreImportPubkey(rpmtxn txn, rpmPubkey key, int replace) -{ - rpmRC rc = RPMRC_FAIL; - rpmts ts = rpmtxnTs(txn); - - /* Add header to database. */ - if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) { - if (ts->keyringtype == KEYRING_FS) - rc = rpmtsImportFSKey(txn, key, 0, replace); - else - rc = rpmtsImportDBKey(txn, key, 0, replace); - } else { - rc = RPMRC_OK; - } - return rc; -} - -rpmRC rpmKeystoreDeletePubkey(rpmtxn txn, rpmPubkey key) -{ - rpmRC rc = RPMRC_FAIL; - rpmts ts = rpmtxnTs(txn); - if (ts->keyringtype == KEYRING_FS) - rc = rpmtsDeleteFSKey(txn, key); - else - rc = rpmtsDeleteDBKey(txn, key); - return rc; -} - -rpmRC rpmKeystoreLoad(rpmtxn txn, rpmKeyring keyring) -{ - rpmRC rc = RPMRC_FAIL; - rpmts ts = rpmtxnTs(txn); - if (ts->keyringtype == KEYRING_FS) { - rc = rpmtsLoadKeyringFromFiles(txn, keyring); - } else { - rc = rpmtsLoadKeyringFromDB(txn, keyring); - } - return rc; -} - diff --git a/lib/keystore.hh b/lib/keystore.hh index 1a988e393f..f031c99afb 100644 --- a/lib/keystore.hh +++ b/lib/keystore.hh @@ -1,20 +1,42 @@ #ifndef _KEYSTORE_H +#define _KEYSTORE_H + +#include #include #include -enum { - KEYRING_RPMDB = 1, - KEYRING_FS = 2, +namespace rpm { + +class keystore { +public: + virtual rpmRC load_keys(rpmtxn txn, rpmKeyring keyring) = 0; + virtual rpmRC import_key(rpmtxn txn, rpmPubkey key, rpmFlags flags = 0, int replace = 1) = 0; + virtual rpmRC delete_key(rpmtxn txn, rpmPubkey key) = 0; + + virtual ~keystore() = default; }; -RPM_GNUC_INTERNAL -rpmRC rpmKeystoreLoad(rpmtxn txn, rpmKeyring keyring); +class keystore_fs : public keystore { +public: + virtual rpmRC load_keys(rpmtxn txn, rpmKeyring keyring); + virtual rpmRC import_key(rpmtxn txn, rpmPubkey key, rpmFlags flags = 0, int replace = 1); + virtual rpmRC delete_key(rpmtxn txn, rpmPubkey key); -RPM_GNUC_INTERNAL -rpmRC rpmKeystoreImportPubkey(rpmtxn txn, rpmPubkey key, int replace = 0); +private: + rpmRC delete_key(rpmtxn txn, const std::string & keyid, const std::string & newname = ""); +}; + +class keystore_rpmdb : public keystore { +public: + virtual rpmRC load_keys(rpmtxn txn, rpmKeyring keyring); + virtual rpmRC import_key(rpmtxn txn, rpmPubkey key, rpmFlags flags = 0, int replace = 1); + virtual rpmRC delete_key(rpmtxn txn, rpmPubkey key); + +private: + rpmRC delete_key(rpmtxn txn, const std::string & keyid, unsigned int newinstance = 0); +}; -RPM_GNUC_INTERNAL -rpmRC rpmKeystoreDeletePubkey(rpmtxn txn, rpmPubkey key); +}; /* namespace */ #endif /* _KEYSTORE_H */ diff --git a/lib/rpmts.cc b/lib/rpmts.cc index 66381e1c3b..d40473cd7d 100644 --- a/lib/rpmts.cc +++ b/lib/rpmts.cc @@ -36,6 +36,7 @@ #include "debug.h" using std::string; +using namespace rpm; /** * Iterator across transaction elements, forward on install, backward on erase. @@ -264,21 +265,25 @@ int rpmtsSetKeyring(rpmts ts, rpmKeyring keyring) return 0; } -static int getKeyringType(void) +static keystore *getKeystore(rpmts ts) { - int kt = KEYRING_RPMDB; - char *krtype = rpmExpand("%{?_keyring}", NULL); + if (ts->keystore == NULL) { + char *krtype = rpmExpand("%{?_keyring}", NULL); - if (rstreq(krtype, "fs")) { - kt = KEYRING_FS; - } else if (*krtype && !rstreq(krtype, "rpmdb")) { - /* Fall back to using rpmdb if unknown, for now at least */ - rpmlog(RPMLOG_WARNING, - _("unknown keyring type: %s, using rpmdb\n"), krtype); + if (rstreq(krtype, "fs")) { + ts->keystore = new keystore_fs(); + } else if (rstreq(krtype, "rpmdb")) { + ts->keystore = new keystore_rpmdb(); + } else { + /* Fall back to using rpmdb if unknown, for now at least */ + rpmlog(RPMLOG_WARNING, + _("unknown keyring type: %s, using rpmdb\n"), krtype); + ts->keystore = new keystore_rpmdb(); + } + free(krtype); } - free(krtype); - return kt; + return ts->keystore; } static void loadKeyring(rpmts ts) @@ -286,12 +291,11 @@ static void loadKeyring(rpmts ts) /* Never load the keyring if signature checking is disabled */ if ((rpmtsVSFlags(ts) & RPMVSF_MASK_NOSIGNATURES) != RPMVSF_MASK_NOSIGNATURES) { - if (!ts->keyringtype) - ts->keyringtype = getKeyringType(); + ts->keystore = getKeystore(ts); ts->keyring = rpmKeyringNew(); rpmtxn txn = rpmtxnBegin(ts, RPMTXN_READ); if (txn) { - rpmKeystoreLoad(txn, ts->keyring); + ts->keystore->load_keys(txn, ts->keyring); rpmtxnEnd(txn); } } @@ -365,7 +369,7 @@ rpmRC rpmtxnImportPubkey(rpmtxn txn, const unsigned char * pkt, size_t pktlen) /* If we dont already have the key, make a persistent record of it */ if (krc == 0) { - rc = rpmKeystoreImportPubkey(txn, pubkey, oldkey ? 1 : 0); + rc = ts->keystore->import_key(txn, pubkey, 0, oldkey ? 1 : 0); } else { rc = RPMRC_OK; /* already have key */ } @@ -395,7 +399,7 @@ rpmRC rpmtxnDeletePubkey(rpmtxn txn, rpmPubkey key) if ((rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) { rc = RPMRC_OK; } else { - rc = rpmKeystoreDeletePubkey(txn, key); + rc = ts->keystore->delete_key(txn, key); } rc = RPMRC_OK; rpmKeyringFree(keyring); @@ -554,6 +558,7 @@ rpmts rpmtsFree(rpmts ts) (void) rpmtsCloseDB(ts); delete ts->members; + delete ts->keystore; if (ts->scriptFd != NULL) { ts->scriptFd = fdFree(ts->scriptFd); @@ -961,7 +966,6 @@ rpmts rpmtsCreate(void) ts->rootDir = NULL; ts->keyring = NULL; - ts->keyringtype = 0; ts->vfyflags = rpmExpandNumeric("%{?_pkgverify_flags}"); ts->vfylevel = vfylevel_init(); diff --git a/lib/rpmts_internal.hh b/lib/rpmts_internal.hh index dc5e465eb6..d1832d102f 100644 --- a/lib/rpmts_internal.hh +++ b/lib/rpmts_internal.hh @@ -11,6 +11,7 @@ #include "rpmal.hh" /* XXX availablePackage */ #include "fprint.hh" +#include "keystore.hh" #include "rpmlock.hh" #include "rpmdb_internal.hh" #include "rpmscript.hh" @@ -84,7 +85,7 @@ struct rpmts_s { rpmVSFlags vfyflags; /*!< Package verification flags */ int vfylevel; /*!< Package verification level */ rpmKeyring keyring; /*!< Keyring in use. */ - int keyringtype; /*!< Keyring type */ + rpm::keystore *keystore; /*!