From 51f483166e803344b214813c0221bdd832454494 Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Fri, 29 Nov 2024 11:18:57 +0100 Subject: [PATCH 1/5] Test rpm -e gpg-pubkey --- tests/rpmsigdig.at | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at index 0b92c929d1..c0bcced292 100644 --- a/tests/rpmsigdig.at +++ b/tests/rpmsigdig.at @@ -122,6 +122,15 @@ runroot rpmkeys --list [0], [], []) + +runroot rpmkeys --import /data/keys/rpm.org-rsa-2048-test.pub +RPMTEST_CHECK([ +runroot rpm -e gpg-pubkey-771b18d3d7baa28734333c424344591e1964c5fc +runroot rpm -qa gpg-pubkey +], +[0], +[], +[]) RPMTEST_CLEANUP AT_SETUP([rpmkeys migrate from keyid to fingerprint (rpmdb)]) From 138f7b192c1a45c03c3477a31ae095b697e72672 Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Fri, 29 Nov 2024 09:22:53 +0100 Subject: [PATCH 2/5] Don't allow installing packages without ARCH or OS We had an exception for public key packages in rpmte. With those now being handled in the keystore without going through the transaction machinery this is no longer needed. This also prevents people from just contructing their own pubkey packages and install them. We still allow removing gpg-pubkey packages but give a warning pointing people to rpmkeys. Resolves: #3344 --- lib/rpmte.cc | 10 +++++++--- tests/rpmsigdig.at | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/rpmte.cc b/lib/rpmte.cc index 6b98918752..70b1d8520f 100644 --- a/lib/rpmte.cc +++ b/lib/rpmte.cc @@ -159,9 +159,13 @@ static int addTE(rpmte p, Header h, fnpyKey key, rpmRelocation * relocs) p->arch = headerGetAsString(h, RPMTAG_ARCH); p->os = headerGetAsString(h, RPMTAG_OS); - /* gpg-pubkey's dont have os or arch (sigh), for others they are required */ - if (!rstreq(p->name, "gpg-pubkey") && (p->arch == NULL || p->os == NULL)) - goto exit; + if (p->arch == NULL || p->os == NULL) { + if (p->type == TR_REMOVED && rstreq(p->name, "gpg-pubkey")) { + rpmlog(RPMLOG_WARNING, _("erasing gpg-pubkey packages is deprecated; use rpmkeys --delete %s\n"), p->version); + } else { + goto exit; + } + } p->isSource = headerIsSource(h); diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at index c0bcced292..38885eb5da 100644 --- a/tests/rpmsigdig.at +++ b/tests/rpmsigdig.at @@ -130,7 +130,8 @@ runroot rpm -qa gpg-pubkey ], [0], [], -[]) +[warning: erasing gpg-pubkey packages is deprecated; use rpmkeys --delete 771b18d3d7baa28734333c424344591e1964c5fc +]) RPMTEST_CLEANUP AT_SETUP([rpmkeys migrate from keyid to fingerprint (rpmdb)]) From ade31e96dea2f91f9d2a470197b56e44fe1126ad Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Fri, 29 Nov 2024 15:22:53 +0100 Subject: [PATCH 3/5] Add test case for missing mandatory tags --- tests/rpmpython.at | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/rpmpython.at b/tests/rpmpython.at index 0fb516e3bf..4ab4fdc245 100644 --- a/tests/rpmpython.at +++ b/tests/rpmpython.at @@ -340,6 +340,26 @@ for e in ts: [adding upgrade to transaction failed] ) +RPMPY_TEST([add bogus package to transaction 3],[ + +for tag in ["os", "arch", "name", "version", "release"]: + h = ts.hdrFromFdno('${RPMDATA}/RPMS/hello-1.0-1.ppc64.rpm') + del h[tag] + try: + ts.addInstall(h, 'foo', 'u') + except rpm.error as err: + myprint(err) +for e in ts: + myprint(e.NEVRA()) +], +[adding upgrade to transaction failed +adding upgrade to transaction failed +adding upgrade to transaction failed +adding upgrade to transaction failed +adding upgrade to transaction failed +], +[]) + RPMPY_TEST([transaction element userdata],[ mydata = { 'foo': 'bar', 'capstest': 'lock' } ts.addInstall('${RPMDATA}/RPMS/foo-1.0-1.noarch.rpm', 'u') From 8425def4db39050c661718bb9982eeeabbc1a964 Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Fri, 29 Nov 2024 15:28:08 +0100 Subject: [PATCH 4/5] Don't allow installing gpg-pubkey packages People could install gpg-pubkey if they had the ARCH and OS tag set. Do not allow that. --- lib/rpmte.cc | 5 +++++ tests/rpmpython.at | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/lib/rpmte.cc b/lib/rpmte.cc index 70b1d8520f..f923e12845 100644 --- a/lib/rpmte.cc +++ b/lib/rpmte.cc @@ -167,6 +167,11 @@ static int addTE(rpmte p, Header h, fnpyKey key, rpmRelocation * relocs) } } + if (p->type != TR_REMOVED && rstreq(p->name, "gpg-pubkey")) { + rpmlog(RPMLOG_ERR, _("public keys can not be installed as gpg-pubkey packages; use rpmkeys --import for that\n")); + goto exit; + } + p->isSource = headerIsSource(h); p->NEVR = headerGetAsString(h, RPMTAG_NEVR); diff --git a/tests/rpmpython.at b/tests/rpmpython.at index 4ab4fdc245..a9dc8e3177 100644 --- a/tests/rpmpython.at +++ b/tests/rpmpython.at @@ -360,6 +360,23 @@ adding upgrade to transaction failed ], []) +RPMPY_TEST([add bogus package to transaction 4],[ + +h = ts.hdrFromFdno('${RPMDATA}/RPMS/hello-1.0-1.ppc64.rpm') +del h["name"] +h["name"] = "gpg-pubkey" +try: + ts.addInstall(h, 'foo', 'u') +except rpm.error as err: + myprint(err) +for e in ts: + myprint(e.NEVRA()) +], +[adding upgrade to transaction failed +], +[error: public keys can not be installed as gpg-pubkey packages; use rpmkeys --import for that +]) + RPMPY_TEST([transaction element userdata],[ mydata = { 'foo': 'bar', 'capstest': 'lock' } ts.addInstall('${RPMDATA}/RPMS/foo-1.0-1.noarch.rpm', 'u') From b6a579397317d9cbb98df12fd9079872637e2ff7 Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Fri, 29 Nov 2024 16:13:00 +0100 Subject: [PATCH 5/5] Ensure gpg-pubkey packages not having OS and ARCH Reject normal packages named gpg-pubkey which do have OS and ARCH. Only packages from properly imported keys don't. --- lib/keystore.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/keystore.cc b/lib/keystore.cc index a64ef07d6a..382a028e83 100644 --- a/lib/keystore.cc +++ b/lib/keystore.cc @@ -247,11 +247,17 @@ rpmRC keystore_rpmdb::load_keys(rpmtxn txn, rpmKeyring keyring) while ((h = rpmdbNextIterator(mi)) != NULL) { struct rpmtd_s pubkeys; const char *key; + char *nevr = headerGetAsString(h, RPMTAG_NEVR); - if (!headerGet(h, RPMTAG_PUBKEYS, &pubkeys, HEADERGET_MINMEM)) - continue; + /* don't allow normal packages named gpg-pubkey */ + if (headerIsEntry(h, RPMTAG_ARCH) || headerIsEntry(h, RPMTAG_OS) || + !headerGet(h, RPMTAG_PUBKEYS, &pubkeys, HEADERGET_MINMEM)) + { + rpmlog(RPMLOG_WARNING, _("%s is not a valid public key\n"), nevr); + free(nevr); + continue; + } - char *nevr = headerGetAsString(h, RPMTAG_NEVR); while ((key = rpmtdNextString(&pubkeys))) { uint8_t *pkt; size_t pktlen;