dcavalca / rpms / libdnf

Forked from rpms/libdnf 2 years ago
Clone

Blame SOURCES/0001-Use-rpmdbCookie-from-librpm-remove-hawkey.Sack._rpmd.patch

ce91f9
From 5fbecb9533a5584d20a2b76f5816e58c2ffbb6f6 Mon Sep 17 00:00:00 2001
ce91f9
From: Jaroslav Rohel <jrohel@redhat.com>
ce91f9
Date: Wed, 2 Feb 2022 08:45:36 +0100
ce91f9
Subject: [PATCH 1/2] Use `rpmdbCookie` from librpm, remove
ce91f9
 `hawkey.Sack._rpmdb_version`
ce91f9
ce91f9
`dnf_sack_get_rpmdb_version` function that computed the hash of installed
ce91f9
packages was removed. `rpmdbCookie` function from librpm is used in context
ce91f9
part of libdnf instead.
ce91f9
ce91f9
The private Python function `hawkey.Sack._rpmdb_version()` was removed too.
ce91f9
It was used by DNF. The new version of DNF uses
ce91f9
`rpm.TransactionSet.dbCookie()` function from librpm, which wraps
ce91f9
the `rpmdbCookie` function. So the same librpm function will be used
ce91f9
in context part of libdnf (e.g. by microdnf) and in the DNF.
ce91f9
ce91f9
`rpmdbCookie` funkcion is safer. It also detect reinstalation of package
ce91f9
as a change. That will be needed in the future to determining if the libsolv
ce91f9
cache is still valid.
ce91f9
It also solves the libdnf problem with SHA1 in FIPS mode.
ce91f9
ce91f9
= changelog =
ce91f9
msg: Use `rpmdbCookie` from librpm, remove `hawkey.Sack._rpmdb_version`
ce91f9
type: bugfix
ce91f9
related: https://bugzilla.redhat.com/show_bug.cgi?id=2043476
ce91f9
---
ce91f9
 libdnf/dnf-sack-private.hpp | 15 ------------
ce91f9
 libdnf/dnf-sack.cpp         | 40 -------------------------------
ce91f9
 libdnf/dnf-transaction.cpp  | 48 +++++++++++++++++++++----------------
ce91f9
 python/hawkey/sack-py.cpp   |  8 -------
ce91f9
 4 files changed, 27 insertions(+), 84 deletions(-)
ce91f9
ce91f9
diff --git a/libdnf/dnf-sack-private.hpp b/libdnf/dnf-sack-private.hpp
ce91f9
index 89873534..2db96320 100644
ce91f9
--- a/libdnf/dnf-sack-private.hpp
ce91f9
+++ b/libdnf/dnf-sack-private.hpp
ce91f9
@@ -81,19 +81,4 @@ std::pair<std::vector<std::vector<std::string>>, libdnf::ModulePackageContainer:
ce91f9
 
ce91f9
 std::vector<libdnf::ModulePackage *> requiresModuleEnablement(DnfSack * sack, const libdnf::PackageSet * installSet);
ce91f9
 
ce91f9
-/**
ce91f9
- * @brief Return fingerprint of installed RPMs.
ce91f9
- * The format is <count>:<hash>.
ce91f9
- * <count> is a count of installed RPMs.
ce91f9
- * <hash> is a sha1 hash of sorted sha1hdr hashes of installed RPMs.
ce91f9
- *
ce91f9
- * The count can be computed from the command line by running:
ce91f9
- * rpm -qa --qf='%{name}\n' | grep -v '^gpg-pubkey$' | wc -l
ce91f9
- *
ce91f9
- * The hash can be computed from the command line by running:
ce91f9
- * rpm -qa --qf='%{name} %{sha1header}\n' | grep -v '^gpg-pubkey ' \
ce91f9
- * | cut -d ' ' -f 2 | LC_ALL=C sort | tr -d '\n' | sha1sum
ce91f9
- */
ce91f9
-std::string dnf_sack_get_rpmdb_version(DnfSack *sack);
ce91f9
-
ce91f9
 #endif // HY_SACK_INTERNAL_H
