static PyObject * hdrCompressFilelist(hdrObject * s) { DEPRECATED_METHOD("use hdr.convert() instead"); headerConvert(s->h, HEADERCONV_COMPRESSFILELIST); Py_RETURN_NONE; }
/* * Source rpms only contain basenames, on install the full paths are * constructed with %{_specdir} and %{_sourcedir} macros. Because * of that regular relocation wont work, we need to do it the hard * way. Return spec file index on success, -1 on errors. */ int rpmRelocateSrpmFileList(Header h, const char *rootDir) { int specix = headerFindSpec(h); if (specix >= 0) { const char *bn; struct rpmtd_s filenames; /* save original file names */ saveOrig(h); headerDel(h, RPMTAG_BASENAMES); headerDel(h, RPMTAG_DIRNAMES); headerDel(h, RPMTAG_DIRINDEXES); /* Macros need to be added before trying to create directories */ rpmInstallLoadMacros(h, 1); /* ALLOC is needed as we modify the header */ headerGet(h, RPMTAG_ORIGBASENAMES, &filenames, HEADERGET_ALLOC); for (int i = 0; (bn = rpmtdNextString(&filenames)); i++) { int spec = (i == specix); char *fn = rpmGenPath(rootDir, spec ? "%{_specdir}" : "%{_sourcedir}", bn); headerPutString(h, RPMTAG_OLDFILENAMES, fn); free(fn); } rpmtdFreeData(&filenames); headerConvert(h, HEADERCONV_COMPRESSFILELIST); rpmInstallLoadMacros(h, 0); } return specix; }
static PyObject * hdrExpandFilelist(hdrObject * s) { DEPRECATED_METHOD("use hdr.convert() instead"); headerConvert(s->h, HEADERCONV_EXPANDFILELIST); Py_RETURN_NONE; }
static PyObject *hdrConvert(hdrObject *self, PyObject *args, PyObject *kwds) { char *kwlist[] = {"op", NULL}; int op = -1; if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &op)) { return NULL; } return PyBool_FromLong(headerConvert(self->h, op)); }
/* make a header with _all_ the tags we need */ static PyObject * hdrFullFilelist(hdrObject * s) { rpmtd fileNames = rpmtdNew(); Header h = s->h; DEPRECATED_METHOD("obsolete method"); if (!headerIsEntry (h, RPMTAG_BASENAMES) || !headerIsEntry (h, RPMTAG_DIRNAMES) || !headerIsEntry (h, RPMTAG_DIRINDEXES)) headerConvert(h, HEADERCONV_COMPRESSFILELIST); if (headerGet(h, RPMTAG_FILENAMES, fileNames, HEADERGET_EXT)) { rpmtdSetTag(fileNames, RPMTAG_OLDFILENAMES); headerPut(h, fileNames, HEADERPUT_DEFAULT); rpmtdFreeData(fileNames); } rpmtdFree(fileNames); Py_RETURN_NONE; }
uint32_t VerifyRpmSig( rpmKeyring pKeyring, const char* pszPkgFile ) { uint32_t dwError = 0; FD_t pFD_t = NULL; rpmts pTS = NULL; rpmtd pTD = NULL; Header pPkgHeader = NULL; pgpDig pDigest = NULL; if(!pKeyring || IsNullOrEmptyString(pszPkgFile)) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } pFD_t = Fopen(pszPkgFile, "r.fdio"); if(!pFD_t) { dwError = errno; BAIL_ON_TDNF_SYSTEM_ERROR(dwError); } pTS = rpmtsCreate(); if(!pTS) { dwError = ERROR_TDNF_RPMTS_CREATE_FAILED; BAIL_ON_TDNF_RPM_ERROR(dwError); } rpmtsSetVSFlags (pTS, _RPMVSF_NOSIGNATURES); pTD = rpmtdNew(); if(!pTD) { dwError = ERROR_TDNF_RPMTD_CREATE_FAILED; BAIL_ON_TDNF_RPM_ERROR(dwError); } dwError = rpmReadPackageFile(pTS, pFD_t, pszPkgFile, &pPkgHeader); BAIL_ON_TDNF_RPM_ERROR(dwError); if(!headerConvert(pPkgHeader, HEADERCONV_RETROFIT_V3)) { dwError = ERROR_TDNF_RPM_HEADER_CONVERT_FAILED; BAIL_ON_TDNF_RPM_ERROR(dwError); } if(!headerGet(pPkgHeader, RPMTAG_RSAHEADER, pTD, HEADERGET_MINMEM)) { dwError = ERROR_TDNF_RPM_GET_RSAHEADER_FAILED; BAIL_ON_TDNF_ERROR(dwError); } pDigest = pgpNewDig(); if(pgpPrtPkts(pTD->data, pTD->count, pDigest, 0)) { dwError = ERROR_TDNF_RPM_GPG_PARSE_FAILED; BAIL_ON_TDNF_ERROR(dwError); } if(rpmKeyringLookup(pKeyring, pDigest) != RPMRC_OK) { dwError = ERROR_TDNF_RPM_GPG_NO_MATCH; BAIL_ON_TDNF_ERROR(dwError); } cleanup: if(pFD_t) { Fclose(pFD_t); } if(pDigest) { pgpFreeDig(pDigest); } if(pPkgHeader) { headerFree(pPkgHeader); } if(pTD) { rpmtdFree(pTD); } if(pTS) { rpmtsFree(pTS); } return dwError; error: goto cleanup; }
static rpmRC rpmpkgRead(rpmKeyring keyring, rpmVSFlags vsflags, FD_t fd, Header * hdrp, unsigned int *keyidp, char **msg) { pgpDigParams sig = NULL; Header sigh = NULL; rpmTagVal sigtag; struct rpmtd_s sigtd; struct sigtInfo_s sinfo; Header h = NULL; rpmRC rc = RPMRC_FAIL; /* assume failure */ int leadtype = -1; headerGetFlags hgeflags = HEADERGET_DEFAULT; if (hdrp) *hdrp = NULL; rpmtdReset(&sigtd); if ((rc = rpmLeadRead(fd, &leadtype, msg)) != RPMRC_OK) { /* Avoid message spew on manifests */ if (rc == RPMRC_NOTFOUND) { *msg = _free(*msg); } goto exit; } /* Read the signature header. */ rc = rpmReadSignature(fd, &sigh, msg); if (rc != RPMRC_OK) { goto exit; } #define _chk(_mask, _tag) \ (sigtag == 0 && !(vsflags & (_mask)) && headerIsEntry(sigh, (_tag))) /* * Figger the most effective means of verification available, prefer * signatures over digests. Legacy header+payload entries are not used. * DSA will be preferred over RSA if both exist because tested first. */ sigtag = 0; if (_chk(RPMVSF_NODSAHEADER, RPMSIGTAG_DSA)) { sigtag = RPMSIGTAG_DSA; } else if (_chk(RPMVSF_NORSAHEADER, RPMSIGTAG_RSA)) { sigtag = RPMSIGTAG_RSA; } else if (_chk(RPMVSF_NOSHA1HEADER, RPMSIGTAG_SHA1)) { sigtag = RPMSIGTAG_SHA1; } /* Read the metadata, computing digest(s) on the fly. */ h = NULL; rc = rpmpkgReadHeader(fd, &h, msg); if (rc != RPMRC_OK || h == NULL) { goto exit; } /* Any digests or signatures to check? */ if (sigtag == 0) { rc = RPMRC_OK; goto exit; } /* Free up any previous "ok" message before signature/digest check */ *msg = _free(*msg); /* Retrieve the tag parameters from the signature header. */ if (!headerGet(sigh, sigtag, &sigtd, hgeflags)) { rc = RPMRC_FAIL; goto exit; } if (rpmSigInfoParse(&sigtd, "package", &sinfo, &sig, msg) == RPMRC_OK) { struct rpmtd_s utd; DIGEST_CTX ctx = rpmDigestInit(sinfo.hashalgo, RPMDIGEST_NONE); if (headerGet(h, RPMTAG_HEADERIMMUTABLE, &utd, hgeflags)) { rpmDigestUpdate(ctx, rpm_header_magic, sizeof(rpm_header_magic)); rpmDigestUpdate(ctx, utd.data, utd.count); rpmtdFreeData(&utd); } /** @todo Implement disable/enable/warn/error/anal policy. */ rc = rpmVerifySignature(keyring, &sigtd, sig, ctx, msg); rpmDigestFinal(ctx, NULL, NULL, 0); } else { rc = RPMRC_FAIL; } exit: if (rc != RPMRC_FAIL && h != NULL && hdrp != NULL) { /* Retrofit RPMTAG_SOURCEPACKAGE to srpms for compatibility */ if (leadtype == RPMLEAD_SOURCE && headerIsSource(h)) { if (!headerIsEntry(h, RPMTAG_SOURCEPACKAGE)) { uint32_t one = 1; headerPutUint32(h, RPMTAG_SOURCEPACKAGE, &one, 1); } } /* * Try to make sure binary rpms have RPMTAG_SOURCERPM set as that's * what we use for differentiating binary vs source elsewhere. */ if (!headerIsEntry(h, RPMTAG_SOURCEPACKAGE) && headerIsSource(h)) { headerPutString(h, RPMTAG_SOURCERPM, "(none)"); } /* * Convert legacy headers on the fly. Not having immutable region * equals a truly ancient package, do full retrofit. OTOH newer * packages might have been built with --nodirtokens, test and handle * the non-compressed filelist case separately. */ if (!headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) headerConvert(h, HEADERCONV_RETROFIT_V3); else if (headerIsEntry(h, RPMTAG_OLDFILENAMES)) headerConvert(h, HEADERCONV_COMPRESSFILELIST); /* Append (and remap) signature tags to the metadata. */ headerMergeLegacySigs(h, sigh); /* Bump reference count for return. */ *hdrp = headerLink(h); if (keyidp) *keyidp = getKeyid(sig); } rpmtdFreeData(&sigtd); h = headerFree(h); pgpDigParamsFree(sig); sigh = headerFree(sigh); return rc; }
rpmRC rpmInstallSourcePackage(rpmts ts, FD_t fd, char ** specFilePtr, char ** cookie) { rpmfi fi = NULL; char * specFile = NULL; const char *rootdir = rpmtsRootDir(ts); Header h = NULL; rpmpsm psm = NULL; rpmte te = NULL; rpmRC rpmrc; int specix = -1; struct rpmtd_s filenames; rpmtdReset(&filenames); rpmrc = rpmReadPackageFile(ts, fd, NULL, &h); switch (rpmrc) { case RPMRC_NOTTRUSTED: case RPMRC_NOKEY: case RPMRC_OK: break; default: goto exit; break; } if (h == NULL) goto exit; rpmrc = RPMRC_FAIL; /* assume failure */ if (!headerIsSource(h)) { rpmlog(RPMLOG_ERR, _("source package expected, binary found\n")); goto exit; } /* src.rpm install can require specific rpmlib features, check them */ if (!rpmlibDeps(h)) goto exit; if (headerGet(h, RPMTAG_BASENAMES, &filenames, HEADERGET_ALLOC)) { struct rpmtd_s td; const char *str; const char *_cookie = headerGetString(h, RPMTAG_COOKIE); if (cookie && _cookie) *cookie = xstrdup(_cookie); /* Try to find spec by file flags */ if (_cookie && headerGet(h, RPMTAG_FILEFLAGS, &td, HEADERGET_MINMEM)) { rpmfileAttrs *flags; while (specix < 0 && (flags = rpmtdNextUint32(&td))) { if (*flags & RPMFILE_SPECFILE) specix = rpmtdGetIndex(&td); } } /* Still no spec? Look by filename. */ while (specix < 0 && (str = rpmtdNextString(&filenames))) { if (rpmFileHasSuffix(str, ".spec")) specix = rpmtdGetIndex(&filenames); } } if (rootdir && rstreq(rootdir, "/")) rootdir = NULL; /* Macros need to be added before trying to create directories */ rpmInstallLoadMacros(h); if (specix >= 0) { const char *bn; headerDel(h, RPMTAG_BASENAMES); headerDel(h, RPMTAG_DIRNAMES); headerDel(h, RPMTAG_DIRINDEXES); rpmtdInit(&filenames); for (int i = 0; (bn = rpmtdNextString(&filenames)); i++) { int spec = (i == specix); char *fn = rpmGenPath(rpmtsRootDir(ts), spec ? "%{_specdir}" : "%{_sourcedir}", bn); headerPutString(h, RPMTAG_OLDFILENAMES, fn); if (spec) specFile = xstrdup(fn); free(fn); } headerConvert(h, HEADERCONV_COMPRESSFILELIST); } else { rpmlog(RPMLOG_ERR, _("source package contains no .spec file\n")); goto exit; }; if (rpmtsAddInstallElement(ts, h, NULL, 0, NULL)) { goto exit; } te = rpmtsElement(ts, 0); if (te == NULL) { /* XXX can't happen */ goto exit; } rpmteSetFd(te, fd); rpmteSetHeader(te, h); fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, RPMFI_KEEPHEADER); h = headerFree(h); if (fi == NULL) { goto exit; } fi->apath = filenames.data; /* Ick */ rpmteSetFI(te, fi); fi = rpmfiFree(fi); if (rpmMkdirs(rpmtsRootDir(ts), "%{_topdir}:%{_sourcedir}:%{_specdir}")) { goto exit; } { /* set all files to be installed */ rpmfs fs = rpmteGetFileStates(te); int i; unsigned int fc = rpmfiFC(fi); for (i=0; i<fc; i++) rpmfsSetAction(fs, i, FA_CREATE); } psm = rpmpsmNew(ts, te); psm->goal = PKG_INSTALL; /* FIX: psm->fi->dnl should be owned. */ if (rpmpsmStage(psm, PSM_PROCESS) == RPMRC_OK) rpmrc = RPMRC_OK; (void) rpmpsmStage(psm, PSM_FINI); rpmpsmFree(psm); exit: if (specFilePtr && specFile && rpmrc == RPMRC_OK) *specFilePtr = specFile; else free(specFile); headerFree(h); rpmfiFree(fi); /* XXX nuke the added package(s). */ rpmtsClean(ts); return rpmrc; }
static rpmRC rpmpkgRead(rpmKeyring keyring, rpmVSFlags vsflags, FD_t fd, const char * fn, Header * hdrp) { pgpDig dig = NULL; char buf[8*BUFSIZ]; ssize_t count; rpmlead l = NULL; Header sigh = NULL; rpmSigTag sigtag; struct rpmtd_s sigtd; Header h = NULL; char * msg; rpmRC rc = RPMRC_FAIL; /* assume failure */ int leadtype = -1; headerGetFlags hgeflags = HEADERGET_DEFAULT; DIGEST_CTX ctx = NULL; if (hdrp) *hdrp = NULL; rpmtdReset(&sigtd); l = rpmLeadNew(); if ((rc = rpmLeadRead(fd, l)) == RPMRC_OK) { const char * err = NULL; if ((rc = rpmLeadCheck(l, &err)) == RPMRC_FAIL) { rpmlog(RPMLOG_ERR, "%s: %s\n", fn, err); } leadtype = rpmLeadType(l); } l = rpmLeadFree(l); if (rc != RPMRC_OK) goto exit; /* Read the signature header. */ msg = NULL; rc = rpmReadSignature(fd, &sigh, RPMSIGTYPE_HEADERSIG, &msg); switch (rc) { default: rpmlog(RPMLOG_ERR, _("%s: rpmReadSignature failed: %s"), fn, (msg && *msg ? msg : "\n")); msg = _free(msg); goto exit; break; case RPMRC_OK: if (sigh == NULL) { rpmlog(RPMLOG_ERR, _("%s: No signature available\n"), fn); rc = RPMRC_FAIL; goto exit; } break; } msg = _free(msg); #define _chk(_mask, _tag) \ (sigtag == 0 && !(vsflags & (_mask)) && headerIsEntry(sigh, (_tag))) /* * Figger the most effective available signature. * Prefer signatures over digests, then header-only over header+payload. * DSA will be preferred over RSA if both exist because tested first. * Note that NEEDPAYLOAD prevents header+payload signatures and digests. */ sigtag = 0; if (_chk(RPMVSF_NODSAHEADER, RPMSIGTAG_DSA)) { sigtag = RPMSIGTAG_DSA; } else if (_chk(RPMVSF_NORSAHEADER, RPMSIGTAG_RSA)) { sigtag = RPMSIGTAG_RSA; } else if (_chk(RPMVSF_NODSA|RPMVSF_NEEDPAYLOAD, RPMSIGTAG_GPG)) { sigtag = RPMSIGTAG_GPG; fdInitDigest(fd, PGPHASHALGO_SHA1, 0); } else if (_chk(RPMVSF_NORSA|RPMVSF_NEEDPAYLOAD, RPMSIGTAG_PGP)) { sigtag = RPMSIGTAG_PGP; fdInitDigest(fd, PGPHASHALGO_MD5, 0); } else if (_chk(RPMVSF_NOSHA1HEADER, RPMSIGTAG_SHA1)) { sigtag = RPMSIGTAG_SHA1; } else if (_chk(RPMVSF_NOMD5|RPMVSF_NEEDPAYLOAD, RPMSIGTAG_MD5)) { sigtag = RPMSIGTAG_MD5; fdInitDigest(fd, PGPHASHALGO_MD5, 0); } /* Read the metadata, computing digest(s) on the fly. */ h = NULL; msg = NULL; rc = rpmpkgReadHeader(keyring, vsflags, fd, &h, &msg); if (rc != RPMRC_OK || h == NULL) { rpmlog(RPMLOG_ERR, _("%s: headerRead failed: %s"), fn, (msg && *msg ? msg : "\n")); msg = _free(msg); goto exit; } msg = _free(msg); /* Any digests or signatures to check? */ if (sigtag == 0) { rc = RPMRC_OK; goto exit; } dig = pgpNewDig(); if (dig == NULL) { rc = RPMRC_FAIL; goto exit; } /* Retrieve the tag parameters from the signature header. */ if (!headerGet(sigh, sigtag, &sigtd, hgeflags)) { rc = RPMRC_FAIL; goto exit; } switch (sigtag) { case RPMSIGTAG_RSA: case RPMSIGTAG_DSA: if ((rc = parsePGP(&sigtd, "package", dig)) != RPMRC_OK) { goto exit; } /* fallthrough */ case RPMSIGTAG_SHA1: { struct rpmtd_s utd; pgpHashAlgo hashalgo = (sigtag == RPMSIGTAG_SHA1) ? PGPHASHALGO_SHA1 : dig->signature.hash_algo; if (!headerGet(h, RPMTAG_HEADERIMMUTABLE, &utd, hgeflags)) break; ctx = rpmDigestInit(hashalgo, RPMDIGEST_NONE); (void) rpmDigestUpdate(ctx, rpm_header_magic, sizeof(rpm_header_magic)); (void) rpmDigestUpdate(ctx, utd.data, utd.count); rpmtdFreeData(&utd); } break; case RPMSIGTAG_GPG: case RPMSIGTAG_PGP5: /* XXX legacy */ case RPMSIGTAG_PGP: if ((rc = parsePGP(&sigtd, "package", dig)) != RPMRC_OK) { goto exit; } /* fallthrough */ case RPMSIGTAG_MD5: /* Legacy signatures need the compressed payload in the digest too. */ while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0) {} if (count < 0) { rpmlog(RPMLOG_ERR, _("%s: Fread failed: %s\n"), fn, Fstrerror(fd)); rc = RPMRC_FAIL; goto exit; } ctx = rpmDigestBundleDupCtx(fdGetBundle(fd), (sigtag == RPMSIGTAG_MD5) ? PGPHASHALGO_MD5 : dig->signature.hash_algo); break; default: break; } /** @todo Implement disable/enable/warn/error/anal policy. */ rc = rpmVerifySignature(keyring, &sigtd, dig, ctx, &msg); switch (rc) { case RPMRC_OK: /* Signature is OK. */ rpmlog(RPMLOG_DEBUG, "%s: %s", fn, msg); break; case RPMRC_NOTTRUSTED: /* Signature is OK, but key is not trusted. */ case RPMRC_NOKEY: /* Public key is unavailable. */ /* XXX Print NOKEY/NOTTRUSTED warning only once. */ { int lvl = (stashKeyid(dig) ? RPMLOG_DEBUG : RPMLOG_WARNING); rpmlog(lvl, "%s: %s", fn, msg); } break; case RPMRC_NOTFOUND: /* Signature is unknown type. */ rpmlog(RPMLOG_WARNING, "%s: %s", fn, msg); break; default: case RPMRC_FAIL: /* Signature does not verify. */ rpmlog(RPMLOG_ERR, "%s: %s", fn, msg); break; } free(msg); exit: if (rc != RPMRC_FAIL && h != NULL && hdrp != NULL) { /* Retrofit RPMTAG_SOURCEPACKAGE to srpms for compatibility */ if (leadtype == RPMLEAD_SOURCE && headerIsSource(h)) { if (!headerIsEntry(h, RPMTAG_SOURCEPACKAGE)) { uint32_t one = 1; headerPutUint32(h, RPMTAG_SOURCEPACKAGE, &one, 1); } } /* * Try to make sure binary rpms have RPMTAG_SOURCERPM set as that's * what we use for differentiating binary vs source elsewhere. */ if (!headerIsEntry(h, RPMTAG_SOURCEPACKAGE) && headerIsSource(h)) { headerPutString(h, RPMTAG_SOURCERPM, "(none)"); } /* * Convert legacy headers on the fly. Not having "new" style compressed * filenames is close enough estimate for legacy indication... */ if (!headerIsEntry(h, RPMTAG_DIRNAMES)) { headerConvert(h, HEADERCONV_RETROFIT_V3); } /* Append (and remap) signature tags to the metadata. */ headerMergeLegacySigs(h, sigh); /* Bump reference count for return. */ *hdrp = headerLink(h); } rpmtdFreeData(&sigtd); rpmDigestFinal(ctx, NULL, NULL, 0); h = headerFree(h); pgpFreeDig(dig); sigh = rpmFreeSignature(sigh); return rc; }
/** * dnf_keyring_check_untrusted_file: */ gboolean dnf_keyring_check_untrusted_file(rpmKeyring keyring, const gchar *filename, GError **error) { FD_t fd = NULL; gboolean ret = FALSE; Header hdr = NULL; pgpDig dig = NULL; rpmRC rc; rpmtd td = NULL; rpmts ts = NULL; /* open the file for reading */ fd = Fopen(filename, "r.fdio"); if (fd == NULL) { g_set_error(error, DNF_ERROR, DNF_ERROR_FILE_INVALID, "failed to open %s", filename); goto out; } if (Ferror(fd)) { g_set_error(error, DNF_ERROR, DNF_ERROR_FILE_INVALID, "failed to open %s: %s", filename, Fstrerror(fd)); goto out; } /* we don't want to abort on missing keys */ ts = rpmtsCreate(); rpmtsSetVSFlags(ts, _RPMVSF_NOSIGNATURES); /* read in the file */ rc = rpmReadPackageFile(ts, fd, filename, &hdr); if (rc != RPMRC_OK) { /* we only return SHA1 and MD5 failures, as we're not * checking signatures at this stage */ g_set_error(error, DNF_ERROR, DNF_ERROR_FILE_INVALID, "%s could not be verified", filename); goto out; } /* convert and upscale */ headerConvert(hdr, HEADERCONV_RETROFIT_V3); /* get RSA key */ td = rpmtdNew(); rc = headerGet(hdr, RPMTAG_RSAHEADER, td, HEADERGET_MINMEM); if (rc != 1) { /* try to read DSA key as a fallback */ rc = headerGet(hdr, RPMTAG_DSAHEADER, td, HEADERGET_MINMEM); } /* the package has no signing key */ if (rc != 1) { g_autofree char *package_filename = g_path_get_basename(filename); ret = FALSE; g_set_error(error, DNF_ERROR, DNF_ERROR_GPG_SIGNATURE_INVALID, "package not signed: %s", package_filename); goto out; } /* make it into a digest */ dig = pgpNewDig(); rc = pgpPrtPkts(td->data, td->count, dig, 0); if (rc != 0) { g_set_error(error, DNF_ERROR, DNF_ERROR_FILE_INVALID, "failed to parse digest header for %s", filename); goto out; } /* does the key exist in the keyring */ rc = rpmKeyringLookup(keyring, dig); if (rc != RPMRC_OK) { g_set_error(error, DNF_ERROR, DNF_ERROR_GPG_SIGNATURE_INVALID, "failed to lookup digest in keyring for %s", filename); goto out; } /* the package is signed by a key we trust */ g_debug("%s has been verified as trusted", filename); ret = TRUE; out: if (dig != NULL) pgpFreeDig(dig); if (td != NULL) { rpmtdFreeData(td); rpmtdFree(td); } if (ts != NULL) rpmtsFree(ts); if (hdr != NULL) headerFree(hdr); if (fd != NULL) Fclose(fd); return ret; }