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

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