ce91f9
diff --git a/libdnf/dnf-sack.cpp b/libdnf/dnf-sack.cpp
ce91f9
index a88e8a1c..13977730 100644
ce91f9
--- a/libdnf/dnf-sack.cpp
ce91f9
+++ b/libdnf/dnf-sack.cpp
ce91f9
@@ -80,7 +80,6 @@ extern "C" {
ce91f9
 #include "module/ModulePackage.hpp"
ce91f9
 #include "repo/Repo-private.hpp"
ce91f9
 #include "repo/solvable/DependencyContainer.hpp"
ce91f9
-#include "utils/crypto/sha1.hpp"
ce91f9
 #include "utils/File.hpp"
ce91f9
 #include "utils/utils.hpp"
ce91f9
 #include "log.hpp"
ce91f9
@@ -2535,42 +2534,3 @@ std::pair<std::vector<std::vector<std::string>>, libdnf::ModulePackageContainer:
ce91f9
     setModuleExcludes(sack, hotfixRepos, *moduleContainer);
ce91f9
     return ret;
ce91f9
 }
ce91f9
-
ce91f9
-std::string dnf_sack_get_rpmdb_version(DnfSack *sack) {
ce91f9
-    // collect all sha1hdr checksums
ce91f9
-    // they are sufficiently unique IDs that represent installed RPMs
ce91f9
-    std::vector<std::string> checksums;
ce91f9
-
ce91f9
-    // iterate all @System repo RPMs (rpmdb records)
ce91f9
-    libdnf::Query query{sack, libdnf::Query::ExcludeFlags::IGNORE_EXCLUDES};
ce91f9
-    query.installed();
ce91f9
-
ce91f9
-    auto pset = query.getResultPset();
ce91f9
-    Id id = -1;
ce91f9
-    while(true) {
ce91f9
-        id = pset->next(id);
ce91f9
-        if (id == -1) {
ce91f9
-            break;
ce91f9
-        }
ce91f9
-        DnfPackage *pkg = dnf_package_new(sack, id);
ce91f9
-        // store pkgid (equals to sha1hdr)
ce91f9
-        checksums.push_back(libdnf::string::fromCstring(dnf_package_get_pkgid(pkg)));
ce91f9
-        g_object_unref(pkg);
ce91f9
-    }
ce91f9
-
ce91f9
-    // sort checksums to compute the output checksum always the same
ce91f9
-    std::sort(checksums.begin(), checksums.end());
ce91f9
-
ce91f9
-    SHA1Hash h;
ce91f9
-    for (auto & checksum : checksums) {
ce91f9
-        h.update(checksum.c_str());
ce91f9
-    }
ce91f9
-
ce91f9
-    // build <count>:<hash> output
ce91f9
-    std::ostringstream result;
ce91f9
-    result << checksums.size();
ce91f9
-    result << ":";
ce91f9
-    result << h.hexdigest();
ce91f9
-
ce91f9
-    return result.str();
ce91f9
-}
ce91f9
diff --git a/libdnf/dnf-transaction.cpp b/libdnf/dnf-transaction.cpp
ce91f9
index e0966582..d93c5ec6 100644
ce91f9
--- a/libdnf/dnf-transaction.cpp
ce91f9
+++ b/libdnf/dnf-transaction.cpp
ce91f9
@@ -28,6 +28,7 @@
ce91f9
  * This object represents an RPM transaction.
ce91f9
  */
ce91f9
 
ce91f9
+#include <rpm/rpmdb.h>
ce91f9
 #include <rpm/rpmlib.h>
ce91f9
 #include <rpm/rpmlog.h>
ce91f9
 #include <rpm/rpmts.h>
ce91f9
@@ -53,6 +54,7 @@
ce91f9
 #include "transaction/Swdb.hpp"
ce91f9
 #include "transaction/Transformer.hpp"
