138 lines
3.6 KiB
Diff
138 lines
3.6 KiB
Diff
diff --git a/lib/rpmchecksig.c b/lib/rpmchecksig.c
|
|
index babbe76..d6150a4 100644
|
|
--- a/lib/rpmchecksig.c
|
|
+++ b/lib/rpmchecksig.c
|
|
@@ -381,37 +381,59 @@ exit:
|
|
return res;
|
|
}
|
|
|
|
-/** \ingroup rpmcli
|
|
- * Import public key(s).
|
|
- * @todo Implicit --update policy for gpg-pubkey headers.
|
|
- * @param ts transaction set
|
|
- * @param qva mode flags and parameters
|
|
- * @param argv array of pubkey file names (NULL terminated)
|
|
- * @return 0 on success
|
|
- */
|
|
-static int rpmcliImportPubkeys(const rpmts ts, QVA_t qva, ARGV_const_t argv)
|
|
+static int doImport(rpmts ts, const char *fn, char *buf, ssize_t blen)
|
|
{
|
|
- const char * fn;
|
|
- unsigned char * pkt = NULL;
|
|
- size_t pktlen = 0;
|
|
- char * t = NULL;
|
|
+ char const * const pgpmark = "-----BEGIN PGP ";
|
|
+ size_t marklen = strlen(pgpmark);
|
|
int res = 0;
|
|
- rpmRC rpmrc;
|
|
- int rc;
|
|
-
|
|
- if (argv == NULL) return res;
|
|
+ int keyno = 1;
|
|
+ char *start = strstr(buf, pgpmark);
|
|
+
|
|
+ while (start) {
|
|
+ uint8_t *pkt = NULL;
|
|
+ size_t pktlen = 0;
|
|
+
|
|
+ /* Read pgp packet. */
|
|
+ if (pgpParsePkts(start, &pkt, &pktlen) == PGPARMOR_PUBKEY) {
|
|
+ /* Import pubkey packet(s). */
|
|
+ if (rpmtsImportPubkey(ts, pkt, pktlen) != RPMRC_OK) {
|
|
+ rpmlog(RPMLOG_ERR, _("%s: key %d import failed.\n"), fn, keyno);
|
|
+ res++;
|
|
+ }
|
|
+ } else {
|
|
+ rpmlog(RPMLOG_ERR, _("%s: key %d not an armored public key.\n"),
|
|
+ fn, keyno);
|
|
+ res++;
|
|
+ }
|
|
+
|
|
+ /* See if there are more keys in the buffer */
|
|
+ if (start + marklen < buf + blen) {
|
|
+ start = strstr(start + marklen, pgpmark);
|
|
+ } else {
|
|
+ start = NULL;
|
|
+ }
|
|
|
|
- while ((fn = *argv++) != NULL) {
|
|
+ keyno++;
|
|
+ free(pkt);
|
|
+ }
|
|
+ return res;
|
|
+}
|
|
|
|
- rpmtsClean(ts);
|
|
- pkt = _free(pkt);
|
|
- t = _free(t);
|
|
+static int rpmcliImportPubkeys(rpmts ts, ARGV_const_t argv)
|
|
+{
|
|
+ int res = 0;
|
|
+ for (ARGV_const_t arg = argv; arg && *arg; arg++) {
|
|
+ const char *fn = *arg;
|
|
+ uint8_t *buf = NULL;
|
|
+ ssize_t blen = 0;
|
|
+ char *t = NULL;
|
|
+ int iorc;
|
|
|
|
/* If arg looks like a keyid, then attempt keyserver retrieve. */
|
|
- if (fn[0] == '0' && fn[1] == 'x') {
|
|
- const char * s;
|
|
+ if (rstreqn(fn, "0x", 2)) {
|
|
+ const char * s = fn + 2;
|
|
int i;
|
|
- for (i = 0, s = fn+2; *s && isxdigit(*s); s++, i++)
|
|
+ for (i = 0; *s && isxdigit(*s); s++, i++)
|
|
{};
|
|
if (i == 8 || i == 16) {
|
|
t = rpmExpand("%{_hkp_keyserver_query}", fn+2, NULL);
|
|
@@ -420,30 +442,18 @@ static int rpmcliImportPubkeys(const rpmts ts, QVA_t qva, ARGV_const_t argv)
|
|
}
|
|
}
|
|
|
|
- /* Read pgp packet. */
|
|
- if ((rc = pgpReadPkts(fn, &pkt, &pktlen)) <= 0) {
|
|
- rpmlog(RPMLOG_ERR, _("%s: import read failed(%d).\n"), fn, rc);
|
|
- res++;
|
|
- continue;
|
|
- }
|
|
- if (rc != PGPARMOR_PUBKEY) {
|
|
- rpmlog(RPMLOG_ERR, _("%s: not an armored public key.\n"), fn);
|
|
- res++;
|
|
- continue;
|
|
- }
|
|
-
|
|
- /* Import pubkey packet(s). */
|
|
- if ((rpmrc = rpmtsImportPubkey(ts, pkt, pktlen)) != RPMRC_OK) {
|
|
- rpmlog(RPMLOG_ERR, _("%s: import failed.\n"), fn);
|
|
+ /* Read the file and try to import all contained keys */
|
|
+ iorc = rpmioSlurp(fn, &buf, &blen);
|
|
+ if (iorc || buf == NULL || blen < 64) {
|
|
+ rpmlog(RPMLOG_ERR, _("%s: import read failed(%d).\n"), fn, iorc);
|
|
res++;
|
|
- continue;
|
|
+ } else {
|
|
+ res += doImport(ts, fn, (char *)buf, blen);
|
|
}
|
|
-
|
|
+
|
|
+ free(t);
|
|
+ free(buf);
|
|
}
|
|
-
|
|
-rpmtsClean(ts);
|
|
- pkt = _free(pkt);
|
|
- t = _free(t);
|
|
return res;
|
|
}
|
|
|
|
@@ -799,7 +809,7 @@ int rpmcliSign(rpmts ts, QVA_t qva, ARGV_const_t argv)
|
|
case RPMSIGN_CHK_SIGNATURE:
|
|
break;
|
|
case RPMSIGN_IMPORT_PUBKEY:
|
|
- return rpmcliImportPubkeys(ts, qva, argv);
|
|
+ return rpmcliImportPubkeys(ts, argv);
|
|
break;
|
|
case RPMSIGN_NEW_SIGNATURE:
|
|
case RPMSIGN_ADD_SIGNATURE:
|