static PyObject *rpmtd_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) { char *kwlist[] = {"tag", NULL}; PyObject *pytag; rpmTag tag; rpmtd td; rpmtdObject *self = PyObject_New(rpmtdObject, subtype); if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &pytag)) return NULL; tag = tagNumFromPyObject(pytag); #ifdef DYING /* XXX with arbitrary tags, all tags are found. */ if (tag == RPMTAG_NOT_FOUND) { PyErr_SetString(PyExc_TypeError, "can't create container for unknown tag"); return NULL; } #endif td = rpmtdNew(); td->tag = tag; td->type = rpmTagGetType(tag) & RPM_MASK_TYPE; self->td = td; return (PyObject *)self; }
rpmtd rpmtdDup(rpmtd td) { rpmtd newtd = NULL; char **data = NULL; int i; assert(td != NULL); /* TODO: permit other types too */ if (td->type != RPM_STRING_ARRAY_TYPE && td->type != RPM_I18NSTRING_TYPE) { return NULL; } /* deep-copy container and data, drop immutable flag */ newtd = rpmtdNew(); memcpy(newtd, td, sizeof(*td)); newtd->flags &= ~(RPMTD_IMMUTABLE); newtd->flags |= (RPMTD_ALLOCED | RPMTD_PTR_ALLOCED); newtd->data = data = xmalloc(td->count * sizeof(*data)); while ((i = rpmtdNext(td)) >= 0) { data[i] = xstrdup(rpmtdGetString(td)); } return newtd; }
/** * This assumes the order of list matches the order of the new headers, and * throws an exception if that isn't true. */ static int rpmMergeHeaders(PyObject * list, FD_t fd, int matchTag) { Header h; HeaderIterator hi; rpmTagVal newMatch, oldMatch; hdrObject * hdr; rpm_count_t count = 0; int rc = 1; /* assume failure */ rpmtd td = rpmtdNew(); Py_BEGIN_ALLOW_THREADS h = headerRead(fd, HEADER_MAGIC_YES); Py_END_ALLOW_THREADS while (h) { if (!headerGet(h, matchTag, td, HEADERGET_MINMEM)) { PyErr_SetString(pyrpmError, "match tag missing in new header"); goto exit; } newMatch = rpmtdTag(td); rpmtdFreeData(td); hdr = (hdrObject *) PyList_GetItem(list, count++); if (!hdr) goto exit; if (!headerGet(hdr->h, matchTag, td, HEADERGET_MINMEM)) { PyErr_SetString(pyrpmError, "match tag missing in new header"); goto exit; } oldMatch = rpmtdTag(td); rpmtdFreeData(td); if (newMatch != oldMatch) { PyErr_SetString(pyrpmError, "match tag mismatch"); goto exit; } for (hi = headerInitIterator(h); headerNext(hi, td); rpmtdFreeData(td)) { /* could be dupes */ headerDel(hdr->h, rpmtdTag(td)); headerPut(hdr->h, td, HEADERPUT_DEFAULT); } headerFreeIterator(hi); h = headerFree(h); Py_BEGIN_ALLOW_THREADS h = headerRead(fd, HEADER_MAGIC_YES); Py_END_ALLOW_THREADS } rc = 0; exit: rpmtdFree(td); return rc; }
QueryData genRpmPackages(QueryContext& context) { QueryData results; auto dropper = DropPrivileges::get(); if (!dropper->dropTo("nobody") && isUserAdmin()) { LOG(WARNING) << "Cannot drop privileges for rpm_packages"; return results; } // Isolate RPM/package inspection to the canonical: /usr/lib/rpm. RpmEnvironmentManager env_manager; // The following implementation uses http://rpm.org/api/4.11.1/ rpmInitCrypto(); if (rpmReadConfigFiles(nullptr, nullptr) != 0) { TLOG << "Cannot read RPM configuration files"; return results; } rpmts ts = rpmtsCreate(); rpmdbMatchIterator matches; if (context.constraints["name"].exists(EQUALS)) { auto name = (*context.constraints["name"].getAll(EQUALS).begin()); matches = rpmtsInitIterator(ts, RPMTAG_NAME, name.c_str(), name.size()); } else { matches = rpmtsInitIterator(ts, RPMTAG_NAME, nullptr, 0); } Header header; while ((header = rpmdbNextIterator(matches)) != nullptr) { Row r; rpmtd td = rpmtdNew(); r["name"] = getRpmAttribute(header, RPMTAG_NAME, td); r["version"] = getRpmAttribute(header, RPMTAG_VERSION, td); r["release"] = getRpmAttribute(header, RPMTAG_RELEASE, td); r["source"] = getRpmAttribute(header, RPMTAG_SOURCERPM, td); r["size"] = getRpmAttribute(header, RPMTAG_SIZE, td); r["sha1"] = getRpmAttribute(header, RPMTAG_SHA1HEADER, td); r["arch"] = getRpmAttribute(header, RPMTAG_ARCH, td); rpmtdFree(td); results.push_back(r); } rpmdbFreeIterator(matches); rpmtsFree(ts); rpmFreeCrypto(); rpmFreeRpmrc(); return results; }
/* * Validate generated signature and insert to header if it looks sane. * NSS doesn't support everything GPG does. Basic tests to see if the * generated signature is something we can use. * Return generated signature tag data on success, NULL on failure. */ static rpmtd makeSigTag(Header sigh, int ishdr, uint8_t *pkt, size_t pktlen) { pgpDigParams sigp = NULL; rpmTagVal sigtag; rpmtd sigtd = NULL; unsigned int hash_algo; unsigned int pubkey_algo; if (pgpPrtParams(pkt, pktlen, PGPTAG_SIGNATURE, &sigp)) { rpmlog(RPMLOG_ERR, _("Unsupported PGP signature\n")); goto exit; } hash_algo = pgpDigParamsAlgo(sigp, PGPVAL_HASHALGO); if (rpmDigestLength(hash_algo) == 0) { rpmlog(RPMLOG_ERR, _("Unsupported PGP hash algorithm %u\n"), hash_algo); goto exit; } pubkey_algo = pgpDigParamsAlgo(sigp, PGPVAL_PUBKEYALGO); switch (pubkey_algo) { case PGPPUBKEYALGO_DSA: sigtag = ishdr ? RPMSIGTAG_DSA : RPMSIGTAG_GPG; break; case PGPPUBKEYALGO_RSA: sigtag = ishdr ? RPMSIGTAG_RSA : RPMSIGTAG_PGP; break; default: rpmlog(RPMLOG_ERR, _("Unsupported PGP pubkey algorithm %u\n"), pubkey_algo); goto exit; break; } /* Looks sane, create the tag data */ sigtd = rpmtdNew(); sigtd->count = pktlen; sigtd->data = memcpy(xmalloc(pktlen), pkt, pktlen);; sigtd->type = RPM_BIN_TYPE; sigtd->tag = sigtag; sigtd->flags |= RPMTD_ALLOCED; exit: pgpDigParamsFree(sigp); return sigtd; }
/* 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; }
QueryData genRpmPackages(QueryContext& context) { QueryData results; // The following implementation uses http://rpm.org/api/4.11.1/ rpmInitCrypto(); if (rpmReadConfigFiles(nullptr, nullptr) != 0) { TLOG << "Cannot read RPM configuration files."; return results; } rpmts ts = rpmtsCreate(); rpmdbMatchIterator matches; if (context.constraints["name"].exists()) { auto name = (*context.constraints["name"].getAll(EQUALS).begin()); matches = rpmtsInitIterator(ts, RPMTAG_NAME, name.c_str(), name.size()); } else { matches = rpmtsInitIterator(ts, RPMTAG_NAME, nullptr, 0); } Header header; while ((header = rpmdbNextIterator(matches)) != nullptr) { Row r; rpmtd td = rpmtdNew(); r["name"] = getRpmAttribute(header, RPMTAG_NAME, td); r["version"] = getRpmAttribute(header, RPMTAG_VERSION, td); r["release"] = getRpmAttribute(header, RPMTAG_RELEASE, td); r["source"] = getRpmAttribute(header, RPMTAG_SOURCERPM, td); r["size"] = getRpmAttribute(header, RPMTAG_SIZE, td); r["sha1"] = getRpmAttribute(header, RPMTAG_SHA1HEADER, td); r["arch"] = getRpmAttribute(header, RPMTAG_ARCH, td); rpmtdFree(td); results.push_back(r); } rpmdbFreeIterator(matches); rpmtsFree(ts); rpmFreeCrypto(); rpmFreeRpmrc(); return results; }
/* * Add rpm tag dictionaries to the module */ static void addRpmTags(PyObject *module) { PyObject *pyval, *pyname, *dict = PyDict_New(); rpmtd names = rpmtdNew(); rpmTagGetNames(names, 1); const char *tagname, *shortname; rpmTagVal tagval; while ((tagname = rpmtdNextString(names))) { shortname = tagname + strlen("RPMTAG_"); tagval = rpmTagGetValue(shortname); PyModule_AddIntConstant(module, tagname, tagval); pyval = PyInt_FromLong(tagval); pyname = Py_BuildValue("s", shortname); PyDict_SetItem(dict, pyval, pyname); Py_DECREF(pyval); Py_DECREF(pyname); } PyModule_AddObject(module, "tagnames", dict); rpmtdFreeData(names); rpmtdFree(names); }
/* * Add rpm tag dictionaries to the module */ static void addRpmTags(PyObject *module) { PyObject * dict = PyDict_New(); #ifdef NOTYET PyObject *pyval, *pyname; rpmtd names = rpmtdNew(); rpmTagGetNames(names, 1); const char *tagname, *shortname; rpmTag tagval; while ((tagname = rpmtdNextString(names))) { shortname = tagname + strlen("RPMTAG_"); tagval = rpmTagGetValue(shortname); PyModule_AddIntConstant(module, tagname, tagval); pyval = PyInt_FromLong(tagval); pyname = PyString_FromString(shortname); PyDict_SetItem(dict, pyval, pyname); Py_XDECREF(pyval); Py_XDECREF(pyname); } PyModule_AddObject(module, "tagnames", dict); rpmtdFreeData(names); rpmtdFree(names); #else PyObject * d = PyModule_GetDict(module); PyObject * o; { const struct headerTagTableEntry_s * t; PyObject * to; for (t = rpmTagTable; t && t->name; t++) { PyDict_SetItemString(d, (char *) t->name, to=PyInt_FromLong(t->val)); Py_XDECREF(to); PyDict_SetItem(dict, to, o=PyString_FromString(t->name + 7)); Py_XDECREF(o); } } { headerSprintfExtension exts = rpmHeaderFormats; headerSprintfExtension ext; PyObject * to; int extNum; for (ext = exts, extNum = 0; ext != NULL && ext->type != HEADER_EXT_LAST; ext = (ext->type == HEADER_EXT_MORE ? *ext->u.more : ext+1), extNum++) { if (ext->name == NULL || ext->type != HEADER_EXT_TAG) continue; PyDict_SetItemString(d, (char *) ext->name, to=PyCObject_FromVoidPtr((void *)ext, NULL)); Py_XDECREF(to); PyDict_SetItem(dict, to, o=PyString_FromString(ext->name + 7)); Py_XDECREF(o); } } PyDict_SetItemString(d, "tagnames", dict); Py_XDECREF(dict); #endif }
cr_Package * cr_package_from_header(Header hdr, int changelog_limit, cr_HeaderReadingFlags hdrrflags, G_GNUC_UNUSED GError **err) { cr_Package *pkg; assert(hdr); assert(!err || *err == NULL); // Create new package structure pkg = cr_package_new(); pkg->loadingflags |= CR_PACKAGE_FROM_HEADER; pkg->loadingflags |= CR_PACKAGE_LOADED_PRI; pkg->loadingflags |= CR_PACKAGE_LOADED_FIL; pkg->loadingflags |= CR_PACKAGE_LOADED_OTH; // Create rpm tag data container rpmtd td = rpmtdNew(); headerGetFlags flags = HEADERGET_MINMEM | HEADERGET_EXT; // Fill package structure pkg->name = cr_safe_string_chunk_insert(pkg->chunk, headerGetString(hdr, RPMTAG_NAME)); gint64 is_src = headerGetNumber(hdr, RPMTAG_SOURCEPACKAGE); if (is_src) { pkg->arch = cr_safe_string_chunk_insert(pkg->chunk, "src"); } else { pkg->arch = cr_safe_string_chunk_insert(pkg->chunk, headerGetString(hdr, RPMTAG_ARCH)); } pkg->version = cr_safe_string_chunk_insert(pkg->chunk, headerGetString(hdr, RPMTAG_VERSION)); #define MAX_STR_INT_LEN 24 char tmp_epoch[MAX_STR_INT_LEN]; if (snprintf(tmp_epoch, MAX_STR_INT_LEN, "%llu", (long long unsigned int) headerGetNumber(hdr, RPMTAG_EPOCH)) <= 0) { tmp_epoch[0] = '\0'; } pkg->epoch = g_string_chunk_insert_len(pkg->chunk, tmp_epoch, MAX_STR_INT_LEN); pkg->release = cr_safe_string_chunk_insert(pkg->chunk, headerGetString(hdr, RPMTAG_RELEASE)); pkg->summary = cr_safe_string_chunk_insert(pkg->chunk, headerGetString(hdr, RPMTAG_SUMMARY)); pkg->description = cr_safe_string_chunk_insert_null(pkg->chunk, headerGetString(hdr, RPMTAG_DESCRIPTION)); pkg->url = cr_safe_string_chunk_insert(pkg->chunk, headerGetString(hdr, RPMTAG_URL)); if (headerGet(hdr, RPMTAG_BUILDTIME, td, flags)) { pkg->time_build = rpmtdGetNumber(td); } pkg->rpm_license = cr_safe_string_chunk_insert(pkg->chunk, headerGetString(hdr, RPMTAG_LICENSE)); pkg->rpm_vendor = cr_safe_string_chunk_insert(pkg->chunk, headerGetString(hdr, RPMTAG_VENDOR)); pkg->rpm_group = cr_safe_string_chunk_insert(pkg->chunk, headerGetString(hdr, RPMTAG_GROUP)); pkg->rpm_buildhost = cr_safe_string_chunk_insert(pkg->chunk, headerGetString(hdr, RPMTAG_BUILDHOST)); pkg->rpm_sourcerpm = cr_safe_string_chunk_insert(pkg->chunk, headerGetString(hdr, RPMTAG_SOURCERPM)); pkg->rpm_packager = cr_safe_string_chunk_insert(pkg->chunk, headerGetString(hdr, RPMTAG_PACKAGER)); if (headerGet(hdr, RPMTAG_SIZE, td, flags)) { pkg->size_installed = rpmtdGetNumber(td); } if (headerGet(hdr, RPMTAG_ARCHIVESIZE, td, flags)) { pkg->size_archive = rpmtdGetNumber(td); } rpmtdFreeData(td); rpmtdFree(td); // // Fill files // rpmtd full_filenames = rpmtdNew(); // Only for filenames_hashtable rpmtd indexes = rpmtdNew(); rpmtd filenames = rpmtdNew(); rpmtd fileflags = rpmtdNew(); rpmtd filemodes = rpmtdNew(); GHashTable *filenames_hashtable = g_hash_table_new(g_str_hash, g_str_equal); rpmtd dirnames = rpmtdNew(); // Create list of pointer to directory names int dir_count; char **dir_list = NULL; if (headerGet(hdr, RPMTAG_DIRNAMES, dirnames, flags) && (dir_count = rpmtdCount(dirnames))) { int x = 0; dir_list = malloc(sizeof(char *) * dir_count); while (rpmtdNext(dirnames) != -1) { dir_list[x] = cr_safe_string_chunk_insert(pkg->chunk, rpmtdGetString(dirnames)); x++; } assert(x == dir_count); } if (headerGet(hdr, RPMTAG_FILENAMES, full_filenames, flags) && headerGet(hdr, RPMTAG_DIRINDEXES, indexes, flags) && headerGet(hdr, RPMTAG_BASENAMES, filenames, flags) && headerGet(hdr, RPMTAG_FILEFLAGS, fileflags, flags) && headerGet(hdr, RPMTAG_FILEMODES, filemodes, flags)) { rpmtdInit(full_filenames); rpmtdInit(indexes); rpmtdInit(filenames); rpmtdInit(fileflags); rpmtdInit(filemodes); while ((rpmtdNext(full_filenames) != -1) && (rpmtdNext(indexes) != -1) && (rpmtdNext(filenames) != -1) && (rpmtdNext(fileflags) != -1) && (rpmtdNext(filemodes) != -1)) { cr_PackageFile *packagefile = cr_package_file_new(); packagefile->name = cr_safe_string_chunk_insert(pkg->chunk, rpmtdGetString(filenames)); packagefile->path = (dir_list) ? dir_list[(int) rpmtdGetNumber(indexes)] : ""; if (S_ISDIR(rpmtdGetNumber(filemodes))) { // Directory packagefile->type = cr_safe_string_chunk_insert(pkg->chunk, "dir"); } else if (rpmtdGetNumber(fileflags) & RPMFILE_GHOST) { // Ghost packagefile->type = cr_safe_string_chunk_insert(pkg->chunk, "ghost"); } else { // Regular file packagefile->type = cr_safe_string_chunk_insert(pkg->chunk, ""); } g_hash_table_replace(filenames_hashtable, (gpointer) rpmtdGetString(full_filenames), (gpointer) rpmtdGetString(full_filenames)); pkg->files = g_slist_prepend(pkg->files, packagefile); } pkg->files = g_slist_reverse (pkg->files); rpmtdFreeData(dirnames); rpmtdFreeData(indexes); rpmtdFreeData(filenames); rpmtdFreeData(fileflags); rpmtdFreeData(filemodes); } rpmtdFree(dirnames); rpmtdFree(indexes); rpmtdFree(filemodes); if (dir_list) { free((void *) dir_list); } // // PCOR (provides, conflicts, obsoletes, requires) // rpmtd fileversions = rpmtdNew(); // Struct used as value in ap_hashtable struct ap_value_struct { const char *flags; const char *version; int pre; }; // Hastable with filenames from provided GHashTable *provided_hashtable = g_hash_table_new(g_str_hash, g_str_equal); // Hashtable with already processed files from requires GHashTable *ap_hashtable = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, free); for (int deptype=0; dep_items[deptype].type != DEP_SENTINEL; deptype++) { if (headerGet(hdr, dep_items[deptype].nametag, filenames, flags) && headerGet(hdr, dep_items[deptype].flagstag, fileflags, flags) && headerGet(hdr, dep_items[deptype].versiontag, fileversions, flags)) { // Because we have to select only libc.so with highest version // e.g. libc.so.6(GLIBC_2.4) cr_Dependency *libc_require_highest = NULL; rpmtdInit(filenames); rpmtdInit(fileflags); rpmtdInit(fileversions); while ((rpmtdNext(filenames) != -1) && (rpmtdNext(fileflags) != -1) && (rpmtdNext(fileversions) != -1)) { int pre = 0; const char *filename = rpmtdGetString(filenames); guint64 num_flags = rpmtdGetNumber(fileflags); const char *flags = cr_flag_to_str(num_flags); const char *full_version = rpmtdGetString(fileversions); // Requires specific stuff if (deptype == DEP_REQUIRES) { // Skip requires which start with "rpmlib(" if (!strncmp("rpmlib(", filename, 7)) { continue; } // Skip package primary files if (g_hash_table_lookup_extended(filenames_hashtable, filename, NULL, NULL)) { if (cr_is_primary(filename)) { continue; } } // Skip files which are provided if (g_hash_table_lookup_extended(provided_hashtable, filename, NULL, NULL)) { continue; } // Calculate pre value if (num_flags & (RPMSENSE_PREREQ | RPMSENSE_SCRIPT_PRE | RPMSENSE_SCRIPT_POST)) { pre = 1; } // Skip duplicate files gpointer value; if (g_hash_table_lookup_extended(ap_hashtable, filename, NULL, &value)) { struct ap_value_struct *ap_value = value; if (!g_strcmp0(ap_value->flags, flags) && !strcmp(ap_value->version, full_version) && (ap_value->pre == pre)) { continue; } } } // Parse dep string cr_EVR *evr = cr_str_to_evr(full_version, pkg->chunk); if ((full_version && *full_version) && !evr->epoch) { // NULL in epoch mean that the epoch was bad (non-numerical) _cleanup_free_ gchar *pkg_nevra = cr_package_nevra(pkg); g_warning("Bad epoch in version string \"%s\" for dependency \"%s\" in package \"%s\"", full_version, filename, pkg_nevra); g_warning("Skipping this dependency"); g_free(evr); continue; } // Create dynamic dependency object cr_Dependency *dependency = cr_dependency_new(); dependency->name = cr_safe_string_chunk_insert(pkg->chunk, filename); dependency->flags = cr_safe_string_chunk_insert(pkg->chunk, flags); dependency->epoch = evr->epoch; dependency->version = evr->version; dependency->release = evr->release; g_free(evr); switch (deptype) { case DEP_PROVIDES: g_hash_table_replace(provided_hashtable, dependency->name, dependency->name); pkg->provides = g_slist_prepend(pkg->provides, dependency); break; case DEP_CONFLICTS: pkg->conflicts = g_slist_prepend(pkg->conflicts, dependency); break; case DEP_OBSOLETES: pkg->obsoletes = g_slist_prepend(pkg->obsoletes, dependency); break; case DEP_REQUIRES: dependency->pre = pre; // XXX: libc.so filtering //////////////////////////// if (g_str_has_prefix(dependency->name, "libc.so.6")) { if (!libc_require_highest) libc_require_highest = dependency; else { if (cr_compare_dependency(libc_require_highest->name, dependency->name) == 2) { g_free(libc_require_highest); libc_require_highest = dependency; } else g_free(dependency); } break; } // XXX: libc.so filtering - END /////////////////////// pkg->requires = g_slist_prepend(pkg->requires, dependency); // Add file into ap_hashtable struct ap_value_struct *value = malloc(sizeof(struct ap_value_struct)); value->flags = flags; value->version = full_version; value->pre = dependency->pre; g_hash_table_replace(ap_hashtable, dependency->name, value); break; //case REQUIRES end case DEP_SUGGESTS: pkg->suggests = g_slist_prepend(pkg->suggests, dependency); break; case DEP_ENHANCES: pkg->enhances = g_slist_prepend(pkg->enhances, dependency); break; case DEP_RECOMMENDS: pkg->recommends = g_slist_prepend(pkg->recommends, dependency); break; case DEP_SUPPLEMENTS: pkg->supplements = g_slist_prepend(pkg->supplements, dependency); break; #ifdef ENABLE_LEGACY_WEAKDEPS case DEP_OLDSUGGESTS: if ( num_flags & RPMSENSE_STRONG ) { pkg->recommends = g_slist_prepend(pkg->recommends, dependency); } else { pkg->suggests = g_slist_prepend(pkg->suggests, dependency); } break; case DEP_OLDENHANCES: if ( num_flags & RPMSENSE_STRONG ) { pkg->supplements = g_slist_prepend(pkg->supplements, dependency); } else { pkg->enhances = g_slist_prepend(pkg->enhances, dependency); } break; #endif } // Switch end } // While end // XXX: libc.so filtering //////////////////////////////// if (deptype == DEP_REQUIRES && libc_require_highest) pkg->requires = g_slist_prepend(pkg->requires, libc_require_highest); // XXX: libc.so filtering - END //////////////////////////////// } rpmtdFreeData(filenames); rpmtdFreeData(fileflags); rpmtdFreeData(fileversions); } pkg->provides = g_slist_reverse (pkg->provides); pkg->conflicts = g_slist_reverse (pkg->conflicts); pkg->obsoletes = g_slist_reverse (pkg->obsoletes); pkg->requires = g_slist_reverse (pkg->requires); pkg->suggests = g_slist_reverse (pkg->suggests); pkg->enhances = g_slist_reverse (pkg->enhances); pkg->recommends = g_slist_reverse (pkg->recommends); pkg->supplements = g_slist_reverse (pkg->supplements); g_hash_table_remove_all(filenames_hashtable); g_hash_table_remove_all(provided_hashtable); g_hash_table_remove_all(ap_hashtable); g_hash_table_unref(filenames_hashtable); g_hash_table_unref(provided_hashtable); g_hash_table_unref(ap_hashtable); rpmtdFree(filenames); rpmtdFree(fileflags); rpmtdFree(fileversions); rpmtdFreeData(full_filenames); rpmtdFree(full_filenames); // // Changelogs // rpmtd changelogtimes = rpmtdNew(); rpmtd changelognames = rpmtdNew(); rpmtd changelogtexts = rpmtdNew(); if (headerGet(hdr, RPMTAG_CHANGELOGTIME, changelogtimes, flags) && headerGet(hdr, RPMTAG_CHANGELOGNAME, changelognames, flags) && headerGet(hdr, RPMTAG_CHANGELOGTEXT, changelogtexts, flags)) { gint64 last_time = G_GINT64_CONSTANT(0); rpmtdInit(changelogtimes); rpmtdInit(changelognames); rpmtdInit(changelogtexts); while ((rpmtdNext(changelogtimes) != -1) && (rpmtdNext(changelognames) != -1) && (rpmtdNext(changelogtexts) != -1) && (changelog_limit > 0 || changelog_limit == -1)) { gint64 time = rpmtdGetNumber(changelogtimes); cr_ChangelogEntry *changelog = cr_changelog_entry_new(); changelog->author = cr_safe_string_chunk_insert(pkg->chunk, rpmtdGetString(changelognames)); changelog->date = time; changelog->changelog = cr_safe_string_chunk_insert(pkg->chunk, rpmtdGetString(changelogtexts)); // Remove space from end of author name if (changelog->author) { size_t len, x; len = strlen(changelog->author); for (x=(len-1); x > 0; x--) { if (changelog->author[x] == ' ') { changelog->author[x] = '\0'; } else { break; } } } pkg->changelogs = g_slist_prepend(pkg->changelogs, changelog); if (changelog_limit != -1) changelog_limit--; // If a previous entry has the same time, increment time of the previous // entry by one. Ugly but works! if (last_time == time) { int tmp_time = time; GSList *previous = pkg->changelogs; while ((previous = g_slist_next(previous)) != NULL && ((cr_ChangelogEntry *) (previous->data))->date == tmp_time) { ((cr_ChangelogEntry *) (previous->data))->date++; tmp_time++; } } else { last_time = time; } } //pkg->changelogs = g_slist_reverse (pkg->changelogs); } rpmtdFreeData(changelogtimes); rpmtdFreeData(changelognames); rpmtdFreeData(changelogtexts); rpmtdFree(changelogtimes); rpmtdFree(changelognames); rpmtdFree(changelogtexts); // // Keys and hdrid (data used for caching when the --cachedir is specified) // if (hdrrflags & CR_HDRR_LOADHDRID) pkg->hdrid = cr_safe_string_chunk_insert(pkg->chunk, headerGetString(hdr, RPMTAG_HDRID)); if (hdrrflags & CR_HDRR_LOADSIGNATURES) { rpmtd gpgtd = rpmtdNew(); rpmtd pgptd = rpmtdNew(); if (headerGet(hdr, RPMTAG_SIGGPG, gpgtd, hdrrflags) && gpgtd->count > 0) { pkg->siggpg = cr_binary_data_new(); pkg->siggpg->size = gpgtd->count; pkg->siggpg->data = g_string_chunk_insert_len(pkg->chunk, gpgtd->data, gpgtd->count); } if (headerGet(hdr, RPMTAG_SIGPGP, pgptd, hdrrflags) && pgptd->count > 0) { pkg->sigpgp = cr_binary_data_new(); pkg->sigpgp->size = pgptd->count; pkg->sigpgp->data = g_string_chunk_insert_len(pkg->chunk, pgptd->data, pgptd->count); } rpmtdFree(gpgtd); rpmtdFree(pgptd); } return pkg; }
/** * 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; }
/* * Create a spec file object from a spec file * @param [String] filename Spec file path * @return [Spec] */ static VALUE spec_s_open(VALUE klass, VALUE filename) { #if RPM_VERSION_CODE < RPM_VERSION(4,1,0) Spec rspec; #else rpmts ts = NULL; #endif if (TYPE(filename) != T_STRING) { rb_raise(rb_eTypeError, "illegal argument type"); } #if RPM_VERSION_CODE < RPM_VERSION(4,1,0) switch (parseSpec(&rspec, RSTRING_PTR(filename), "/", NULL, 0, "", NULL, 1, 1)) { case 0: if (rspec != NULL) { break; } default: rb_raise(rb_eRuntimeError, "specfile `%s' parsing failed", RSTRING_PTR(filename)); } return Data_Wrap_Struct(klass, NULL, spec_free, rspec); #else ts = rpmtsCreate(); #if RPM_VERSION_CODE < RPM_VERSION(4,4,8) switch (parseSpec(ts, RSTRING_PTR(filename), "/", NULL, 0, "", NULL, 1, 1)) { #elif RPM_VERSION_CODE < RPM_VERSION(4,5,90) switch (parseSpec(ts, RSTRING_PTR(filename), "/", 0, "", NULL, 1, 1, 0)) { #elif RPM_VERSION_CODE < RPM_VERSION(5,0,0) switch (parseSpec(ts, RSTRING_PTR(filename), "/", NULL, 0, "", NULL, 1, 1)) { #else switch (parseSpec(ts, RSTRING_PTR(filename), "/", 0, "", NULL, 1, 1, 0)) { #endif case 0: if (ts != NULL) { break; } default: rb_raise(rb_eRuntimeError, "specfile `%s' parsing failed", RSTRING_PTR(filename)); } return Data_Wrap_Struct(klass, NULL, ts_free, ts); #endif } /* * * Alias for Spec#open */ VALUE rpm_spec_open(const char* filename) { return spec_s_open(rpm_cSpec, rb_str_new2(filename)); } /* * @return [String] Return Build root defined in the spec file */ VALUE rpm_spec_get_buildroot(VALUE spec) { #if RPM_VERSION_CODE < RPM_VERSION(4,5,90) if (RPM_SPEC(spec)->buildRootURL) { return rb_str_new2(RPM_SPEC(spec)->buildRootURL); } #elif RPM_VERSION_CODE < RPM_VERSION(4,5,90) if (RPM_SPEC(spec)->rootURL) { return rb_str_new2(RPM_SPEC(spec)->rootURL); } #elif RPM_VERSION_CODE < RPM_VERSION(5,0,0) if (RPM_SPEC(spec)->buildRoot) { return rb_str_new2(RPM_SPEC(spec)->buildRoot); } #else const char *buildRootURL = rpmGenPath(RPM_SPEC(spec)->rootURL, "%{?buildroot}", NULL); VALUE result = rb_str_new2(buildRootURL); buildRootURL = _free(buildRootURL); return result; #endif return Qnil; } /* * @return [String] Return Build subdirectory defined in the spec file */ VALUE rpm_spec_get_buildsubdir(VALUE spec) { if (RPM_SPEC(spec)->buildSubdir) { return rb_str_new2(RPM_SPEC(spec)->buildSubdir); } return Qnil; } /* * @return [Array<String>] Return Build architectures defined in the spec file */ VALUE rpm_spec_get_buildarchs(VALUE spec) { VALUE ba = rb_ivar_get(spec, id_ba); if (NIL_P(ba)) { register int i; ba = rb_ary_new(); for (i = 0; i < RPM_SPEC(spec)->BACount; i++) { rb_ary_push(ba, rb_str_new2(RPM_SPEC(spec)->BANames[i])); } rb_ivar_set(spec, id_ba, ba); } return ba; } /* * @return [Array<RPM::Require>] Return Build requires defined in the spec file */ VALUE rpm_spec_get_buildrequires(VALUE spec) { VALUE br = rb_ivar_get(spec, id_br); #if RPM_VERSION_CODE < RPM_VERSION(4,6,0) || RPM_VERSION_CODE >= RPM_VERSION(5,0,0) if (NIL_P(br)) { const char** names; const char** vers; int_32* flags; int_32 count; rpmTagType nt, vt, type; register int i; br = rb_ary_new(); if (!headerGetEntryMinMemory(RPM_SPEC(spec)->buildRestrictions, RPMTAG_REQUIRENAME, (hTYP_t)&nt, (hPTR_t*)&names, (hCNT_t)&count)) { goto leave; } get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_REQUIREVERSION, &vt, (void*)&vers); get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_REQUIREFLAGS, &type, (void*)&flags); for (i = 0; i < count; i++) { rb_ary_push(br, rpm_require_new(names[i], rpm_version_new(vers[i]), flags[i], spec)); } release_entry(nt, names); release_entry(vt, vers); rb_ivar_set(spec, id_br, br); } leave: return br; #else rpmtd nametd = rpmtdNew(); rpmtd versiontd = rpmtdNew(); rpmtd flagtd = rpmtdNew(); if (NIL_P(br)) { br = rb_ary_new(); if (!headerGet(RPM_SPEC(spec)->buildRestrictions, RPMTAG_REQUIRENAME, nametd, HEADERGET_MINMEM)) { goto leave; } get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_REQUIREVERSION, versiontd); get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_REQUIREFLAGS, flagtd); rpmtdInit(nametd); while ( rpmtdNext(nametd) != -1 ) { rb_ary_push(br, rpm_require_new(rpmtdGetString(nametd), rpm_version_new(rpmtdNextString(versiontd)), *rpmtdNextUint32(flagtd), spec)); } rb_ivar_set(spec, id_br, br); } leave: rpmtdFree(nametd); rpmtdFree(versiontd); rpmtdFree(flagtd); return br; #endif } /* * @return [Array<RPM::Conflict>] Return Build conflicts defined in the spec file */ VALUE rpm_spec_get_buildconflicts(VALUE spec) { VALUE bc = rb_ivar_get(spec, id_bc); #if RPM_VERSION_CODE < RPM_VERSION(4,6,0) || RPM_VERSION_CODE >= RPM_VERSION(5,0,0) if (NIL_P(bc)) { const char** names; const char** vers; int_32* flags; int_32 count; rpmTagType nt, vt, type; register int i; bc = rb_ary_new(); if (!headerGetEntryMinMemory(RPM_SPEC(spec)->buildRestrictions, RPMTAG_CONFLICTNAME, (hTYP_t)&nt, (hPTR_t*)&names, (hCNT_t)&count)) { goto leave; } get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_CONFLICTVERSION, &vt, (void*)&vers); get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_CONFLICTFLAGS, &type, (void*)&flags); for (i = 0; i < count; i++) { rb_ary_push(bc, rpm_conflict_new(names[i], rpm_version_new(vers[i]), flags[i], spec)); } release_entry(nt, names); release_entry(vt, vers); rb_ivar_set(spec, id_bc, bc); } leave: return bc; #else rpmtd nametd = rpmtdNew(); rpmtd versiontd = rpmtdNew(); rpmtd flagtd = rpmtdNew(); if (NIL_P(bc)) { bc = rb_ary_new(); if (!headerGet(RPM_SPEC(spec)->buildRestrictions, RPMTAG_CONFLICTNAME, nametd, HEADERGET_MINMEM)) { goto leave; } get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_CONFLICTVERSION, versiontd); get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_CONFLICTFLAGS, flagtd); rpmtdInit(nametd); while ( rpmtdNext(nametd) != -1) { rb_ary_push(bc, rpm_conflict_new(rpmtdGetString(nametd), rpm_version_new(rpmtdNextString(versiontd)), *rpmtdNextUint32(flagtd), spec)); } rb_ivar_set(spec, id_bc, bc); } leave: rpmtdFree(nametd); rpmtdFree(versiontd); rpmtdFree(flagtd); return bc; #endif }
void genRpmPackageFiles(RowYield& yield, QueryContext& context) { auto dropper = DropPrivileges::get(); if (!dropper->dropTo("nobody") && isUserAdmin()) { LOG(WARNING) << "Cannot drop privileges for rpm_package_files"; return; } // Isolate RPM/package inspection to the canonical: /usr/lib/rpm. RpmEnvironmentManager env_manager; if (rpmReadConfigFiles(nullptr, nullptr) != 0) { TLOG << "Cannot read RPM configuration files"; return; } rpmts ts = rpmtsCreate(); rpmdbMatchIterator matches; if (context.constraints["package"].exists(EQUALS)) { auto name = (*context.constraints["package"].getAll(EQUALS).begin()); matches = rpmtsInitIterator(ts, RPMTAG_NAME, name.c_str(), name.size()); } else { matches = rpmtsInitIterator(ts, RPMTAG_NAME, nullptr, 0); } Header header; while ((header = rpmdbNextIterator(matches)) != nullptr) { rpmtd td = rpmtdNew(); rpmfi fi = rpmfiNew(ts, header, RPMTAG_BASENAMES, RPMFI_NOHEADER); std::string package_name = getRpmAttribute(header, RPMTAG_NAME, td); auto file_count = rpmfiFC(fi); if (file_count <= 0) { VLOG(1) << "RPM package " << package_name << " contains 0 files"; rpmfiFree(fi); continue; } else if (file_count > MAX_RPM_FILES) { VLOG(1) << "RPM package " << package_name << " contains over " << MAX_RPM_FILES << " files"; rpmfiFree(fi); continue; } // Iterate over every file in this package. for (size_t i = 0; rpmfiNext(fi) >= 0 && i < file_count; i++) { Row r; auto path = rpmfiFN(fi); r["package"] = package_name; r["path"] = (path != nullptr) ? path : ""; auto username = rpmfiFUser(fi); r["username"] = (username != nullptr) ? username : ""; auto groupname = rpmfiFGroup(fi); r["groupname"] = (groupname != nullptr) ? groupname : ""; r["mode"] = lsperms(rpmfiFMode(fi)); r["size"] = BIGINT(rpmfiFSize(fi)); int digest_algo; auto digest = rpmfiFDigestHex(fi, &digest_algo); if (digest_algo == PGPHASHALGO_SHA256) { r["sha256"] = (digest != nullptr) ? digest : ""; } yield(r); } rpmfiFree(fi); rpmtdFree(td); } rpmdbFreeIterator(matches); rpmtsFree(ts); rpmFreeRpmrc(); }
void init_rpm(void) { PyObject * d, *o, *tag = NULL, *dict, *m; #if Py_TPFLAGS_HAVE_ITER /* XXX backport to python-1.5.2 */ if (PyType_Ready(&hdr_Type) < 0) return; if (PyType_Ready(&rpmal_Type) < 0) return; if (PyType_Ready(&rpmds_Type) < 0) return; if (PyType_Ready(&rpmfd_Type) < 0) return; if (PyType_Ready(&rpmfi_Type) < 0) return; if (PyType_Ready(&rpmmi_Type) < 0) return; if (PyType_Ready(&rpmps_Type) < 0) return; if (PyType_Ready(&rpmte_Type) < 0) return; if (PyType_Ready(&rpmts_Type) < 0) return; if (PyType_Ready(&spec_Type) < 0) return; #endif m = Py_InitModule3("_rpm", rpmModuleMethods, rpm__doc__); if (m == NULL) return; /* * treat error to register rpm cleanup hook as fatal, tracebacks * can and will leave stale locks around if we can't clean up */ if (Py_AtExit(rpm_exithook) == -1) return; rpmReadConfigFiles(NULL, NULL); d = PyModule_GetDict(m); #ifdef HACK pyrpmError = PyString_FromString("_rpm.error"); PyDict_SetItemString(d, "error", pyrpmError); Py_DECREF(pyrpmError); #else pyrpmError = PyErr_NewException("_rpm.error", NULL, NULL); if (pyrpmError != NULL) PyDict_SetItemString(d, "error", pyrpmError); #endif #if Py_TPFLAGS_HAVE_ITER /* XXX backport to python-1.5.2 */ Py_INCREF(&hdr_Type); PyModule_AddObject(m, "hdr", (PyObject *) &hdr_Type); Py_INCREF(&rpmal_Type); PyModule_AddObject(m, "al", (PyObject *) &rpmal_Type); Py_INCREF(&rpmds_Type); PyModule_AddObject(m, "ds", (PyObject *) &rpmds_Type); Py_INCREF(&rpmfd_Type); PyModule_AddObject(m, "fd", (PyObject *) &rpmfd_Type); Py_INCREF(&rpmfi_Type); PyModule_AddObject(m, "fi", (PyObject *) &rpmfi_Type); Py_INCREF(&rpmmi_Type); PyModule_AddObject(m, "mi", (PyObject *) &rpmmi_Type); Py_INCREF(&rpmps_Type); PyModule_AddObject(m, "ps", (PyObject *) &rpmps_Type); Py_INCREF(&rpmte_Type); PyModule_AddObject(m, "te", (PyObject *) &rpmte_Type); Py_INCREF(&rpmts_Type); PyModule_AddObject(m, "ts", (PyObject *) &rpmts_Type); Py_INCREF(&spec_Type); PyModule_AddObject(m, "spec", (PyObject *) &spec_Type); #else hdr_Type.ob_type = &PyType_Type; rpmal_Type.ob_type = &PyType_Type; rpmds_Type.ob_type = &PyType_Type; rpmfd_Type.ob_type = &PyType_Type; rpmfi_Type.ob_type = &PyType_Type; rpmmi_Type.ob_type = &PyType_Type; rpmps_Type.ob_type = &PyType_Type; rpmte_Type.ob_type = &PyType_Type; rpmts_Type.ob_type = &PyType_Type; spec_Type.ob_type = &PyType_Type; #endif dict = PyDict_New(); { const char *tname, *sname; rpmtd names = rpmtdNew(); rpmTagGetNames(names, 1); while ((tname = rpmtdNextString(names))) { sname = tname + strlen("RPMTAG_"); tag = PyInt_FromLong(rpmTagGetValue(sname)); PyDict_SetItemString(d, tname, tag); Py_DECREF(tag); o = PyString_FromString(sname); PyDict_SetItem(dict, tag, o); Py_DECREF(o); } rpmtdFreeData(names); rpmtdFree(names); } PyDict_SetItemString(d, "tagnames", dict); Py_DECREF(dict); #define REGISTER_ENUM(val) \ PyDict_SetItemString(d, #val, o=PyInt_FromLong( val )); \ Py_DECREF(o); REGISTER_ENUM(RPMTAG_NOT_FOUND); REGISTER_ENUM(RPMFILE_STATE_NORMAL); REGISTER_ENUM(RPMFILE_STATE_REPLACED); REGISTER_ENUM(RPMFILE_STATE_NOTINSTALLED); REGISTER_ENUM(RPMFILE_STATE_NETSHARED); REGISTER_ENUM(RPMFILE_STATE_WRONGCOLOR); REGISTER_ENUM(RPMFILE_CONFIG); REGISTER_ENUM(RPMFILE_DOC); REGISTER_ENUM(RPMFILE_ICON); REGISTER_ENUM(RPMFILE_MISSINGOK); REGISTER_ENUM(RPMFILE_NOREPLACE); REGISTER_ENUM(RPMFILE_GHOST); REGISTER_ENUM(RPMFILE_LICENSE); REGISTER_ENUM(RPMFILE_README); REGISTER_ENUM(RPMFILE_EXCLUDE); REGISTER_ENUM(RPMFILE_UNPATCHED); REGISTER_ENUM(RPMFILE_PUBKEY); REGISTER_ENUM(RPMDEP_SENSE_REQUIRES); REGISTER_ENUM(RPMDEP_SENSE_CONFLICTS); REGISTER_ENUM(RPMSENSE_LESS); REGISTER_ENUM(RPMSENSE_GREATER); REGISTER_ENUM(RPMSENSE_EQUAL); REGISTER_ENUM(RPMSENSE_PREREQ); REGISTER_ENUM(RPMSENSE_INTERP); REGISTER_ENUM(RPMSENSE_SCRIPT_PRE); REGISTER_ENUM(RPMSENSE_SCRIPT_POST); REGISTER_ENUM(RPMSENSE_SCRIPT_PREUN); REGISTER_ENUM(RPMSENSE_SCRIPT_POSTUN); REGISTER_ENUM(RPMSENSE_SCRIPT_VERIFY); REGISTER_ENUM(RPMSENSE_FIND_REQUIRES); REGISTER_ENUM(RPMSENSE_FIND_PROVIDES); REGISTER_ENUM(RPMSENSE_TRIGGERIN); REGISTER_ENUM(RPMSENSE_TRIGGERUN); REGISTER_ENUM(RPMSENSE_TRIGGERPOSTUN); REGISTER_ENUM(RPMSENSE_SCRIPT_PREP); REGISTER_ENUM(RPMSENSE_SCRIPT_BUILD); REGISTER_ENUM(RPMSENSE_SCRIPT_INSTALL); REGISTER_ENUM(RPMSENSE_SCRIPT_CLEAN); REGISTER_ENUM(RPMSENSE_RPMLIB); REGISTER_ENUM(RPMSENSE_TRIGGERPREIN); REGISTER_ENUM(RPMSENSE_KEYRING); REGISTER_ENUM(RPMSENSE_PATCHES); REGISTER_ENUM(RPMSENSE_CONFIG); REGISTER_ENUM(RPMTRANS_FLAG_TEST); REGISTER_ENUM(RPMTRANS_FLAG_BUILD_PROBS); REGISTER_ENUM(RPMTRANS_FLAG_NOSCRIPTS); REGISTER_ENUM(RPMTRANS_FLAG_JUSTDB); REGISTER_ENUM(RPMTRANS_FLAG_NOTRIGGERS); REGISTER_ENUM(RPMTRANS_FLAG_NODOCS); REGISTER_ENUM(RPMTRANS_FLAG_ALLFILES); REGISTER_ENUM(RPMTRANS_FLAG_KEEPOBSOLETE); REGISTER_ENUM(RPMTRANS_FLAG_REPACKAGE); REGISTER_ENUM(RPMTRANS_FLAG_REVERSE); REGISTER_ENUM(RPMTRANS_FLAG_NOPRE); REGISTER_ENUM(RPMTRANS_FLAG_NOPOST); REGISTER_ENUM(RPMTRANS_FLAG_NOTRIGGERPREIN); REGISTER_ENUM(RPMTRANS_FLAG_NOTRIGGERIN); REGISTER_ENUM(RPMTRANS_FLAG_NOTRIGGERUN); REGISTER_ENUM(RPMTRANS_FLAG_NOPREUN); REGISTER_ENUM(RPMTRANS_FLAG_NOPOSTUN); REGISTER_ENUM(RPMTRANS_FLAG_NOTRIGGERPOSTUN); REGISTER_ENUM(RPMTRANS_FLAG_NOMD5); REGISTER_ENUM(RPMTRANS_FLAG_NOSUGGEST); REGISTER_ENUM(RPMTRANS_FLAG_ADDINDEPS); REGISTER_ENUM(RPMTRANS_FLAG_NOCONFIGS); REGISTER_ENUM(RPMPROB_FILTER_IGNOREOS); REGISTER_ENUM(RPMPROB_FILTER_IGNOREARCH); REGISTER_ENUM(RPMPROB_FILTER_REPLACEPKG); REGISTER_ENUM(RPMPROB_FILTER_FORCERELOCATE); REGISTER_ENUM(RPMPROB_FILTER_REPLACENEWFILES); REGISTER_ENUM(RPMPROB_FILTER_REPLACEOLDFILES); REGISTER_ENUM(RPMPROB_FILTER_OLDPACKAGE); REGISTER_ENUM(RPMPROB_FILTER_DISKSPACE); REGISTER_ENUM(RPMPROB_FILTER_DISKNODES); REGISTER_ENUM(RPMCALLBACK_UNKNOWN); REGISTER_ENUM(RPMCALLBACK_INST_PROGRESS); REGISTER_ENUM(RPMCALLBACK_INST_START); REGISTER_ENUM(RPMCALLBACK_INST_OPEN_FILE); REGISTER_ENUM(RPMCALLBACK_INST_CLOSE_FILE); REGISTER_ENUM(RPMCALLBACK_TRANS_PROGRESS); REGISTER_ENUM(RPMCALLBACK_TRANS_START); REGISTER_ENUM(RPMCALLBACK_TRANS_STOP); REGISTER_ENUM(RPMCALLBACK_UNINST_PROGRESS); REGISTER_ENUM(RPMCALLBACK_UNINST_START); REGISTER_ENUM(RPMCALLBACK_UNINST_STOP); REGISTER_ENUM(RPMCALLBACK_REPACKAGE_PROGRESS); REGISTER_ENUM(RPMCALLBACK_REPACKAGE_START); REGISTER_ENUM(RPMCALLBACK_REPACKAGE_STOP); REGISTER_ENUM(RPMCALLBACK_UNPACK_ERROR); REGISTER_ENUM(RPMCALLBACK_CPIO_ERROR); REGISTER_ENUM(RPMCALLBACK_SCRIPT_ERROR); REGISTER_ENUM(RPMPROB_BADARCH); REGISTER_ENUM(RPMPROB_BADOS); REGISTER_ENUM(RPMPROB_PKG_INSTALLED); REGISTER_ENUM(RPMPROB_BADRELOCATE); REGISTER_ENUM(RPMPROB_REQUIRES); REGISTER_ENUM(RPMPROB_CONFLICT); REGISTER_ENUM(RPMPROB_NEW_FILE_CONFLICT); REGISTER_ENUM(RPMPROB_FILE_CONFLICT); REGISTER_ENUM(RPMPROB_OLDPACKAGE); REGISTER_ENUM(RPMPROB_DISKSPACE); REGISTER_ENUM(RPMPROB_DISKNODES); REGISTER_ENUM(VERIFY_DIGEST); REGISTER_ENUM(VERIFY_SIGNATURE); REGISTER_ENUM(RPMLOG_EMERG); REGISTER_ENUM(RPMLOG_ALERT); REGISTER_ENUM(RPMLOG_CRIT); REGISTER_ENUM(RPMLOG_ERR); REGISTER_ENUM(RPMLOG_WARNING); REGISTER_ENUM(RPMLOG_NOTICE); REGISTER_ENUM(RPMLOG_INFO); REGISTER_ENUM(RPMLOG_DEBUG); REGISTER_ENUM(RPMMIRE_DEFAULT); REGISTER_ENUM(RPMMIRE_STRCMP); REGISTER_ENUM(RPMMIRE_REGEX); REGISTER_ENUM(RPMMIRE_GLOB); REGISTER_ENUM(RPMVSF_DEFAULT); REGISTER_ENUM(RPMVSF_NOHDRCHK); REGISTER_ENUM(RPMVSF_NEEDPAYLOAD); REGISTER_ENUM(RPMVSF_NOSHA1HEADER); REGISTER_ENUM(RPMVSF_NOMD5HEADER); REGISTER_ENUM(RPMVSF_NODSAHEADER); REGISTER_ENUM(RPMVSF_NORSAHEADER); REGISTER_ENUM(RPMVSF_NOSHA1); REGISTER_ENUM(RPMVSF_NOMD5); REGISTER_ENUM(RPMVSF_NODSA); REGISTER_ENUM(RPMVSF_NORSA); REGISTER_ENUM(_RPMVSF_NODIGESTS); REGISTER_ENUM(_RPMVSF_NOSIGNATURES); REGISTER_ENUM(_RPMVSF_NOHEADER); REGISTER_ENUM(_RPMVSF_NOPAYLOAD); REGISTER_ENUM(TR_ADDED); REGISTER_ENUM(TR_REMOVED); REGISTER_ENUM(RPMDBI_PACKAGES); REGISTER_ENUM((intptr_t)RPMAL_NOMATCH); }
QueryData genRpmPackageFiles(QueryContext& context) { QueryData results; if (rpmReadConfigFiles(nullptr, nullptr) != 0) { TLOG << "Cannot read RPM configuration files."; return results; } rpmts ts = rpmtsCreate(); rpmdbMatchIterator matches; if (context.constraints["package"].exists()) { auto name = (*context.constraints["package"].getAll(EQUALS).begin()); matches = rpmtsInitIterator(ts, RPMTAG_NAME, name.c_str(), name.size()); } else { matches = rpmtsInitIterator(ts, RPMTAG_NAME, nullptr, 0); } Header header; while ((header = rpmdbNextIterator(matches)) != nullptr) { rpmtd td = rpmtdNew(); rpmfi fi = rpmfiNew(ts, header, RPMTAG_BASENAMES, RPMFI_NOHEADER); auto file_count = rpmfiFC(fi); if (file_count <= 0 || file_count > MAX_RPM_FILES) { // This package contains no or too many files. rpmfiFree(fi); continue; } // Iterate over every file in this package. for (size_t i = 0; rpmfiNext(fi) >= 0 && i < file_count; i++) { Row r; r["package"] = getRpmAttribute(header, RPMTAG_NAME, td); auto path = rpmfiFN(fi); r["path"] = (path != nullptr) ? path : ""; auto username = rpmfiFUser(fi); r["username"] = (username != nullptr) ? username : ""; auto groupname = rpmfiFGroup(fi); r["groupname"] = (groupname != nullptr) ? groupname : ""; r["mode"] = lsperms(rpmfiFMode(fi)); r["size"] = BIGINT(rpmfiFSize(fi)); #ifdef CENTOS_CENTOS6 // Older versions of rpmlib/rpmip use a hash algorithm enum. pgpHashAlgo digest_algo; #else int digest_algo; #endif auto digest = rpmfiFDigestHex(fi, &digest_algo); if (digest_algo == PGPHASHALGO_SHA256) { r["sha256"] = (digest != nullptr) ? digest : ""; } results.push_back(r); } rpmfiFree(fi); rpmtdFree(td); } rpmdbFreeIterator(matches); rpmtsFree(ts); rpmFreeRpmrc(); return results; }
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; }
/* --------------------------------------------------------------------- */ int netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags) { rpmts ts; rpmdbMatchIterator mi; Header h; #if HAVE_HEADERGET const char *g; rpmtd td_name, td_version, td_release, td_group, td_time; #else char *n, *v, *r, *g; int32_t *t; #endif time_t install_time; size_t date_len; int i = 1; netsnmp_swinst_entry *entry; #if HAVE_HEADERGET td_name = rpmtdNew(); td_version = rpmtdNew(); td_release = rpmtdNew(); td_group = rpmtdNew(); td_time = rpmtdNew(); #endif ts = rpmtsCreate(); rpmtsSetVSFlags( ts, (_RPMVSF_NOSIGNATURES|_RPMVSF_NODIGESTS)); mi = rpmtsInitIterator( ts, RPMDBI_PACKAGES, NULL, 0); if (mi == NULL) NETSNMP_LOGONCE((LOG_ERR, "rpmdbOpen() failed\n")); while (NULL != (h = rpmdbNextIterator( mi ))) { const u_char *dt; entry = netsnmp_swinst_entry_create( i++ ); if (NULL == entry) continue; /* error already logged by function */ CONTAINER_INSERT(container, entry); h = headerLink( h ); #if HAVE_HEADERGET headerGet(h, RPMTAG_NAME, td_name, HEADERGET_EXT); headerGet(h, RPMTAG_VERSION, td_version, HEADERGET_EXT); headerGet(h, RPMTAG_RELEASE, td_release, HEADERGET_EXT); headerGet(h, RPMTAG_GROUP, td_group, HEADERGET_EXT); headerGet(h, RPMTAG_INSTALLTIME, td_time, HEADERGET_EXT); entry->swName_len = snprintf( entry->swName, sizeof(entry->swName), "%s-%s-%s", rpmtdGetString(td_name), rpmtdGetString(td_version), rpmtdGetString(td_release)); install_time = rpmtdGetNumber(td_time); g = rpmtdGetString(td_group); #else headerGetEntry( h, RPMTAG_NAME, NULL, (void**)&n, NULL); headerGetEntry( h, RPMTAG_VERSION, NULL, (void**)&v, NULL); headerGetEntry( h, RPMTAG_RELEASE, NULL, (void**)&r, NULL); headerGetEntry( h, RPMTAG_GROUP, NULL, (void**)&g, NULL); headerGetEntry( h, RPMTAG_INSTALLTIME, NULL, (void**)&t, NULL); entry->swName_len = snprintf( entry->swName, sizeof(entry->swName), "%s-%s-%s", n, v, r); install_time = *t; #endif entry->swType = (g && NULL != strstr( g, "System Environment")) ? 2 /* operatingSystem */ : 4; /* application */ if (entry->swName_len > sizeof(entry->swName)) entry->swName_len = sizeof(entry->swName); dt = date_n_time( &install_time, &date_len ); if (date_len != 8 && date_len != 11) { snmp_log(LOG_ERR, "Bogus length from date_n_time for %s", entry->swName); entry->swDate_len = 0; } else { entry->swDate_len = date_len; memcpy(entry->swDate, dt, entry->swDate_len); } #if HAVE_HEADERGET rpmtdFreeData(td_name); rpmtdFreeData(td_version); rpmtdFreeData(td_release); rpmtdFreeData(td_group); rpmtdFreeData(td_time); #endif headerFree( h ); } rpmdbFreeIterator( mi ); rpmtsFree( ts ); #if HAVE_HEADERGET rpmtdFree(td_name); rpmtdFree(td_version); rpmtdFree(td_release); rpmtdFree(td_group); rpmtdFree(td_time); #endif DEBUGMSGTL(("swinst:load:arch", "loaded %d entries\n", (int)CONTAINER_SIZE(container))); return 0; }