ce91f9
 #include "utils/bgettext/bgettext-lib.h"
ce91f9
+#include "utils/utils.hpp"
ce91f9
 
ce91f9
 typedef enum {
ce91f9
     DNF_TRANSACTION_STEP_STARTED,
ce91f9
@@ -1136,9 +1138,8 @@ dnf_transaction_commit(DnfTransaction *transaction, HyGoal goal, DnfState *state
ce91f9
     libdnf::Swdb *swdb = priv->swdb;
ce91f9
     PluginHookContextTransactionData data{PLUGIN_HOOK_ID_CONTEXT_PRE_TRANSACTION, transaction, goal, state};
ce91f9
     DnfSack * sack = hy_goal_get_sack(goal);
ce91f9
-    DnfSack * rpmdb_version_sack = NULL;
ce91f9
-    std::string rpmdb_begin;
ce91f9
-    std::string rpmdb_end;
ce91f9
+    std::unique_ptr<char, decltype(free)*> rpmdb_cookie_uptr{nullptr, free};
ce91f9
+    std::string rpmdb_cookie;
ce91f9
 
ce91f9
     /* take lock */
ce91f9
     ret = dnf_state_take_lock(state, DNF_LOCK_TYPE_RPMDB, DNF_LOCK_MODE_PROCESS, error);
ce91f9
@@ -1431,17 +1432,24 @@ dnf_transaction_commit(DnfTransaction *transaction, HyGoal goal, DnfState *state
ce91f9
     if (!dnf_context_plugin_hook(priv->context, PLUGIN_HOOK_ID_CONTEXT_PRE_TRANSACTION, &data, nullptr))
ce91f9
         goto out;
ce91f9
 
ce91f9
-    // FIXME get commandline
ce91f9
-    if (sack) {
ce91f9
-        rpmdb_begin = dnf_sack_get_rpmdb_version(sack);
ce91f9
-    } else {
ce91f9
-        // if sack is not available, create a custom instance
ce91f9
-        rpmdb_version_sack = dnf_sack_new();
ce91f9
-        dnf_sack_load_system_repo(rpmdb_version_sack, nullptr, DNF_SACK_LOAD_FLAG_NONE, nullptr);
ce91f9
-        rpmdb_begin = dnf_sack_get_rpmdb_version(rpmdb_version_sack);
ce91f9
-        g_object_unref(rpmdb_version_sack);
ce91f9
+    // Open rpm database if it is not already open
ce91f9
+    if (!rpmtsGetRdb(priv->ts)) {
ce91f9
+        rc = rpmtsOpenDB(priv->ts, rpmtsGetDBMode(priv->ts));
ce91f9
+        if (rc != 0) {
ce91f9
+            ret = FALSE;
ce91f9
+            g_set_error(
ce91f9
+                error, DNF_ERROR, DNF_ERROR_INTERNAL_ERROR, _("Error %i opening rpm database"), rc);
ce91f9
+            goto out;
ce91f9
+        }
ce91f9
     }
ce91f9
-    swdb->beginTransaction(_get_current_time(), rpmdb_begin, "", priv->uid);
ce91f9
+
ce91f9
+    rpmdb_cookie_uptr.reset(rpmdbCookie(rpmtsGetRdb(priv->ts)));
ce91f9
+    rpmdb_cookie = libdnf::string::fromCstring(rpmdb_cookie_uptr.get());
ce91f9
+    if (rpmdb_cookie.empty()) {
ce91f9
+        g_critical(_("The rpmdbCookie() function did not return cookie of rpm database."));
ce91f9
+    }
ce91f9
+    // FIXME get commandline
ce91f9
+    swdb->beginTransaction(_get_current_time(), rpmdb_cookie, "", priv->uid);
ce91f9
 
ce91f9
     /* run the transaction */
ce91f9
     priv->state = dnf_state_get_child(state);
ce91f9
@@ -1481,14 +1489,12 @@ dnf_transaction_commit(DnfTransaction *transaction, HyGoal goal, DnfState *state
ce91f9
     if (!ret)
ce91f9
         goto out;
ce91f9
 
ce91f9
-    // finalize swdb transaction
ce91f9
-    // always load a new sack with rpmdb state after the transaction
ce91f9
-    rpmdb_version_sack = dnf_sack_new();
ce91f9
-    dnf_sack_load_system_repo(rpmdb_version_sack, nullptr, DNF_SACK_LOAD_FLAG_NONE, nullptr);
ce91f9
-    rpmdb_end = dnf_sack_get_rpmdb_version(rpmdb_version_sack);
ce91f9
-    g_object_unref(rpmdb_version_sack);
ce91f9
-
ce91f9
-    swdb->endTransaction(_get_current_time(), rpmdb_end.c_str(), libdnf::TransactionState::DONE);
ce91f9
+    rpmdb_cookie_uptr.reset(rpmdbCookie(rpmtsGetRdb(priv->ts)));
ce91f9
+    rpmdb_cookie = libdnf::string::fromCstring(rpmdb_cookie_uptr.get());
ce91f9
+    if (rpmdb_cookie.empty()) {
ce91f9
+        g_critical(_("The rpmdbCookie() function did not return cookie of rpm database."));
ce91f9
+    }
ce91f9
+    swdb->endTransaction(_get_current_time(), rpmdb_cookie, libdnf::TransactionState::DONE);
ce91f9
     swdb->closeTransaction();
ce91f9
 
ce91f9
     data.hookId = PLUGIN_HOOK_ID_CONTEXT_TRANSACTION;
ce91f9
diff --git a/python/hawkey/sack-py.cpp b/python/hawkey/sack-py.cpp
ce91f9
index 4de499cb..fcb5cd61 100644
ce91f9
--- a/python/hawkey/sack-py.cpp
ce91f9
+++ b/python/hawkey/sack-py.cpp
ce91f9
@@ -783,13 +783,6 @@ load_repo(_SackObject *self, PyObject *args, PyObject *kwds) try
ce91f9
     Py_RETURN_NONE;
ce91f9
 } CATCH_TO_PYTHON
ce91f9
 
ce91f9
-static PyObject *
ce91f9
-rpmdb_version(_SackObject *self, PyObject *unused) try
ce91f9
-{
ce91f9
-    auto result = dnf_sack_get_rpmdb_version(self->sack);
ce91f9
-    return PyString_FromString(result.c_str());
ce91f9
-} CATCH_TO_PYTHON
ce91f9
-
ce91f9
 static Py_ssize_t
ce91f9
 len(_SackObject *self) try
ce91f9
 {
ce91f9
@@ -858,7 +851,6 @@ PyMethodDef sack_methods[] = {
ce91f9
      METH_VARARGS | METH_KEYWORDS, NULL},
ce91f9
     {"load_repo", (PyCFunction)load_repo, METH_VARARGS | METH_KEYWORDS,
ce91f9
      NULL},
ce91f9
-    {"_rpmdb_version", (PyCFunction)rpmdb_version, METH_VARARGS | METH_KEYWORDS, NULL},
ce91f9
     {NULL}                      /* sentinel */
ce91f9
 };
ce91f9
 
ce91f9
-- 
ce91f9
2.34.1
ce91f9
ce91f9
ce91f9
From 3dae1fd8754ec9521e16e2e11a7c4bf2c81bbb02 Mon Sep 17 00:00:00 2001
ce91f9
From: Jaroslav Rohel <jrohel@redhat.com>
ce91f9
Date: Wed, 2 Feb 2022 18:00:39 +0100
ce91f9
Subject: [PATCH 2/2] Remove class `SHA1Hash`, which is no longer used, remove
ce91f9
 OpenSSL require
ce91f9
ce91f9
The class was used by the `dnf_sack_get_rpmdb_version` function, which was
ce91f9
removed. The `rpmdbCookie` function from librpm is used instead.
ce91f9
---
ce91f9
 CMakeLists.txt                     |  1 -
ce91f9
 libdnf.spec                        |  1 -
ce91f9
 libdnf/CMakeLists.txt              |  1 -
ce91f9
 libdnf/utils/CMakeLists.txt        |  1 -
ce91f9
 libdnf/utils/crypto/CMakeLists.txt |  5 -----
ce91f9
 libdnf/utils/crypto/sha1.cpp       | 36 ------------------------------
ce91f9
 libdnf/utils/crypto/sha1.hpp       | 25 ---------------------
ce91f9
 7 files changed, 70 deletions(-)
ce91f9
 delete mode 100644 libdnf/utils/crypto/CMakeLists.txt
ce91f9
 delete mode 100644 libdnf/utils/crypto/sha1.cpp
ce91f9
 delete mode 100644 libdnf/utils/crypto/sha1.hpp
ce91f9
ce91f9
diff --git a/CMakeLists.txt b/CMakeLists.txt
ce91f9
index 60cf1b8c..7149b9e6 100644
ce91f9
--- a/CMakeLists.txt
ce91f9
+++ b/CMakeLists.txt
ce91f9
@@ -52,7 +52,6 @@ endif()
ce91f9
 # build dependencies
ce91f9
 find_package(Gpgme REQUIRED)
ce91f9
 find_package(LibSolv 0.6.30 REQUIRED COMPONENTS ext)
ce91f9
-find_package(OpenSSL REQUIRED)
ce91f9
 
ce91f9
 
ce91f9
 # build dependencies via pkg-config
ce91f9
diff --git a/libdnf.spec b/libdnf.spec
ce91f9
index 697911f0..89d2fb40 100644
ce91f9
--- a/libdnf.spec
ce91f9
+++ b/libdnf.spec
ce91f9
@@ -83,7 +83,6 @@ BuildRequires:  pkgconfig(zck) >= 0.9.11
ce91f9
 BuildRequires:  pkgconfig(sqlite3)
ce91f9
 BuildRequires:  pkgconfig(json-c)
ce91f9
 BuildRequires:  pkgconfig(cppunit)
ce91f9
-BuildRequires:  pkgconfig(libcrypto)
ce91f9
 BuildRequires:  pkgconfig(modulemd-2.0) >= %{libmodulemd_version}
ce91f9
 BuildRequires:  pkgconfig(smartcols)
ce91f9
 BuildRequires:  gettext
ce91f9
diff --git a/libdnf/CMakeLists.txt b/libdnf/CMakeLists.txt
ce91f9
index 998a6f94..9e71d139 100644
ce91f9
--- a/libdnf/CMakeLists.txt
ce91f9
+++ b/libdnf/CMakeLists.txt
ce91f9
@@ -75,7 +75,6 @@ target_link_libraries(libdnf
ce91f9
     ${GLIB_GIO_UNIX_LIBRARIES}
ce91f9
     ${LIBSOLV_LIBRARY}
ce91f9
     ${LIBSOLV_EXT_LIBRARY}
ce91f9
-    ${OPENSSL_CRYPTO_LIBRARY}
ce91f9
     ${RPM_LIBRARIES}
ce91f9
     ${SCOLS_LIBRARIES}
ce91f9
     ${SQLite3_LIBRARIES}
ce91f9
diff --git a/libdnf/utils/CMakeLists.txt b/libdnf/utils/CMakeLists.txt
ce91f9
index 71a1042c..4ec456ef 100644
ce91f9
--- a/libdnf/utils/CMakeLists.txt
ce91f9
+++ b/libdnf/utils/CMakeLists.txt
ce91f9
@@ -1,5 +1,4 @@
ce91f9
 add_subdirectory(bgettext)
ce91f9
-add_subdirectory(crypto)
ce91f9
 add_subdirectory(iniparser)
ce91f9
 add_subdirectory(regex)
ce91f9
 add_subdirectory(sqlite3)
ce91f9
diff --git a/libdnf/utils/crypto/CMakeLists.txt b/libdnf/utils/crypto/CMakeLists.txt
ce91f9
deleted file mode 100644
ce91f9
index 149d100c..00000000
ce91f9
--- a/libdnf/utils/crypto/CMakeLists.txt
ce91f9
+++ /dev/null
ce91f9
@@ -1,5 +0,0 @@
ce91f9
-set(UTILS_SOURCES
ce91f9
-    ${UTILS_SOURCES}
ce91f9
-    ${CMAKE_CURRENT_SOURCE_DIR}/sha1.cpp
ce91f9
-    PARENT_SCOPE
ce91f9
-)
ce91f9
diff --git a/libdnf/utils/crypto/sha1.cpp b/libdnf/utils/crypto/sha1.cpp
ce91f9
deleted file mode 100644
ce91f9
index 1533ee6b..00000000
ce91f9
--- a/libdnf/utils/crypto/sha1.cpp
ce91f9
+++ /dev/null
ce91f9
@@ -1,36 +0,0 @@
ce91f9
-#include <cstring>
ce91f9
-
ce91f9
-#include <iomanip>
ce91f9
-#include <sstream>
ce91f9
-
ce91f9
-#include "sha1.hpp"
ce91f9
-
ce91f9
-
ce91f9
-SHA1Hash::SHA1Hash()
ce91f9
-{
ce91f9
-    md_ctx = EVP_MD_CTX_new();
ce91f9
-    EVP_DigestInit_ex(md_ctx, EVP_sha1(), NULL);
ce91f9
-}
ce91f9
-
ce91f9
-
ce91f9
-void
ce91f9
-SHA1Hash::update(const char * data)
ce91f9
-{
ce91f9
-    EVP_DigestUpdate(md_ctx, data, strlen(data));
ce91f9
-}
ce91f9
-
ce91f9
-
ce91f9
-std::string
ce91f9
-SHA1Hash::hexdigest()
ce91f9
-{
ce91f9
-    unsigned char md[digestLength];
ce91f9
-    EVP_DigestFinal_ex(md_ctx, md, NULL);
ce91f9
-
ce91f9
-    std::stringstream ss;
ce91f9
-    for(int i=0; i
ce91f9
-        ss << std::setfill('0') << std::setw(2) << std::hex << static_cast<int>(md[i]);
ce91f9
-    }
ce91f9
-
ce91f9
-    EVP_MD_CTX_free(md_ctx);
ce91f9
-    return ss.str();
ce91f9
-}
ce91f9
diff --git a/libdnf/utils/crypto/sha1.hpp b/libdnf/utils/crypto/sha1.hpp
ce91f9
deleted file mode 100644
ce91f9
index 9f1dfdeb..00000000
ce91f9
--- a/libdnf/utils/crypto/sha1.hpp
ce91f9
+++ /dev/null
ce91f9
@@ -1,25 +0,0 @@
ce91f9
-#include <string>
ce91f9
-#include <openssl/sha.h>
ce91f9
-#include <openssl/evp.h>
ce91f9
-
ce91f9
-
ce91f9
-/*
ce91f9
-USAGE:
ce91f9
-
ce91f9
-SHA1Hash h;
ce91f9
-h.update("foo");
ce91f9
-h.update("bar");
ce91f9
-std::cout << h.hexdigest() << std::endl;
ce91f9
-*/
ce91f9
-
ce91f9
-
ce91f9
-class SHA1Hash {
ce91f9
-public:
ce91f9
-    SHA1Hash();
ce91f9
-    void update(const char *data);
ce91f9
-    std::string hexdigest();
ce91f9
-    static constexpr int digestLength = SHA_DIGEST_LENGTH;
ce91f9
-
ce91f9
-private:
ce91f9
-    EVP_MD_CTX *md_ctx;
ce91f9
-};
ce91f9
-- 
ce91f9
2.34.1
ce91f9