Skip to content

Commit edbcb45

Browse files
mlschroepmatilai
authored andcommitted
Merge keys and update the database in rpmtsImportPubkey()
1 parent 0c52a52 commit edbcb45

File tree

1 file changed

+66
-9
lines changed

1 file changed

+66
-9
lines changed

lib/rpmts.c

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -577,29 +577,79 @@ rpmRC rpmtsImportHeader(rpmtxn txn, Header h, rpmFlags flags)
577577
return rc;
578578
}
579579

580-
static rpmRC rpmtsImportFSKey(rpmtxn txn, Header h, rpmFlags flags)
580+
static rpmRC rpmtsImportFSKey(rpmtxn txn, Header h, rpmFlags flags, int replace)
581581
{
582582
rpmRC rc = RPMRC_FAIL;
583583
char *keyfmt = headerFormat(h, "%{nvr}.key", NULL);
584584
char *keyval = headerGetAsString(h, RPMTAG_DESCRIPTION);
585585
char *path = rpmGenPath(rpmtsRootDir(txn->ts), "%{_keyringpath}/", keyfmt);
586+
char *tmppath = NULL;
586587

587-
FD_t fd = Fopen(path, "wx");
588+
if (replace) {
589+
rasprintf(&tmppath, "%s.new", path);
590+
unlink(tmppath);
591+
}
592+
593+
FD_t fd = Fopen(tmppath ? tmppath : path, "wx");
588594
if (fd) {
589595
size_t keylen = strlen(keyval);
590596
if (Fwrite(keyval, 1, keylen, fd) == keylen)
591597
rc = RPMRC_OK;
592598
Fclose(fd);
593599
}
600+
if (!rc && tmppath && rename(tmppath, path) != 0)
601+
rc = RPMRC_FAIL;
594602

595603
if (rc) {
596604
rpmlog(RPMLOG_ERR, _("failed to import key: %s: %s\n"),
597-
path, strerror(errno));
605+
tmppath ? tmppath : path, strerror(errno));
606+
if (tmppath)
607+
unlink(tmppath);
608+
}
609+
610+
if (!rc && replace) {
611+
/* find and delete the old pubkey entry */
612+
char *keyglob = headerFormat(h, "%{name}-%{version}-*.key", NULL);
613+
ARGV_t files = NULL;
614+
char *pkpath = rpmGenPath(rpmtsRootDir(txn->ts), "%{_keyringpath}/", keyglob);
615+
if (rpmGlob(pkpath, NULL, &files) == 0) {
616+
char **f;
617+
for (f = files; *f; f++) {
618+
char *bf = strrchr(*f, '/');
619+
if (bf && strcmp(bf + 1, keyfmt) != 0)
620+
unlink(*f);
621+
}
622+
}
623+
free(pkpath);
624+
argvFree(files);
625+
free(keyglob);
598626
}
599627

600628
free(path);
601629
free(keyval);
602630
free(keyfmt);
631+
free(tmppath);
632+
return rc;
633+
}
634+
635+
static rpmRC rpmtsImportDBKey(rpmtxn txn, Header h, rpmFlags flags, int replace)
636+
{
637+
rpmRC rc = rpmtsImportHeader(txn, h, 0);
638+
639+
if (!rc && replace) {
640+
/* find and delete the old pubkey entry */
641+
unsigned int newinstance = headerGetInstance(h), otherinstance = 0;
642+
char *label = headerFormat(h, "%{name}-%{version}", NULL);
643+
Header oh;
644+
rpmdbMatchIterator mi = rpmtsInitIterator(txn->ts, RPMDBI_LABEL, label, 0);
645+
while (otherinstance == 0 && (oh = rpmdbNextIterator(mi)) != NULL)
646+
if (headerGetInstance(oh) != newinstance)
647+
otherinstance = headerGetInstance(oh);
648+
rpmdbFreeIterator(mi);
649+
if (otherinstance)
650+
rpmdbRemove(rpmtsGetRdb(txn->ts), otherinstance);
651+
}
652+
603653
return rc;
604654
}
605655

@@ -644,17 +694,24 @@ rpmRC rpmtsImportPubkey(const rpmts ts, const unsigned char * pkt, size_t pktlen
644694

645695
oldkey = rpmKeyringLookupKey(keyring, pubkey);
646696
if (oldkey) {
647-
rc = RPMRC_OK; /* already have key */
648-
goto exit;
697+
rpmPubkey mergedkey = NULL;
698+
if (rpmPubkeyMerge(oldkey, pubkey, &mergedkey) != RPMRC_OK)
699+
goto exit;
700+
if (!mergedkey) {
701+
rc = RPMRC_OK; /* already have key */
702+
goto exit;
703+
}
704+
rpmPubkeyFree(pubkey);
705+
pubkey = mergedkey;
649706
}
650707
if ((subkeys = rpmGetSubkeys(pubkey, &subkeysCount)) == NULL)
651708
goto exit;
652709

653-
krc = rpmKeyringAddKey(keyring, pubkey);
710+
krc = rpmKeyringModify(keyring, pubkey, oldkey ? RPMKEYRING_REPLACE : RPMKEYRING_ADD);
654711
if (krc < 0)
655712
goto exit;
656713
for (i = 0; i < subkeysCount; i++)
657-
rpmKeyringAddKey(keyring, subkeys[i]);
714+
rpmKeyringModify(keyring, subkeys[i], oldkey ? RPMKEYRING_REPLACE : RPMKEYRING_ADD);
658715

659716
/* If we dont already have the key, make a persistent record of it */
660717
if (krc == 0) {
@@ -670,9 +727,9 @@ rpmRC rpmtsImportPubkey(const rpmts ts, const unsigned char * pkt, size_t pktlen
670727
rc = RPMRC_OK;
671728
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) {
672729
if (ts->keyringtype == KEYRING_FS)
673-
rc = rpmtsImportFSKey(txn, h, 0);
730+
rc = rpmtsImportFSKey(txn, h, 0, oldkey ? 1 : 0);
674731
else
675-
rc = rpmtsImportHeader(txn, h, 0);
732+
rc = rpmtsImportDBKey(txn, h, 0, oldkey ? 1 : 0);
676733
}
677734
} else {
678735
rc = RPMRC_OK; /* already have key */

0 commit comments

Comments
 (0)