@@ -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