Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package keylime for openSUSE:Factory checked 
in at 2022-01-21 01:24:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/keylime (Old)
 and      /work/SRC/openSUSE:Factory/.keylime.new.1938 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "keylime"

Fri Jan 21 01:24:58 2022 rev:11 rq:947243 version:6.2.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/keylime/keylime.changes  2022-01-13 
00:22:14.719924836 +0100
+++ /work/SRC/openSUSE:Factory/.keylime.new.1938/keylime.changes        
2022-01-21 01:25:02.742741216 +0100
@@ -1,0 +2,9 @@
+Tue Jan 18 14:28:05 UTC 2022 - Alberto Planas Dominguez <apla...@suse.com>
+
+- Add 0001-config-support-merge-multiple-config-files.patch
+  This will allow the merge of config files in /usr/etc and /etc.
+- Move the configuration file to /usr/etc in new distributions
+- Add 0001-ca-support-back-old-cyptography-API.patch
+  This is only required for SLE, but the API is compatible with new versions
+
+-------------------------------------------------------------------

New:
----
  0001-ca-support-back-old-cyptography-API.patch
  0001-config-support-merge-multiple-config-files.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ keylime.spec ++++++
--- /var/tmp/diff_new_pack.h2NGLR/_old  2022-01-21 01:25:03.790734031 +0100
+++ /var/tmp/diff_new_pack.h2NGLR/_new  2022-01-21 01:25:03.794734005 +0100
@@ -40,6 +40,10 @@
 Patch3:         config-libefivars.diff
 # PATCH-FIX-UPSTREAM 0001-Drop-dataclasses-module-usage.patch 
