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-03-02 18:20:22
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/keylime (Old)
 and      /work/SRC/openSUSE:Factory/.keylime.new.1958 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "keylime"

Wed Mar  2 18:20:22 2022 rev:16 rq:958269 version:6.3.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/keylime/keylime.changes  2022-02-26 
17:02:31.279540081 +0100
+++ /work/SRC/openSUSE:Factory/.keylime.new.1958/keylime.changes        
2022-03-02 18:20:34.724654834 +0100
@@ -1,0 +2,9 @@
+Thu Feb 24 15:50:53 UTC 2022 - Alberto Planas Dominguez <[email protected]>
+
+- Add upstream patches:
+  * drop_privileges_of_agent_process_after_startup.patch
+  * config_fix_config_search_order.patch
+  * services_add_keylime_agent_secure_mount_service.patch
+- Configure the agent to run as non-root
+
+-------------------------------------------------------------------

New:
----
  config_fix_config_search_order.patch
  drop_privileges_of_agent_process_after_startup.patch
  keylime-user.conf
  services_add_keylime_agent_secure_mount_service.patch

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

Other differences:
------------------
++++++ keylime.spec ++++++
--- /var/tmp/diff_new_pack.HAjvWj/_old  2022-03-02 18:20:35.448654860 +0100
+++ /var/tmp/diff_new_pack.HAjvWj/_new  2022-03-02 18:20:35.452654859 +0100
@@ -32,14 +32,22 @@
 URL:            https://github.com/keylime/keylime
 Source0:        %{name}-v%{version}.tar.xz
 Source1:        keylime.xml
+Source2:        %{name}-user.conf
 # PATCH-FIX-OPENSUSE keylime.conf.diff
 Patch1:         keylime.conf.diff
 # PATCH-FIX-OPENSUSE config-libefivars.diff
 Patch2:         config-libefivars.diff
