int _print_pkts = 0;
-static int closeFile(FD_t *fdp)
-{
- if (fdp == NULL || *fdp == NULL)
- return 1;
-
- /* close and reset *fdp to NULL */
- (void) Fclose(*fdp);
- *fdp = NULL;
- return 0;
-}
-
-/**
- */
-static int manageFile(FD_t *fdp, const char *fn, int flags)
-{
- FD_t fd;
-
- if (fdp == NULL || fn == NULL) /* programmer error */
- return 1;
-
- /* open a file and set *fdp */
- if (*fdp == NULL && fn != NULL) {
- fd = Fopen(fn, (flags & O_ACCMODE) == O_WRONLY ? "w.ufdio" : "r.ufdio");
- if (fd == NULL || Ferror(fd)) {
- rpmlog(RPMLOG_ERR, _("%s: open failed: %s\n"), fn,
- Fstrerror(fd));
- return 1;
- }
- *fdp = fd;
- return 0;
- }
-
- /* no operation */
- if (*fdp != NULL && fn != NULL)
- return 0;
-
- /* XXX never reached */
- return 1;
-}
-
-/**
- * Copy header+payload, calculating digest(s) on the fly.
- */
-static int copyFile(FD_t *sfdp, const char *sfnp,
- FD_t *tfdp, const char *tfnp)
-{
- unsigned char buf[BUFSIZ];
- ssize_t count;
- int rc = 1;
-
- if (manageFile(sfdp, sfnp, O_RDONLY))
- goto exit;
- if (manageFile(tfdp, tfnp, O_WRONLY|O_CREAT|O_TRUNC))
- goto exit;
-
- while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), *sfdp)) > 0)
- {
- if (Fwrite(buf, sizeof(buf[0]), count, *tfdp) != count) {
- rpmlog(RPMLOG_ERR, _("%s: Fwrite failed: %s\n"), tfnp,
- Fstrerror(*tfdp));
- goto exit;
- }
- }
- if (count < 0) {
- rpmlog(RPMLOG_ERR, _("%s: Fread failed: %s\n"), sfnp, Fstrerror(*sfdp));
- goto exit;
- }
- if (Fflush(*tfdp) != 0) {
- rpmlog(RPMLOG_ERR, _("%s: Fflush failed: %s\n"), tfnp,
- Fstrerror(*tfdp));
- }
-
- rc = 0;
-
-exit:
- if (*sfdp) (void) closeFile(sfdp);
- if (*tfdp) (void) closeFile(tfdp);
- return rc;
-}
-
-/**
- * Retrieve signer fingerprint from an OpenPGP signature tag.
- * @param sig signature header
- * @param sigtag signature tag
- * @retval signid signer fingerprint
- * @return 0 on success
- */
-static int getSignid(Header sig, rpmSigTag sigtag, pgpKeyID_t signid)
-{
- struct rpmtd_s pkt;
- int rc = 1;
-
- if (headerGet(sig, sigtag, &pkt, HEADERGET_DEFAULT) && pkt.data != NULL) {
- pgpDig dig = pgpNewDig();
-
- if (!pgpPrtPkts(pkt.data, pkt.count, dig, 0)) {
- memcpy(signid, dig->signature.signid, sizeof(dig->signature.signid));
- rc = 0;
- }
-
- dig = pgpFreeDig(dig);
- rpmtdFreeData(&pkt);
- }
- return rc;
-}
-
-/** \ingroup rpmcli
- * Create/modify elements in signature header.
- * @param ts transaction set
- * @param qva mode flags and parameters
- * @param argv array of package file names (NULL terminated)
- * @return 0 on success, -1 on error
- */
-static int rpmReSign(rpmts ts, QVA_t qva, ARGV_const_t argv)
-{
- FD_t fd = NULL;
- FD_t ofd = NULL;
- rpmlead lead;
- rpmSigTag sigtag;
- const char *rpm;
- char *sigtarget = NULL, *trpm = NULL;
- Header sigh = NULL;
- char * msg;
- int res = -1; /* assume failure */
- int deleting = (qva->qva_mode == RPMSIGN_DEL_SIGNATURE);
- int xx;
-
- if (argv)
- while ((rpm = *argv++) != NULL)
- {
- rpmRC rc;
- struct rpmtd_s utd;
-
- fprintf(stdout, "%s:\n", rpm);
-
- if (manageFile(&fd, rpm, O_RDONLY))
- goto exit;
-
- lead = rpmLeadNew();
-
- if ((rc = rpmLeadRead(fd, lead)) == RPMRC_OK) {
- const char *lmsg = NULL;
- rc = rpmLeadCheck(lead, &lmsg);
- if (rc != RPMRC_OK)
- rpmlog(RPMLOG_ERR, "%s: %s\n", rpm, lmsg);
- }
-
- if (rc != RPMRC_OK) {
- lead = rpmLeadFree(lead);
- goto exit;
- }
-
- msg = NULL;
- rc = rpmReadSignature(fd, &sigh, RPMSIGTYPE_HEADERSIG, &msg);
- switch (rc) {
- default:
- rpmlog(RPMLOG_ERR, _("%s: rpmReadSignature failed: %s"), rpm,
- (msg && *msg ? msg : "\n"));
- msg = _free(msg);
- goto exit;
- break;
- case RPMRC_OK:
- if (sigh == NULL) {
- rpmlog(RPMLOG_ERR, _("%s: No signature available\n"), rpm);
- goto exit;
- }
- break;
- }
- msg = _free(msg);
-
- /* ASSERT: ofd == NULL && sigtarget == NULL */
- ofd = rpmMkTempFile(NULL, &sigtarget);
- if (ofd == NULL || Ferror(ofd)) {
- rpmlog(RPMLOG_ERR, _("rpmMkTemp failed\n"));
- goto exit;
- }
- /* Write the header and archive to a temp file */
- if (copyFile(&fd, rpm, &ofd, sigtarget))
- goto exit;
- /* Both fd and ofd are now closed. sigtarget contains tempfile name. */
- /* ASSERT: fd == NULL && ofd == NULL */
-
- /* Dump the immutable region (if present). */
- if (headerGet(sigh, RPMTAG_HEADERSIGNATURES, &utd, HEADERGET_DEFAULT)) {
- struct rpmtd_s copytd;
- Header nh = headerNew();
- Header oh = headerCopyLoad(utd.data);
- HeaderIterator hi = headerInitIterator(oh);
- while (headerNext(hi, ©td)) {
- if (copytd.data)
- xx = headerPut(nh, ©td, HEADERPUT_DEFAULT);
- rpmtdFreeData(©td);
- }
- hi = headerFreeIterator(hi);
- oh = headerFree(oh);
-
- sigh = headerFree(sigh);
- sigh = headerLink(nh);
- nh = headerFree(nh);
- }
-
- /* Eliminate broken digest values. */
- xx = headerDel(sigh, RPMSIGTAG_BADSHA1_1);
- xx = headerDel(sigh, RPMSIGTAG_BADSHA1_2);
-
- /* Toss and recalculate header+payload size and digests. */
- {
- rpmSigTag const sigs[] = { RPMSIGTAG_SIZE,
- RPMSIGTAG_MD5,
- RPMSIGTAG_SHA1,
- };
- int nsigs = sizeof(sigs) / sizeof(rpmSigTag);
- for (int i = 0; i < nsigs; i++) {
- (void) headerDel(sigh, sigs[i]);
- if (rpmAddSignature(sigh, sigtarget, sigs[i], qva->passPhrase))
- goto exit;
- }
- }
-
- if (deleting) { /* Nuke all the signature tags. */
- xx = headerDel(sigh, RPMSIGTAG_GPG);
- xx = headerDel(sigh, RPMSIGTAG_DSA);
- xx = headerDel(sigh, RPMSIGTAG_PGP5);
- xx = headerDel(sigh, RPMSIGTAG_PGP);
- xx = headerDel(sigh, RPMSIGTAG_RSA);
- } else /* If gpg/pgp is configured, replace the signature. */
- if ((sigtag = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY)) > 0) {
- pgpKeyID_t oldsignid, newsignid;
-
- /* Grab the old signature fingerprint (if any) */
- memset(oldsignid, 0, sizeof(oldsignid));
- xx = getSignid(sigh, sigtag, oldsignid);
-
- switch (sigtag) {
- case RPMSIGTAG_DSA:
- xx = headerDel(sigh, RPMSIGTAG_GPG);
- break;
- case RPMSIGTAG_RSA:
- xx = headerDel(sigh, RPMSIGTAG_PGP);
- break;
- case RPMSIGTAG_GPG:
- xx = headerDel(sigh, RPMSIGTAG_DSA);
- case RPMSIGTAG_PGP5:
- case RPMSIGTAG_PGP:
- xx = headerDel(sigh, RPMSIGTAG_RSA);
- break;
- default:
- break;
- }
-
- xx = headerDel(sigh, sigtag);
- if (rpmAddSignature(sigh, sigtarget, sigtag, qva->passPhrase)) {
- goto exit;
- }
-
- /* If package was previously signed, check for same signer. */
- memset(newsignid, 0, sizeof(newsignid));
- if (memcmp(oldsignid, newsignid, sizeof(oldsignid))) {
-
- /* Grab the new signature fingerprint */
- xx = getSignid(sigh, sigtag, newsignid);
-
- /* If same signer, skip resigning the package. */
- if (!memcmp(oldsignid, newsignid, sizeof(oldsignid))) {
-
- char *signid = pgpHexStr(newsignid+4, sizeof(newsignid)-4);
- rpmlog(RPMLOG_WARNING,
- _("%s: was already signed by key ID %s, skipping\n"),
- rpm, signid);
- free(signid);
-
- /* Clean up intermediate target */
- xx = unlink(sigtarget);
- sigtarget = _free(sigtarget);
- continue;
- }
- }
- }
-
- /* Reallocate the signature into one contiguous region. */
- sigh = headerReload(sigh, RPMTAG_HEADERSIGNATURES);
- if (sigh == NULL) /* XXX can't happen */
- goto exit;
-
- rasprintf(&trpm, "%s.XXXXXX", rpm);
- ofd = rpmMkTemp(trpm);
- if (ofd == NULL || Ferror(ofd)) {
- rpmlog(RPMLOG_ERR, _("rpmMkTemp failed\n"));
- goto exit;
- }
-
- /* Write the lead/signature of the output rpm */
- rc = rpmLeadWrite(ofd, lead);
- lead = rpmLeadFree(lead);
- if (rc != RPMRC_OK) {
- rpmlog(RPMLOG_ERR, _("%s: writeLead failed: %s\n"), trpm,
- Fstrerror(ofd));
- goto exit;
- }
-
- if (rpmWriteSignature(ofd, sigh)) {
- rpmlog(RPMLOG_ERR, _("%s: rpmWriteSignature failed: %s\n"), trpm,
- Fstrerror(ofd));
- goto exit;
- }
-
- /* Append the header and archive from the temp file */
- /* ASSERT: fd == NULL && ofd != NULL */
- if (copyFile(&fd, sigtarget, &ofd, trpm))
- goto exit;
- /* Both fd and ofd are now closed. */
- /* ASSERT: fd == NULL && ofd == NULL */
-
- /* Move final target into place, restore file permissions. */
- {
- struct stat st;
- xx = stat(rpm, &st);
- xx = unlink(rpm);
- xx = rename(trpm, rpm);
- xx = chmod(rpm, st.st_mode);
- }
- trpm = _free(trpm);
-
- /* Clean up intermediate target */
- xx = unlink(sigtarget);
- sigtarget = _free(sigtarget);
- }
-
- res = 0;
-
-exit:
- if (fd) (void) closeFile(&fd);
- if (ofd) (void) closeFile(&ofd);
-
- sigh = rpmFreeSignature(sigh);
-
- if (sigtarget) {
- xx = unlink(sigtarget);
- sigtarget = _free(sigtarget);
- }
- if (trpm) {
- (void) unlink(trpm);
- free(trpm);
- }
-
- return res;
-}
-
static int doImport(rpmts ts, const char *fn, char *buf, ssize_t blen)
{
char const * const pgpmark = "-----BEGIN PGP ";
rpmKeyringFree(keyring);
return res;
}
-
-int rpmcliSign(rpmts ts, QVA_t qva, ARGV_const_t argv)
-{
-
- if (argv == NULL) return -1;
-
- switch (qva->qva_mode) {
- case RPMSIGN_CHK_SIGNATURE:
- return rpmcliVerifySignatures(ts, qva, argv);
- break;
- case RPMSIGN_IMPORT_PUBKEY:
- return rpmcliImportPubkeys(ts, argv);
- break;
- case RPMSIGN_NEW_SIGNATURE:
- case RPMSIGN_ADD_SIGNATURE:
- case RPMSIGN_DEL_SIGNATURE:
- return rpmReSign(ts, qva, argv);
- break;
- default:
- break;
- }
-
- return -1;
-}
--- /dev/null
+/** \ingroup rpmcli
+ * \file lib/rpmchecksig.c
+ * Verify the signature of a package.
+ */
+
+#include "system.h"
+
+#include <rpm/rpmlib.h> /* RPMSIGTAG & related */
+#include <rpm/rpmpgp.h>
+#include <rpm/rpmcli.h>
+#include <rpm/rpmfileutil.h> /* rpmMkTemp() */
+#include <rpm/rpmlog.h>
+#include <rpm/rpmstring.h>
+
+#include "rpmio/digest.h"
+#include "lib/rpmlead.h"
+#include "lib/signature.h"
+
+#include "debug.h"
+
+static int closeFile(FD_t *fdp)
+{
+ if (fdp == NULL || *fdp == NULL)
+ return 1;
+
+ /* close and reset *fdp to NULL */
+ (void) Fclose(*fdp);
+ *fdp = NULL;
+ return 0;
+}
+
+/**
+ */
+static int manageFile(FD_t *fdp, const char *fn, int flags)
+{
+ FD_t fd;
+
+ if (fdp == NULL || fn == NULL) /* programmer error */
+ return 1;
+
+ /* open a file and set *fdp */
+ if (*fdp == NULL && fn != NULL) {
+ fd = Fopen(fn, (flags & O_ACCMODE) == O_WRONLY ? "w.ufdio" : "r.ufdio");
+ if (fd == NULL || Ferror(fd)) {
+ rpmlog(RPMLOG_ERR, _("%s: open failed: %s\n"), fn,
+ Fstrerror(fd));
+ return 1;
+ }
+ *fdp = fd;
+ return 0;
+ }
+
+ /* no operation */
+ if (*fdp != NULL && fn != NULL)
+ return 0;
+
+ /* XXX never reached */
+ return 1;
+}
+
+/**
+ * Copy header+payload, calculating digest(s) on the fly.
+ */
+static int copyFile(FD_t *sfdp, const char *sfnp,
+ FD_t *tfdp, const char *tfnp)
+{
+ unsigned char buf[BUFSIZ];
+ ssize_t count;
+ int rc = 1;
+
+ if (manageFile(sfdp, sfnp, O_RDONLY))
+ goto exit;
+ if (manageFile(tfdp, tfnp, O_WRONLY|O_CREAT|O_TRUNC))
+ goto exit;
+
+ while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), *sfdp)) > 0)
+ {
+ if (Fwrite(buf, sizeof(buf[0]), count, *tfdp) != count) {
+ rpmlog(RPMLOG_ERR, _("%s: Fwrite failed: %s\n"), tfnp,
+ Fstrerror(*tfdp));
+ goto exit;
+ }
+ }
+ if (count < 0) {
+ rpmlog(RPMLOG_ERR, _("%s: Fread failed: %s\n"), sfnp, Fstrerror(*sfdp));
+ goto exit;
+ }
+ if (Fflush(*tfdp) != 0) {
+ rpmlog(RPMLOG_ERR, _("%s: Fflush failed: %s\n"), tfnp,
+ Fstrerror(*tfdp));
+ }
+
+ rc = 0;
+
+exit:
+ if (*sfdp) (void) closeFile(sfdp);
+ if (*tfdp) (void) closeFile(tfdp);
+ return rc;
+}
+
+/**
+ * Retrieve signer fingerprint from an OpenPGP signature tag.
+ * @param sig signature header
+ * @param sigtag signature tag
+ * @retval signid signer fingerprint
+ * @return 0 on success
+ */
+static int getSignid(Header sig, rpmSigTag sigtag, pgpKeyID_t signid)
+{
+ struct rpmtd_s pkt;
+ int rc = 1;
+
+ if (headerGet(sig, sigtag, &pkt, HEADERGET_DEFAULT) && pkt.data != NULL) {
+ pgpDig dig = pgpNewDig();
+
+ if (!pgpPrtPkts(pkt.data, pkt.count, dig, 0)) {
+ memcpy(signid, dig->signature.signid, sizeof(dig->signature.signid));
+ rc = 0;
+ }
+
+ dig = pgpFreeDig(dig);
+ rpmtdFreeData(&pkt);
+ }
+ return rc;
+}
+
+/** \ingroup rpmcli
+ * Create/modify elements in signature header.
+ * @param ts transaction set
+ * @param qva mode flags and parameters
+ * @param argv array of package file names (NULL terminated)
+ * @return 0 on success, -1 on error
+ */
+static int rpmReSign(rpmts ts, QVA_t qva, ARGV_const_t argv)
+{
+ FD_t fd = NULL;
+ FD_t ofd = NULL;
+ rpmlead lead;
+ rpmSigTag sigtag;
+ const char *rpm;
+ char *sigtarget = NULL, *trpm = NULL;
+ Header sigh = NULL;
+ char * msg;
+ int res = -1; /* assume failure */
+ int deleting = (qva->qva_mode == RPMSIGN_DEL_SIGNATURE);
+ int xx;
+
+ if (argv)
+ while ((rpm = *argv++) != NULL)
+ {
+ rpmRC rc;
+ struct rpmtd_s utd;
+
+ fprintf(stdout, "%s:\n", rpm);
+
+ if (manageFile(&fd, rpm, O_RDONLY))
+ goto exit;
+
+ lead = rpmLeadNew();
+
+ if ((rc = rpmLeadRead(fd, lead)) == RPMRC_OK) {
+ const char *lmsg = NULL;
+ rc = rpmLeadCheck(lead, &lmsg);
+ if (rc != RPMRC_OK)
+ rpmlog(RPMLOG_ERR, "%s: %s\n", rpm, lmsg);
+ }
+
+ if (rc != RPMRC_OK) {
+ lead = rpmLeadFree(lead);
+ goto exit;
+ }
+
+ msg = NULL;
+ rc = rpmReadSignature(fd, &sigh, RPMSIGTYPE_HEADERSIG, &msg);
+ switch (rc) {
+ default:
+ rpmlog(RPMLOG_ERR, _("%s: rpmReadSignature failed: %s"), rpm,
+ (msg && *msg ? msg : "\n"));
+ msg = _free(msg);
+ goto exit;
+ break;
+ case RPMRC_OK:
+ if (sigh == NULL) {
+ rpmlog(RPMLOG_ERR, _("%s: No signature available\n"), rpm);
+ goto exit;
+ }
+ break;
+ }
+ msg = _free(msg);
+
+ /* ASSERT: ofd == NULL && sigtarget == NULL */
+ ofd = rpmMkTempFile(NULL, &sigtarget);
+ if (ofd == NULL || Ferror(ofd)) {
+ rpmlog(RPMLOG_ERR, _("rpmMkTemp failed\n"));
+ goto exit;
+ }
+ /* Write the header and archive to a temp file */
+ if (copyFile(&fd, rpm, &ofd, sigtarget))
+ goto exit;
+ /* Both fd and ofd are now closed. sigtarget contains tempfile name. */
+ /* ASSERT: fd == NULL && ofd == NULL */
+
+ /* Dump the immutable region (if present). */
+ if (headerGet(sigh, RPMTAG_HEADERSIGNATURES, &utd, HEADERGET_DEFAULT)) {
+ struct rpmtd_s copytd;
+ Header nh = headerNew();
+ Header oh = headerCopyLoad(utd.data);
+ HeaderIterator hi = headerInitIterator(oh);
+ while (headerNext(hi, ©td)) {
+ if (copytd.data)
+ xx = headerPut(nh, ©td, HEADERPUT_DEFAULT);
+ rpmtdFreeData(©td);
+ }
+ hi = headerFreeIterator(hi);
+ oh = headerFree(oh);
+
+ sigh = headerFree(sigh);
+ sigh = headerLink(nh);
+ nh = headerFree(nh);
+ }
+
+ /* Eliminate broken digest values. */
+ xx = headerDel(sigh, RPMSIGTAG_BADSHA1_1);
+ xx = headerDel(sigh, RPMSIGTAG_BADSHA1_2);
+
+ /* Toss and recalculate header+payload size and digests. */
+ {
+ rpmSigTag const sigs[] = { RPMSIGTAG_SIZE,
+ RPMSIGTAG_MD5,
+ RPMSIGTAG_SHA1,
+ };
+ int nsigs = sizeof(sigs) / sizeof(rpmSigTag);
+ for (int i = 0; i < nsigs; i++) {
+ (void) headerDel(sigh, sigs[i]);
+ if (rpmAddSignature(sigh, sigtarget, sigs[i], qva->passPhrase))
+ goto exit;
+ }
+ }
+
+ if (deleting) { /* Nuke all the signature tags. */
+ xx = headerDel(sigh, RPMSIGTAG_GPG);
+ xx = headerDel(sigh, RPMSIGTAG_DSA);
+ xx = headerDel(sigh, RPMSIGTAG_PGP5);
+ xx = headerDel(sigh, RPMSIGTAG_PGP);
+ xx = headerDel(sigh, RPMSIGTAG_RSA);
+ } else /* If gpg/pgp is configured, replace the signature. */
+ if ((sigtag = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY)) > 0) {
+ pgpKeyID_t oldsignid, newsignid;
+
+ /* Grab the old signature fingerprint (if any) */
+ memset(oldsignid, 0, sizeof(oldsignid));
+ xx = getSignid(sigh, sigtag, oldsignid);
+
+ switch (sigtag) {
+ case RPMSIGTAG_DSA:
+ xx = headerDel(sigh, RPMSIGTAG_GPG);
+ break;
+ case RPMSIGTAG_RSA:
+ xx = headerDel(sigh, RPMSIGTAG_PGP);
+ break;
+ case RPMSIGTAG_GPG:
+ xx = headerDel(sigh, RPMSIGTAG_DSA);
+ case RPMSIGTAG_PGP5:
+ case RPMSIGTAG_PGP:
+ xx = headerDel(sigh, RPMSIGTAG_RSA);
+ break;
+ default:
+ break;
+ }
+
+ xx = headerDel(sigh, sigtag);
+ if (rpmAddSignature(sigh, sigtarget, sigtag, qva->passPhrase)) {
+ goto exit;
+ }
+
+ /* If package was previously signed, check for same signer. */
+ memset(newsignid, 0, sizeof(newsignid));
+ if (memcmp(oldsignid, newsignid, sizeof(oldsignid))) {
+
+ /* Grab the new signature fingerprint */
+ xx = getSignid(sigh, sigtag, newsignid);
+
+ /* If same signer, skip resigning the package. */
+ if (!memcmp(oldsignid, newsignid, sizeof(oldsignid))) {
+
+ char *signid = pgpHexStr(newsignid+4, sizeof(newsignid)-4);
+ rpmlog(RPMLOG_WARNING,
+ _("%s: was already signed by key ID %s, skipping\n"),
+ rpm, signid);
+ free(signid);
+
+ /* Clean up intermediate target */
+ xx = unlink(sigtarget);
+ sigtarget = _free(sigtarget);
+ continue;
+ }
+ }
+ }
+
+ /* Reallocate the signature into one contiguous region. */
+ sigh = headerReload(sigh, RPMTAG_HEADERSIGNATURES);
+ if (sigh == NULL) /* XXX can't happen */
+ goto exit;
+
+ rasprintf(&trpm, "%s.XXXXXX", rpm);
+ ofd = rpmMkTemp(trpm);
+ if (ofd == NULL || Ferror(ofd)) {
+ rpmlog(RPMLOG_ERR, _("rpmMkTemp failed\n"));
+ goto exit;
+ }
+
+ /* Write the lead/signature of the output rpm */
+ rc = rpmLeadWrite(ofd, lead);
+ lead = rpmLeadFree(lead);
+ if (rc != RPMRC_OK) {
+ rpmlog(RPMLOG_ERR, _("%s: writeLead failed: %s\n"), trpm,
+ Fstrerror(ofd));
+ goto exit;
+ }
+
+ if (rpmWriteSignature(ofd, sigh)) {
+ rpmlog(RPMLOG_ERR, _("%s: rpmWriteSignature failed: %s\n"), trpm,
+ Fstrerror(ofd));
+ goto exit;
+ }
+
+ /* Append the header and archive from the temp file */
+ /* ASSERT: fd == NULL && ofd != NULL */
+ if (copyFile(&fd, sigtarget, &ofd, trpm))
+ goto exit;
+ /* Both fd and ofd are now closed. */
+ /* ASSERT: fd == NULL && ofd == NULL */
+
+ /* Move final target into place, restore file permissions. */
+ {
+ struct stat st;
+ xx = stat(rpm, &st);
+ xx = unlink(rpm);
+ xx = rename(trpm, rpm);
+ xx = chmod(rpm, st.st_mode);
+ }
+ trpm = _free(trpm);
+
+ /* Clean up intermediate target */
+ xx = unlink(sigtarget);
+ sigtarget = _free(sigtarget);
+ }
+
+ res = 0;
+
+exit:
+ if (fd) (void) closeFile(&fd);
+ if (ofd) (void) closeFile(&ofd);
+
+ sigh = rpmFreeSignature(sigh);
+
+ if (sigtarget) {
+ xx = unlink(sigtarget);
+ sigtarget = _free(sigtarget);
+ }
+ if (trpm) {
+ (void) unlink(trpm);
+ free(trpm);
+ }
+
+ return res;
+}
+
+int rpmcliSign(rpmts ts, QVA_t qva, ARGV_const_t argv)
+{
+ if (argv == NULL) return -1;
+
+ switch (qva->qva_mode) {
+ case RPMSIGN_CHK_SIGNATURE:
+ return rpmcliVerifySignatures(ts, qva, argv);
+ break;
+ case RPMSIGN_IMPORT_PUBKEY:
+ return rpmcliImportPubkeys(ts, argv);
+ break;
+ case RPMSIGN_NEW_SIGNATURE:
+ case RPMSIGN_ADD_SIGNATURE:
+ case RPMSIGN_DEL_SIGNATURE:
+ return rpmReSign(ts, qva, argv);
+ break;
+ default:
+ break;
+ }
+
+ return -1;
+}