(gh#keylime/keylime!827)
 Patch4:         0001-Drop-dataclasses-module-usage.patch
+# PATCH-FIX-UPSTREAM 0001-config-support-merge-multiple-config-files.patch 
(gh#keylime/keylime!829)
+Patch5:         0001-config-support-merge-multiple-config-files.patch
+# PATCH-FIX-UPSTREAM 0001-ca-support-back-old-cyptography-API.patch 
(gh#keylime/keylime!839)
+Patch6:         0001-ca-support-back-old-cyptography-API.patch
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  fdupes
 BuildRequires:  firewall-macros
@@ -154,7 +158,13 @@
 
 %python_expand %fdupes %{buildroot}%{$python_sitelib}
 
+%if 0%{?suse_version} >= 1550
+# setup.py copy keylime.conf in /etc, but we expect it in /usr/etc
+rm %{buildroot}%{_sysconfdir}/%{srcname}.conf
+install -Dpm 600 %{srcname}.conf 
%{buildroot}%{_prefix}%{_sysconfdir}/%{srcname}.conf
+%else
 install -Dpm 600 %{srcname}.conf %{buildroot}%{_sysconfdir}/%{srcname}.conf
+%endif
 install -Dpm 644 ./services/%{srcname}_agent.service 
%{buildroot}%{_unitdir}/%{srcname}_agent.service
 install -Dpm 644 ./services/%{srcname}_verifier.service 
%{buildroot}%{_unitdir}/%{srcname}_verifier.service
 install -Dpm 644 ./services/%{srcname}_registrar.service 
%{buildroot}%{_unitdir}/%{srcname}_registrar.service
@@ -253,7 +263,11 @@
 %{python_sitelib}/*
 
 %files -n %{srcname}-config
+%if 0%{?suse_version} >= 1550
+%{_prefix}%{_sysconfdir}/%{srcname}.conf
+%else
 %config(noreplace) %{_sysconfdir}/%{srcname}.conf
+%endif
 
 %files -n %{srcname}-firewalld
 %dir %{_prefix}/lib/firewalld

++++++ 0001-ca-support-back-old-cyptography-API.patch ++++++
>From 57d033e9a9a5946a63c9d161381dee4830017531 Mon Sep 17 00:00:00 2001
From: Alberto Planas <apla...@suse.com>
Date: Tue, 18 Jan 2022 15:04:55 +0100
Subject: [PATCH] ca: support back old cyptography API

After [1] we moved from M2Crypto to cryptography, and we started to drop
the use of the, now optional, `backend` parameter.  This is OK as we are
explicit on the minimal version of cryptography, but we still use in
other modules (like crypto.py or tpm_main.py for example) the old API.

This patch use the optional `backend` parameter to unify the API usage,
and still be compatible with some older versions of cryptography.

[1] https://github.com/keylime/keylime/pull/747

Signed-off-by: Alberto Planas <apla...@suse.com>
---
 keylime/ca_impl_cfssl.py   | 2 ++
 keylime/ca_impl_openssl.py | 4 ++++
 keylime/ca_util.py         | 6 +++++-
 3 files changed, 11 insertions(+), 1 deletion(-)

Index: keylime-v6.2.1/keylime/ca_impl_cfssl.py
===================================================================
--- keylime-v6.2.1.orig/keylime/ca_impl_cfssl.py
+++ keylime-v6.2.1/keylime/ca_impl_cfssl.py
@@ -127,6 +127,7 @@ def mk_cacert(name=None):
         privkey = serialization.load_pem_private_key(
             body['result']['private_key'].encode('utf-8'),
             password=None,
+            backend=default_backend(),
         )
         cert = x509.load_pem_x509_certificate(
             data=body['result']['certificate'].encode('utf-8'),
@@ -212,6 +213,7 @@ def mk_signed_cert(cacert, ca_pk, name,
         pk = serialization.load_pem_private_key(
             body['result']['private_key'].encode('utf-8'),
             password=None,
+            backend=default_backend(),
         )
         cert = x509.load_pem_x509_certificate(
             data=body['result']['certificate'].encode('utf-8'),
Index: keylime-v6.2.1/keylime/ca_impl_openssl.py
===================================================================
--- keylime-v6.2.1.orig/keylime/ca_impl_openssl.py
+++ keylime-v6.2.1/keylime/ca_impl_openssl.py
@@ -6,6 +6,7 @@ Copyright 2017 Massachusetts Institute o
 import datetime
 
 from cryptography import x509
+from cryptography.hazmat.backends import default_backend
 from cryptography.hazmat.primitives import hashes
 from cryptography.hazmat.primitives.asymmetric import rsa
 from cryptography.x509.oid import NameOID
@@ -63,6 +64,7 @@ def mk_request(bits, common_name):
     privkey = rsa.generate_private_key(
         public_exponent=65537,
         key_size=bits,
+        backend=default_backend(),
     )
 
     cert_req = x509.CertificateBuilder()
@@ -128,6 +130,7 @@ def mk_cacert(name=None):
     cert = cert_req.sign(
         private_key=privkey,
         algorithm=hashes.SHA256(),
+        backend=default_backend(),
     )
 
     return cert, privkey, pubkey
@@ -177,6 +180,7 @@ def mk_signed_cert(cacert, ca_privkey, n
     cert = cert_req.sign(
         private_key=ca_privkey,
         algorithm=hashes.SHA256(),
+        backend=default_backend(),
     )
     return cert, privkey
 
Index: keylime-v6.2.1/keylime/ca_util.py
===================================================================
--- keylime-v6.2.1.orig/keylime/ca_util.py
+++ keylime-v6.2.1/keylime/ca_util.py
@@ -88,7 +88,11 @@ def cmd_mkcert(workingdir, name):
         config.ch_dir(workingdir, logger)
         priv = read_private()
         cacert = load_cert_by_path('cacert.crt')
-        ca_pk = serialization.load_pem_private_key(priv[0]['ca'], 
password=None)
+        ca_pk = serialization.load_pem_private_key(
+            priv[0]['ca'],
+            password=None,
+            backend=default_backend()
+        )
 
         cert, pk = ca_impl.mk_signed_cert(
             cacert, ca_pk, name, priv[0]['lastserial'] + 1)

++++++ 0001-config-support-merge-multiple-config-files.patch ++++++
>From b6879e3e3c238609a7f001b2536c699c63f050f9 Mon Sep 17 00:00:00 2001
From: Alberto Planas <apla...@suse.com>
Date: Wed, 12 Jan 2022 15:42:56 +0100
Subject: [PATCH] config: support merge multiple config files

Currently Keylime read the config for all the services from the same
file, in /etc/keylime.conf.

This commit support the load of multiple configuration files, and
merge the contents together.  This will enable the separation of a
system wide configuration file in /usr/etc/keylime.conf, and a admin
owerwrite in /etc/keylime.conf.

Signed-off-by: Alberto Planas <apla...@suse.com>
---
 keylime/cloud_verifier_common.py  |  2 +-
 keylime/cloud_verifier_tornado.py |  8 +--
 keylime/config.py                 | 93 +++++++++++--------------------
 keylime/ima_ast.py                |  2 +-
 keylime/keylime_logging.py        |  4 +-
 keylime/revocation_notifier.py    |  2 +-
 test/data/config/keylime-1.conf   |  3 +
 test/data/config/keylime-2.conf   |  3 +
 test/data/config/keylime-3.conf   |  4 ++
 test/test_config.py               | 82 +++++++++++++++++++++++++++
 10 files changed, 133 insertions(+), 70 deletions(-)
 create mode 100644 test/data/config/keylime-1.conf
 create mode 100644 test/data/config/keylime-2.conf
 create mode 100644 test/data/config/keylime-3.conf
 create mode 100644 test/test_config.py

Index: keylime-v6.2.1/keylime/cloud_verifier_common.py
===================================================================
--- keylime-v6.2.1.orig/keylime/cloud_verifier_common.py
+++ keylime-v6.2.1/keylime/cloud_verifier_common.py
@@ -368,7 +368,7 @@ def process_get_status(agent):
 
 def notify_error(agent, msgtype='revocation', event=None):
     send_mq = config.getboolean('cloud_verifier', 'revocation_notifier')
-    send_webhook = config.getboolean('cloud_verifier', 
'revocation_notifier_webhook', False)
+    send_webhook = config.getboolean('cloud_verifier', 
'revocation_notifier_webhook', fallback=False)
     if not (send_mq or send_webhook):
         return
 
Index: keylime-v6.2.1/keylime/cloud_verifier_tornado.py
===================================================================
--- keylime-v6.2.1.orig/keylime/cloud_verifier_tornado.py
+++ keylime-v6.2.1/keylime/cloud_verifier_tornado.py
@@ -330,7 +330,7 @@ class AgentsHandler(BaseHandler):
             logger.info('DELETE returning 404 response. agent id: %s not 
found.', agent_id)
             return
 
-        verifier_id = config.get('cloud_verifier', 'cloudverifier_id', 
cloud_verifier_common.DEFAULT_VERIFIER_ID)
+        verifier_id = config.get('cloud_verifier', 'cloudverifier_id', 
fallback=cloud_verifier_common.DEFAULT_VERIFIER_ID)
         if verifier_id != agent.verifier_id:
             config.echo_json_response(self, 404, "agent id associated to this 
verifier")
             logger.info('DELETE returning 404 response. agent id: %s not 
associated to this verifer.', agent_id)
@@ -417,7 +417,7 @@ class AgentsHandler(BaseHandler):
                     agent_data['pcr10'] = START_HASH
                     agent_data['next_ima_ml_entry'] = 0
                     agent_data['learned_ima_keyrings'] = {}
-                    agent_data['verifier_id'] = config.get('cloud_verifier', 
'cloudverifier_id', cloud_verifier_common.DEFAULT_VERIFIER_ID)
+                    agent_data['verifier_id'] = config.get('cloud_verifier', 
'cloudverifier_id', fallback=cloud_verifier_common.DEFAULT_VERIFIER_ID)
                     agent_data['verifier_ip'] = config.get('cloud_verifier', 
'cloudverifier_ip')
                     agent_data['verifier_port'] = config.get('cloud_verifier', 
'cloudverifier_port')
 
@@ -492,7 +492,7 @@ class AgentsHandler(BaseHandler):
                 config.echo_json_response(self, 400, "uri not supported")
                 logger.warning("PUT returning 400 response. uri not supported")
             try:
-                verifier_id = config.get('cloud_verifier', 'cloudverifier_id', 
cloud_verifier_common.DEFAULT_VERIFIER_ID)
+                verifier_id = config.get('cloud_verifier', 'cloudverifier_id', 
fallback=cloud_verifier_common.DEFAULT_VERIFIER_ID)
                 agent = session.query(VerfierMain).filter_by(
                     agent_id=agent_id, verifier_id=verifier_id).one()
             except SQLAlchemyError as e:
@@ -971,7 +971,7 @@ def main():
 
     cloudverifier_port = config.get('cloud_verifier', 'cloudverifier_port')
     cloudverifier_host = config.get('cloud_verifier', 'cloudverifier_ip')
-    cloudverifier_id = config.get('cloud_verifier', 'cloudverifier_id', 
cloud_verifier_common.DEFAULT_VERIFIER_ID)
+    cloudverifier_id = config.get('cloud_verifier', 'cloudverifier_id', 
fallback=cloud_verifier_common.DEFAULT_VERIFIER_ID)
 
     # allow tornado's max upload size to be configurable
     max_upload_size = None
Index: keylime-v6.2.1/keylime/config.py
===================================================================
--- keylime-v6.2.1.orig/keylime/config.py
+++ keylime-v6.2.1/keylime/config.py
@@ -6,7 +6,6 @@ Copyright 2017 Massachusetts Institute o
 import os
 import os.path
 import configparser
-import sys
 import urllib.parse
 import re
 from http.server import BaseHTTPRequestHandler
@@ -117,69 +116,39 @@ TPM_LIBS_PATH = '/usr/local/lib/'
 TPM_TOOLS_PATH = '/usr/local/bin/'
 
 
-CONFIG_FILE = os.getenv('KEYLIME_CONFIG', '/etc/keylime.conf')
-
-
-WARN = False
-if not os.path.exists(CONFIG_FILE):
-    # try to locate the config file next to the script if bundled
-    if getattr(sys, 'frozen', False):
-        CONFIG_FILE = os.path.dirname(
-            os.path.abspath(sys.executable)) + "/keylime.conf"
-    else:
-        # instead try to get config file from python data_files install
-        CONFIG_FILE = os.path.dirname(os.path.abspath(
-            __file__)) + "/../package_default/keylime.conf"
-        WARN = True
-
-if not os.path.exists(CONFIG_FILE):
-    raise Exception(f"{CONFIG_FILE} does not exist. Please set environment"
-                    f"variable KEYLIME_CONFIG or see {__file__} for more"
-                    f"details")
-print(f"Using config file {CONFIG_FILE}")
-if WARN:
-    print("WARNING: Keylime is using the config file from its installation 
location. \n\tWe recommend you copy keylime.conf to /etc/ to customize it.")
-
-
-_CURRENT_CONFIG = None
+# Config files can be merged together, reading from the system to the
+# user.
+CONFIG_FILES = [
+    os.path.expanduser("~/.config/keylime.conf"), "/etc/keylime.conf", 
"/usr/etc/keylime.conf"
+]
+if "KEYLIME_CONFIG" in os.environ:
+    CONFIG_FILES.insert(0, os.environ["KEYLIME_CONFIG"])
 
 
 def get_config():
-    global _CURRENT_CONFIG
-    if _CURRENT_CONFIG is None:
-        # read the config file
-        _CURRENT_CONFIG = configparser.ConfigParser()
-        _CURRENT_CONFIG.read(CONFIG_FILE)
-    return _CURRENT_CONFIG
-
-
-def get(section, option, fallback=None):
-    if fallback is not None:
-        return get_config().get(section, option, fallback=fallback)
-    return get_config().get(section, option)
-
-
-def getint(section, option, fallback=None):
-    if fallback is not None:
-        return get_config().get(section, option, fallback=fallback)
-    return get_config().getint(section, option)
-
-
-def getboolean(section, option, fallback=None):
-    if fallback is not None:
-        return get_config().getboolean(section, option, fallback=fallback)
-    return get_config().getboolean(section, option)
-
-
-def getfloat(section, option, fallback=None):
-    if fallback is not None:
-        return get_config().get(section, option, fallback=fallback)
-    return get_config().getfloat(section, option)
-
-
-def has_option(section, option):
-    return get_config().has_option(section, option)
-
+    """Read configuration files and merge them together."""
+    if not getattr(get_config, "config", None):
+        # TODO - use logger and be sure that all variables have a
+        # propper default, and the sections are initialized
+        if not any(os.path.exists(c) for c in CONFIG_FILES):
+            print(f"Config file not found in {CONFIG_FILES}. Please set "
+                  f"environment variable KEYLIME_CONFIG or see {__file__} "
+                  "for more details")
+
+        # Validate that at least one config file is present
+        get_config.config = configparser.ConfigParser()
+        config_files = get_config.config.read(CONFIG_FILES)
+        # TODO - use the logger
+        print(f"Reading configuration from {config_files}")
+    return get_config.config
+
+
+# Re-export some utility functions
+get = get_config().get
+getint = get_config().getint
+getboolean = get_config().getboolean
+getfloat = get_config().getfloat
+has_option = get_config().has_option
 
 if not REQUIRE_ROOT:
     DEFAULT_WORK_DIR = os.path.abspath(".")
@@ -319,6 +288,6 @@ TPM_DATA_PCR = 16
 BOOTSTRAP_KEY_SIZE = 32
 
 # choose between cfssl or openssl for creating CA certificates
-CA_IMPL = get_config().get('general', 'ca_implementation')
+CA_IMPL = get_config().get('general', 'ca_implementation', fallback='openssl')
 
 CRL_PORT = 38080
Index: keylime-v6.2.1/keylime/ima_ast.py
===================================================================
--- keylime-v6.2.1.orig/keylime/ima_ast.py
+++ keylime-v6.2.1/keylime/ima_ast.py
@@ -351,7 +351,7 @@ class Entry:
         if self.template_hash == FF_HASH:
             logger.warning("Skipped template_hash validation entry with 
FF_HASH")
             # By default ToMToU errors are not treated as a failure
-            if config.getboolean("cloud_verifier", "tomtou_errors", False):
+            if config.getboolean("cloud_verifier", "tomtou_errors", 
fallback=False):
                 failure.add_event("tomtou", "hash validation was skipped", 
True)
             return failure
         if self.template_hash != self.mode.hash():
Index: keylime-v6.2.1/keylime/keylime_logging.py
===================================================================
--- keylime-v6.2.1.orig/keylime/keylime_logging.py
+++ keylime-v6.2.1/keylime/keylime_logging.py
@@ -19,7 +19,9 @@ if not config.REQUIRE_ROOT:
 else:
     LOGSTREAM = LOGDIR + '/keylime-stream.log'
 
-logging.config.fileConfig(config.CONFIG_FILE)
+for config_file in reversed(config.CONFIG_FILES):
+    if os.path.exists(config_file):
+        logging.config.fileConfig(config_file)
 
 
 def set_log_func(loglevel, logger):
Index: keylime-v6.2.1/keylime/revocation_notifier.py
===================================================================
--- keylime-v6.2.1.orig/keylime/revocation_notifier.py
+++ keylime-v6.2.1/keylime/revocation_notifier.py
@@ -81,7 +81,7 @@ def notify(tosend):
 
 
 def notify_webhook(tosend):
-    url = config.get('cloud_verifier', 'webhook_url', '')
+    url = config.get('cloud_verifier', 'webhook_url', fallback='')
     # Check if a url was specified
     if url == '':
         return
Index: keylime-v6.2.1/test/data/config/keylime-1.conf
===================================================================
--- /dev/null
+++ keylime-v6.2.1/test/data/config/keylime-1.conf
@@ -0,0 +1,3 @@
+[default]
+
+attribute_1 = value_1
Index: keylime-v6.2.1/test/data/config/keylime-2.conf
===================================================================
--- /dev/null
+++ keylime-v6.2.1/test/data/config/keylime-2.conf
@@ -0,0 +1,3 @@
+[default]
+
+attribute_2= value_2
Index: keylime-v6.2.1/test/data/config/keylime-3.conf
===================================================================
--- /dev/null
+++ keylime-v6.2.1/test/data/config/keylime-3.conf
@@ -0,0 +1,4 @@
+[default]
+
+attribute_1 = value_1_3
+attribute_3 = value_3
Index: keylime-v6.2.1/test/test_config.py
===================================================================
--- /dev/null
+++ keylime-v6.2.1/test/test_config.py
@@ -0,0 +1,82 @@
+import importlib
+import os
+import unittest
+
+from keylime import config
+
+CONFIG_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), 
"data/config"))
+
+
+class TestConfig(unittest.TestCase):
+    def setUp(self):
+        """The config module should be reloaded."""
+        # Because we can alter global state, we should reload the
+        # config module before every test
+        importlib.reload(config)
+        # Remove a side effect of some variables pre-loading the
+        # configuration files
+        del config.get_config.config
+
+    def test_default_config_files(self):
+        """Test default config file list."""
+        self.assertEqual(
+            config.CONFIG_FILES,
+            [
+                os.path.expanduser("~/.config/keylime.conf"),
+                "/etc/keylime.conf",
+                "/usr/etc/keylime.conf",
+            ],
+        )
+
+    def test_no_config(self):
+        """Test that no config files is an empty set."""
+        c = config.get_config()
+        self.assertEqual(c.get("default", "value_1", fallback=None), None)
+
+    def test_single_config(self):
+        """Test reading a single config file."""
+        config.CONFIG_FILES = [os.path.join(CONFIG_DIR, "keylime-1.conf")]
+        c = config.get_config()
+        self.assertEqual(c.get("default", "attribute_1"), "value_1")
+
+    def test_multiple_config(self):
+        """Test reading multiple config files."""
+        config.CONFIG_FILES = [
+            os.path.join(CONFIG_DIR, "keylime-1.conf"),
+            os.path.join(CONFIG_DIR, "keylime-2.conf"),
+        ]
+        c = config.get_config()
+        self.assertEqual(c.get("default", "attribute_1"), "value_1")
+        self.assertEqual(c.get("default", "attribute_2"), "value_2")
+
+    def test_merge_config(self):
+        """Test reading multiple config files and merging them."""
+        config.CONFIG_FILES = [
+            os.path.join(CONFIG_DIR, "keylime-1.conf"),
+            os.path.join(CONFIG_DIR, "keylime-2.conf"),
+            os.path.join(CONFIG_DIR, "keylime-3.conf"),
+        ]
+        c = config.get_config()
+        self.assertEqual(c.get("default", "attribute_1"), "value_1_3")
+        self.assertEqual(c.get("default", "attribute_2"), "value_2")
+        self.assertEqual(c.get("default", "attribute_3"), "value_3")
+
+    def test_cache_config(self):
+        """Test the config is properly cached between calls."""
+        c = config.get_config()
+        self.assertEqual(c.get("default", "attribute", fallback=None), None)
+
+        c.add_section("default")
+        c.set("default", "attribute", "value")
+        self.assertEqual(c.get("default", "attribute"), "value")
+
+        c_copy = config.get_config()
+        self.assertEqual(c_copy.get("default", "attribute"), "value")
+
+    def test_reexport_function(self):
+        """Test re-exported functions to access data."""
+        self.assertEqual(config.get("default", "attribute", fallback=None), 
None)
+
+
+if __name__ == "__main__":
+    unittest.main()

Reply via email to