+# PATCH-FIX-UPSTREAM drop_privileges_of_agent_process_after_startup.patch 
(gh#keylime/keylime!900)
+Patch3:         drop_privileges_of_agent_process_after_startup.patch
+# PATCH-FIX-UPSTREAM config_fix_config_search_order.patch 
(gh#keylime/keylime!902)
+Patch4:         config_fix_config_search_order.patch
+# PATCH-FIX-UPSTREAM services_add_keylime_agent_secure_mount_service.patch 
(gh#keylime/keylime!903)
+Patch5:         services_add_keylime_agent_secure_mount_service.patch
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  fdupes
 BuildRequires:  firewall-macros
 BuildRequires:  python-rpm-macros
+BuildRequires:  sysuser-tools
 Requires:       libtss2-tcti-device0
 Requires:       libtss2-tcti-tabrmd0
 Requires:       procps
@@ -128,6 +136,7 @@
 
 %build
 %python_build
+%sysusers_generate_pre %{SOURCE2} %{name} %{name}-user.conf
 
 %install
 export VERSION=%{version}
@@ -153,6 +162,7 @@
 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}_agent_secure.mount 
%{buildroot}%{_unitdir}/var-lib-keylime-secure.mount
 install -Dpm 644 ./services/%{srcname}_verifier.service 
%{buildroot}%{_unitdir}/%{srcname}_verifier.service
 install -Dpm 644 ./services/%{srcname}_registrar.service 
%{buildroot}%{_unitdir}/%{srcname}_registrar.service
 
@@ -162,6 +172,9 @@
 cp -r ./tpm_cert_store %{buildroot}%{_sharedstatedir}/%{srcname}/
 %fdupes %{buildroot}%{_sharedstatedir}/%{srcname}/
 
+mkdir -p %{buildroot}%{_sysusersdir}
+install -m 0644 %{SOURCE2} %{buildroot}%{_sysusersdir}/
+
 # %%check
 # %%pyunittest -v
 
@@ -190,6 +203,8 @@
 %post -n %{srcname}-firewalld
 %firewalld_reload
 
+%pre -n %{srcname}-tpm_cert_store -f %{srcname}.pre
+
 %pre -n %{srcname}-verifier
 %service_add_pre %{srcname}_verifier.service
 
@@ -216,15 +231,19 @@
 
 %pre -n %{srcname}-agent
 %service_add_pre %{srcname}_agent.service
+%service_add_pre var-lib-keylime-secure.mount
 
 %post -n %{srcname}-agent
 %service_add_post %{srcname}_agent.service
+%service_add_post var-lib-keylime-secure.mount
 
 %preun -n %{srcname}-agent
 %service_del_preun %{srcname}_agent.service
+%service_del_preun var-lib-keylime-secure.mount
 
 %postun -n %{srcname}-agent
 %service_del_postun %{srcname}_agent.service
+%service_del_postun var-lib-keylime-secure.mount
 
 %files %{python_files}
 %doc README.md
@@ -253,9 +272,10 @@
 %{_prefix}/lib/firewalld/services/keylime.xml
 
 %files -n %{srcname}-tpm_cert_store
-%dir %attr(0700,root,root) %{_sharedstatedir}/keylime
+%dir %attr(0700,keylime,tss) %{_sharedstatedir}/keylime
 %dir %{_sharedstatedir}/keylime/tpm_cert_store
 %{_sharedstatedir}/keylime/tpm_cert_store/*
+%{_sysusersdir}/%{srcname}-user.conf
 
 %files -n %{srcname}-verifier
 %{_unitdir}/%{srcname}_verifier.service
@@ -265,5 +285,6 @@
 
 %files -n %{srcname}-agent
 %{_unitdir}/%{srcname}_agent.service
+%{_unitdir}/var-lib-keylime-secure.mount
 
 %changelog

++++++ config_fix_config_search_order.patch ++++++
>From b1eb01629b6af035dc95d6815ca4731922fb0fa4 Mon Sep 17 00:00:00 2001
From: Alberto Planas <[email protected]>
Date: Mon, 28 Feb 2022 17:37:45 +0100
Subject: [PATCH] config: fix config search order

The configuration search order for RawConfigParser is from left (less
priority) to right (high priority).

This patch set the correct search order and adjust the test.

Signed-off-by: Alberto Planas <[email protected]>
---
 keylime/config.py   | 5 +++--
 test/test_config.py | 4 ++--
 2 files changed, 5 insertions(+), 4 deletions(-)

Index: keylime-v6.3.1/keylime/config.py
===================================================================
--- keylime-v6.3.1.orig/keylime/config.py
+++ keylime-v6.3.1/keylime/config.py
@@ -7,7 +7,8 @@ import os.path
 import configparser
 from typing import Optional
 
-# resources in importlib is a Python 3.7 feature, so we disable fallback 
support if we cannot import this module
+# resources in importlib is a Python 3.7 feature, so we disable
+# fallback support if we cannot import this module
 try:
     from importlib import resources
     _CONFIG_FALLBACK = True
@@ -118,7 +119,7 @@ if not REQUIRE_ROOT:
 # 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"
+    "/usr/etc/keylime.conf", "/etc/keylime.conf", 
os.path.expanduser("~/.config/keylime.conf")
 ]
 if "KEYLIME_CONFIG" in os.environ:
     CONFIG_FILES.insert(0, os.environ["KEYLIME_CONFIG"])
Index: keylime-v6.3.1/test/test_config.py
===================================================================
--- keylime-v6.3.1.orig/test/test_config.py
+++ keylime-v6.3.1/test/test_config.py
@@ -22,9 +22,9 @@ class TestConfig(unittest.TestCase):
         self.assertEqual(
             config.CONFIG_FILES,
             [
-                os.path.expanduser("~/.config/keylime.conf"),
-                "/etc/keylime.conf",
                 "/usr/etc/keylime.conf",
+                "/etc/keylime.conf",
+                os.path.expanduser("~/.config/keylime.conf"),
             ],
         )
 

++++++ drop_privileges_of_agent_process_after_startup.patch ++++++
>From d8d0184fc82a7746a52f9c2ead9069a0593adcfa Mon Sep 17 00:00:00 2001
From: Stefan Berger <[email protected]>
Date: Wed, 23 Feb 2022 12:58:30 -0500
Subject: [PATCH 1/7] ima: Refactor read_measurement_list() to take file as
 argument

Prepare ima.read_measurement_list() to work with an open file by
refactoring the function to take a file as an argument rather than
the filename. Modify all callers to pass in an open file.

Signed-off-by: Stefan Berger <[email protected]>
---
 keylime/ima.py           | 13 ++++++-------
 keylime/ima_test.py      | 10 +++++++---
 keylime/keylime_agent.py |  7 ++++++-
 3 files changed, 19 insertions(+), 11 deletions(-)

Index: keylime-v6.3.1/keylime/ima.py
===================================================================
--- keylime-v6.3.1.orig/keylime/ima.py
+++ keylime-v6.3.1/keylime/ima.py
@@ -71,7 +71,7 @@ class IMAMeasurementList:
         return best
 
 
-def read_measurement_list(filename, nth_entry):
+def read_measurement_list(ima_log_file, nth_entry):
     """ Read the IMA measurement list starting from a given entry.
         The entry may be of any value 0 <= entry <= entries_in_log where
         entries_in_log + 1 indicates that the client wants to read the next 
entry
@@ -86,14 +86,13 @@ def read_measurement_list(filename, nth_
     # Try to find the closest entry to the nth_entry
     num_entries, filesize = IMAML.find(nth_entry)
 
-    if not os.path.exists(filename):
+    if not ima_log_file:
         IMAML.reset()
         nth_entry = 0
-        logger.warning("IMA measurement list not available: %s", filename)
+        logger.warning("IMA measurement list not available: %s", config.IMA_ML)
     else:
-        with open(filename, 'r', encoding="utf-8") as f:
-            f.seek(filesize)
-            filedata = f.read()
+        ima_log_file.seek(filesize)
+        filedata = ima_log_file.read()
         # filedata now corresponds to starting list at entry number 
'IMAML.num_entries'
         # find n-th entry and determine number of total entries in file now
         offset = 0
@@ -112,7 +111,7 @@ def read_measurement_list(filename, nth_
         # Nothing found? User request beyond next-expected entry.
         # Start over with entry 0. This cannot recurse again.
         if ml is None:
-            return read_measurement_list(filename, 0)
+            return read_measurement_list(ima_log_file, 0)
 
     return ml, nth_entry, num_entries
 
Index: keylime-v6.3.1/keylime/ima_test.py
===================================================================
--- keylime-v6.3.1.orig/keylime/ima_test.py
+++ keylime-v6.3.1/keylime/ima_test.py
@@ -16,25 +16,29 @@ class TestIMA(unittest.TestCase):
         tf.write(filedata.encode('utf-8'))
         tf.flush()
 
+        # Open file again to get str on read()
+        ima_log_file = open(tf.name, 'r', encoding="utf-8")
+
         # Request the 2nd entry, which is available
-        ml, nth_entry, num_entries = ima.read_measurement_list(tf.name, 2)
+        ml, nth_entry, num_entries = ima.read_measurement_list(ima_log_file, 2)
         self.assertEqual(num_entries, 3)
         self.assertEqual(nth_entry, 2)
         self.assertTrue(ml.startswith('2-entry'))
 
         # Request the 3rd entry, which is not available yet, thus we get an 
empty list
-        ml, nth_entry, num_entries = ima.read_measurement_list(tf.name, 3)
+        ml, nth_entry, num_entries = ima.read_measurement_list(ima_log_file, 3)
         self.assertEqual(num_entries, 3)
         self.assertEqual(nth_entry, 3)
         self.assertTrue(ml == '')
 
         # Request the 4th entry, which is beyond the next entry; since this is 
wrong,
         # we expect the entire list now.
-        ml, nth_entry, num_entries = ima.read_measurement_list(tf.name, 4)
+        ml, nth_entry, num_entries = ima.read_measurement_list(ima_log_file, 4)
         self.assertEqual(num_entries, 3)
         self.assertEqual(nth_entry, 0)
         self.assertTrue(ml.startswith('0-entry'))
 
+        ima_log_file.close()
         tf.close()
 
 if __name__ == '__main__':
Index: keylime-v6.3.1/keylime/keylime_agent.py
===================================================================
--- keylime-v6.3.1.orig/keylime/keylime_agent.py
+++ keylime-v6.3.1/keylime/keylime_agent.py
@@ -43,6 +43,7 @@ from keylime import json
 from keylime import revocation_notifier
 from keylime import registrar_client
 from keylime import secure_mount
+from keylime import user_utils
 from keylime import web_util
 from keylime import api_version as keylime_api_version
 from keylime.common import algorithms, validators
@@ -181,7 +182,7 @@ class Handler(BaseHTTPRequestHandler):
                 ima_ml_entry = int(ima_ml_entry)
                 if ima_ml_entry > self.server.next_ima_ml_entry:
                     ima_ml_entry = 0
-                ml, nth_entry, num_entries = 
ima.read_measurement_list(config.IMA_ML, ima_ml_entry)
+                ml, nth_entry, num_entries = 
ima.read_measurement_list(self.server.ima_log_file, ima_ml_entry)
                 if num_entries > 0:
                     response['ima_measurement_list'] = ml
                     response['ima_measurement_list_entry'] = nth_entry
@@ -192,12 +193,10 @@ class Handler(BaseHTTPRequestHandler):
             # generally speaking, retrieving the 15Kbytes of a boot log does 
not seem significant compared to the
             # potential Mbytes of an IMA measurement list.
             if TPM_Utilities.check_mask(imaMask, config.MEASUREDBOOT_PCRS[0]):
-                if not os.path.exists(config.MEASUREDBOOT_ML):
-                    logger.warning("TPM2 event log not available: %s", 
config.MEASUREDBOOT_ML)
+                if not self.server.tpm_log_file_data:
+                    logger.warning(f"TPM2 event log not available: 
{config.MEASUREDBOOT_ML}")
                 else:
-                    with open(config.MEASUREDBOOT_ML, 'rb') as f:
-                        el = base64.b64encode(f.read())
-                    response['mb_measurement_list'] = el
+                    response['mb_measurement_list'] = 
self.server.tpm_log_file_data
 
             web_util.echo_json_response(self, 200, "Success", response)
             logger.info('GET %s quote returning 200 response.', 
rest_params["quotes"])
@@ -398,7 +397,7 @@ class CloudAgentHTTPServer(ThreadingMixI
     next_ima_ml_entry = 0 # The next IMA log offset the verifier may ask for.
     boottime = int(psutil.boot_time())
 
-    def __init__(self, server_address, RequestHandlerClass, agent_uuid, 
contact_ip):
+    def __init__(self, server_address, RequestHandlerClass, agent_uuid, 
contact_ip, ima_log_file, tpm_log_file_data):
         """Constructor overridden to provide ability to pass configuration 
arguments to the server"""
         # Find the locations for the U/V transport and mTLS key and 
certificate.
         # They are either relative to secdir (/var/lib/keylime/secure) or 
absolute paths.
@@ -454,6 +453,8 @@ class CloudAgentHTTPServer(ThreadingMixI
             self, server_address, RequestHandlerClass)
         self.enc_keyname = config.get('cloud_agent', 'enc_keyname')
         self.agent_uuid = agent_uuid
+        self.ima_log_file = ima_log_file
+        self.tpm_log_file_data = tpm_log_file_data
 
     def add_U(self, u):
         """Threadsafe method for adding a U value received from the Tenant
@@ -617,6 +618,15 @@ def main():
         if not os.access(ML, os.F_OK):
             logger.warning("Measurement list path %s not accessible by agent. 
Any attempt to instruct it to access this path - via \"keylime_tenant\" CLI - 
will result in agent process dying", ML)
 
+    ima_log_file = None
+    if os.path.exists(config.IMA_ML):
+        ima_log_file = open(config.IMA_ML, 'r', encoding="utf-8")
+
+    tpm_log_file_data = None
+    if os.path.exists(config.MEASUREDBOOT_ML):
+        with open(config.MEASUREDBOOT_ML, 'rb') as tpm_log_file:
+            tpm_log_file_data = base64.b64encode(tpm_log_file.read())
+
     if config.get('cloud_agent', 'agent_uuid') == 'dmidecode':
         if os.getuid() != 0:
             raise RuntimeError('agent_uuid is configured to use dmidecode, '
@@ -627,6 +637,20 @@ def main():
             raise RuntimeError('agent_uuid is configured to use dmidecode, '
                                'but it\'s is not found on the system.')
 
+    # initialize the tmpfs partition to store keys if it isn't already 
available
+    secdir = secure_mount.mount()
+
+    # Now that operations requiring root privileges are done, drop privileges
+    # if 'run_as' is available in the configuration.
+    if os.getuid() == 0:
+        run_as = config.get('cloud_agent', 'run_as', fallback='')
+        if run_as != '':
+            user_utils.chown(secdir, run_as)
+            user_utils.change_uidgid(run_as)
+            logger.info(f"Dropped privileges to {run_as}")
+        else:
+            logger.warning("Cannot drop privileges since 'run_as' is empty or 
missing in keylime.conf agent section.")
+
     # Instanitate TPM class
 
     instance_tpm = tpm()
@@ -642,9 +666,6 @@ def main():
     if contact_port is None and config.has_option('cloud_agent', 
'agent_contact_port'):
         contact_port = config.get('cloud_agent', 'agent_contact_port', 
fallback="invalid")
 
-    # initialize the tmpfs partition to store keys if it isn't already 
available
-    secure_mount.mount()
-
     # change dir to working dir
     fs_util.ch_dir(config.WORK_DIR)
 
@@ -723,7 +744,7 @@ def main():
     if keylime_ca == "default":
         keylime_ca = os.path.join(config.WORK_DIR, 'cv_ca', 'cacert.crt')
 
-    server = CloudAgentHTTPServer(serveraddr, Handler, agent_uuid, contact_ip)
+    server = CloudAgentHTTPServer(serveraddr, Handler, agent_uuid, contact_ip, 
ima_log_file, tpm_log_file_data)
     context = web_util.generate_mtls_context(server.mtls_cert_path, 
server.rsakey_path, keylime_ca, logger=logger)
     server.socket = context.wrap_socket(server.socket, server_side=True)
     serverthread = threading.Thread(target=server.serve_forever, daemon=True)
Index: keylime-v6.3.1/keylime.conf
===================================================================
--- keylime-v6.3.1.orig/keylime.conf
+++ keylime-v6.3.1/keylime.conf
@@ -152,6 +152,25 @@ tpm_signing_alg = rsassa
 # create a new EK upon startup, and neither will it flush the EK upon exit.
 ek_handle = generate
 
+# The user account to switch to to drop privileges when started as root
+# If left empty, the agent will keep running with high privileges.
+# The user and group specified here must allow the user to access the
+# WORK_DIR (typically /var/lib/keylime) and /dev/tpmrm0. Therefore,
+# suggested value for the run_as parameter is keylime:tss.
+# The following commands should be used to set ownership before running the
+# agent:
+# chown keylime /var/lib/keylime
+#
+# If tpmdata.yml already exists:
+# chown keylime /var/lib/keylime/tpmdata.yml
+#
+# If cv_ca directory exists:
+# chown keylime /var/lib/keylime/cv_ca
+# chown keylime /var/lib/keylime/cv_ca/cacert.crt
+#
+# run_as =
+run_as = keylime:tss
+
 #=============================================================================
 [cloud_verifier]
 #=============================================================================
Index: keylime-v6.3.1/keylime/user_utils.py
===================================================================
--- /dev/null
+++ keylime-v6.3.1/keylime/user_utils.py
@@ -0,0 +1,100 @@
+#!/usr/bin/python3
+
+'''
+SPDX-License-Identifier: Apache-2.0
+Copyright 2022 IBM Corporation
+'''
+
+import os
+import grp
+import pwd
+
+from keylime import keylime_logging
+
+# Configure logger
+logger = keylime_logging.init_logging('privileges')
+
+
+def string_to_uidgid(user_and_group):
+    """ Translate the user_and_group string to uid and gid.
+        The userandgroup parameter must be a string of the format 
'<user>[:[<group>]]'
+        or '[<user>]:gid'
+        User and group can be strings or integers. If no group is given, -1 
will be
+        returned for gid.
+        :raises ValueError: if user or group could not be resolved
+    """
+    params = user_and_group.split(':')
+    if len(params) > 2:
+        raise ValueError(f"User and group {user_and_group} are in wrong 
format. Expected <user>[:[<group>]] or [<user>]:group")
+
+    gid = None
+    if len(params) == 2 and len(params[1]) > 0:
+        if params[1].isnumeric():
+            gid = int(params[1])
+            if gid < 0:
+                raise ValueError(f"User and group {user_and_group} contains an 
illegal value")
+        else:
+            try:
+                gr = grp.getgrnam(params[1])
+                gid = gr.gr_gid
+            except KeyError as e:
+                raise ValueError(f'Could not resolve group {params[1]}: {e}') 
from e
+
+    uid = None
+    if len(params[0]) > 0:
+        if params[0].isnumeric():
+            uid = int(params[0])
+            if uid < 0:
+                raise ValueError(f"User and group {user_and_group} contains an 
illegal value")
+        else:
+            try:
+                passwd = pwd.getpwnam(params[0])
+                uid = passwd.pw_uid
+            except KeyError as e:
+                raise ValueError(f'Could not resolve user {params[0]}: {e}') 
from e
+
+    if uid is None and gid is None:
+        raise ValueError(f"User and group {user_and_group} are in wrong 
format. Expected <user>[:[<group>]] or [<user>]:group")
+
+    return uid, gid
+
+
+def change_uidgid(user_and_group):
+    """ Change uid and gid of the current process.
+        The user_and_group parameter must be a string of the format
+        '<user>[:[<group>]]' or [<user>]:<group>. User and group can
+        be strings or integers.
+        :raises ValueError: if user or group could not be resolved
+        :raises RuntimeError: if setting gid or uid did not succeed
+    """
+    uid, gid = string_to_uidgid(user_and_group)
+
+    # First change group and then user
+    if gid is not None:
+        try:
+            os.setgid(gid)
+        except (OSError, PermissionError) as e:
+            raise RuntimeError(f'Could not set gid to {gid}: {e}') from e
+
+    if uid is not None:
+        try:
+            os.setuid(uid)
+        except (OSError, PermissionError) as e:
+            raise RuntimeError(f'Could not set uid to {uid}: {e}') from e
+
+
+def chown(path, user_and_group):
+    """ Change ownership on a given file to the new owner described in
+        user_and_group string.
+        The user_and_group parameter must be a string of the format
+        '<user>[:[<group>]]' or [<user>]:<group>. User and group can
+        be strings or integers.
+        :raises ValueError: if user or group could not be resolved
+    """
+    uid, gid = string_to_uidgid(user_and_group)
+    if uid is None:
+        uid = -1
+    if gid is None:
+        gid = -1
+
+    os.chown(path, uid, gid)
Index: keylime-v6.3.1/keylime/user_utils_test.py
===================================================================
--- /dev/null
+++ keylime-v6.3.1/keylime/user_utils_test.py
@@ -0,0 +1,52 @@
+'''
+SPDX-License-Identifier: Apache-2.0
+Copyright 2022 IBM Corporation
+'''
+
+import unittest
+
+from keylime import user_utils
+
+class TestUserUtils(unittest.TestCase):
+
+    def test_string_to_uidgid(self):
+        uid, gid = user_utils.string_to_uidgid('root')
+        self.assertTrue(isinstance(uid, int))
+        self.assertTrue(gid is None)
+
+        uid, gid = user_utils.string_to_uidgid('root:')
+        self.assertTrue(isinstance(uid, int))
+        self.assertTrue(gid is None)
+
+        uid, gid = user_utils.string_to_uidgid(':root')
+        self.assertTrue(uid is None)
+        self.assertTrue(isinstance(gid, int))
+
+        uid, gid = user_utils.string_to_uidgid('root:root')
+        self.assertTrue(isinstance(uid, int))
+        self.assertTrue(isinstance(gid, int))
+
+        with self.assertRaises(ValueError):
+            uid, gid = user_utils.string_to_uidgid(':')
+
+        uid, gid = user_utils.string_to_uidgid('100')
+        self.assertTrue(uid == 100)
+        self.assertTrue(gid is None)
+
+        uid, gid = user_utils.string_to_uidgid('100:')
+        self.assertTrue(uid == 100)
+        self.assertTrue(gid is None)
+
+        uid, gid = user_utils.string_to_uidgid(':200')
+        self.assertTrue(uid is None)
+        self.assertTrue(gid == 200)
+
+        uid, gid = user_utils.string_to_uidgid('100:200')
+        self.assertTrue(uid == 100)
+        self.assertTrue(gid == 200)
+
+        with self.assertRaises(ValueError):
+            uid, gid = user_utils.string_to_uidgid('-100:200')
+
+        with self.assertRaises(ValueError):
+            uid, gid = user_utils.string_to_uidgid('nobodyever')
Index: keylime-v6.3.1/keylime/secure_mount.py
===================================================================
--- keylime-v6.3.1.orig/keylime/secure_mount.py
+++ keylime-v6.3.1/keylime/secure_mount.py
@@ -4,6 +4,7 @@ Copyright 2017 Massachusetts Institute o
 '''
 
 import os
+import shutil
 
 from keylime import keylime_logging
 from keylime import cmd_exec
@@ -85,6 +86,12 @@ def mount():
 
 def umount():
     """Umount all the devices mounted by Keylime."""
+
+    # Make sure we leave tmpfs dir empty even if we did not mount it or
+    # if we cannot unmount it. Ignore errors while deleting. The deletion
+    # of the 'secure' directory will result in an error since it's a mount 
point.
+    shutil.rmtree(mount(), ignore_errors=True)
+
     while _MOUNTED:
         directory = _MOUNTED.pop()
         logger.info("Unmounting %s", directory)

++++++ keylime-user.conf ++++++
# Type Name ID GECOS [HOME]
u keylime - "Keylime agent" /var/lib/keylime

++++++ services_add_keylime_agent_secure_mount_service.patch ++++++
>From 8fb134b873a46280350c7e2fecece7ed3e6e1492 Mon Sep 17 00:00:00 2001
From: Alberto Planas <[email protected]>
Date: Mon, 28 Feb 2022 18:01:55 +0100
Subject: [PATCH] services: add keylime_agent_secure.mount service
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Add Keylime secure mount for agent from Debian.

Co-authored-by: Utkarsh Gupta <[email protected]>
Co-authored-by: Miriam Espa??a Acebal <[email protected]>
Signed-off-by: Alberto Planas <[email protected]>
---
 services/keylime_agent_secure.mount | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 services/keylime_agent_secure.mount

diff --git a/services/keylime_agent_secure.mount 
b/services/keylime_agent_secure.mount
new file mode 100644
index 00000000..606b9db1
--- /dev/null
+++ b/services/keylime_agent_secure.mount
@@ -0,0 +1,12 @@
+[Unit]
+Description=Keylime configuration filesystem
+Before=keylime_agent.service
+
+[Mount]
+What=tmpfs
+Where=/var/lib/keylime/secure
+Type=tmpfs
+Options=mode=0700,size=1m,uid=keylime,gid=tss
+
+[Install]
+WantedBy=multi-user.target

Reply via email to