Add debian package for python-keyring
The upstream commit 1e422ed of python-keyring moved non-preferred keyring backends to separated package "keyrings.alt", so adding the keyrings.alt and porting the patches related to non-preferred keyring backends to keyrings.alt. Patches are not up to our standard. Bringing them up to standard is future work, tracked by: https://bugs.launchpad.net/starlingx/+bug/1950506. Related-Bug: 1950506 Building successfully. Installing python3-keyrings.alt, python3-keyring and the dependence package tsconfig successfully. Booting up ISO successfully on qemu. Story: 2009221 Task: 43438 Signed-off-by: Yue Tao <yue.tao@windriver.com> Change-Id: I4b70927709f0cc968e32af1d0e2a9402f47b2fe9
This commit is contained in:
		@@ -0,0 +1,15 @@
 | 
			
		||||
The source patch use_new_lock.patch import python module
 | 
			
		||||
oslo_concurrency, so add python3-oslo.concurrency to Depends.
 | 
			
		||||
 | 
			
		||||
Yue Tao <yue.tao@windriver.com>
 | 
			
		||||
 | 
			
		||||
--- a/debian/control
 | 
			
		||||
+++ b/debian/control
 | 
			
		||||
@@ -24,6 +24,7 @@ Package: python3-keyrings.alt
 | 
			
		||||
 Architecture: all
 | 
			
		||||
 Depends: python3-keyring,
 | 
			
		||||
          python3-pycryptodome,
 | 
			
		||||
+         python3-oslo.concurrency,
 | 
			
		||||
          ${misc:Depends},
 | 
			
		||||
          ${python3:Depends}
 | 
			
		||||
 Description: alternate backend implementations for python3-keyring
 | 
			
		||||
@@ -0,0 +1,14 @@
 | 
			
		||||
The source patch no_keyring_password.patch changes the 
 | 
			
		||||
behavior of Keyring password, that causes the selftest
 | 
			
		||||
failed, so disable the selftest
 | 
			
		||||
 | 
			
		||||
--- a/debian/rules
 | 
			
		||||
+++ b/debian/rules
 | 
			
		||||
@@ -4,6 +4,7 @@
 | 
			
		||||
 
 | 
			
		||||
 export PYBUILD_NAME=keyrings.alt
 | 
			
		||||
 export PYBUILD_TEST_ARGS=--ignore=keyrings/alt/_win_crypto.py
 | 
			
		||||
+export PYBUILD_DISABLE=test
 | 
			
		||||
 
 | 
			
		||||
 %:
 | 
			
		||||
 	dh $@ --with python3 --buildsystem pybuild
 | 
			
		||||
							
								
								
									
										2
									
								
								security/keyrings.alt/debian/deb_patches/series
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								security/keyrings.alt/debian/deb_patches/series
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
debian-depend-python3-oslo-concurrency.patch
 | 
			
		||||
debian-disable-selftest.patch
 | 
			
		||||
							
								
								
									
										8
									
								
								security/keyrings.alt/debian/meta_data.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								security/keyrings.alt/debian/meta_data.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
debver: 4.0.2-1
 | 
			
		||||
dl_path:
 | 
			
		||||
  name: keyrings.alt-debian-4.0.2-1.tar.gz
 | 
			
		||||
  url: https://salsa.debian.org/python-team/packages/keyrings.alt/-/archive/debian/4.0.2-1/keyrings.alt-debian-4.0.2-1.tar.gz
 | 
			
		||||
  md5sum: 05c9ca1f508d65e232d98a3f9535b88d
 | 
			
		||||
revision:
 | 
			
		||||
  dist: $STX_DIST
 | 
			
		||||
  PKG_GITREVCOUNT:
 | 
			
		||||
@@ -0,0 +1,41 @@
 | 
			
		||||
The upstream commit 1e422ed of keyring moves non-preferred keyring
 | 
			
		||||
backends to keyrings.alt package, so porting chmod_keyringlock2.patch
 | 
			
		||||
to package keyrings.alt
 | 
			
		||||
 | 
			
		||||
Index: keyring-5.3/keyrings/alt/file_base.py
 | 
			
		||||
===================================================================
 | 
			
		||||
--- keyring-5.3.orig/keyrings/alt/file_base.py
 | 
			
		||||
+++ keyring-5.3/keyrings/alt/file_base.py
 | 
			
		||||
@@ -97,6 +97,9 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
         service = escape_for_ini(service)
 | 
			
		||||
         username = escape_for_ini(username)
 | 
			
		||||
 
 | 
			
		||||
+        # ensure the file exists
 | 
			
		||||
+        self._ensure_file_path()
 | 
			
		||||
+
 | 
			
		||||
         # load the passwords from the file
 | 
			
		||||
         config = configparser.RawConfigParser()
 | 
			
		||||
         if os.path.exists(self.file_path):
 | 
			
		||||
@@ -191,12 +194,16 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
             user_read_write = 0o644
 | 
			
		||||
             os.chmod(self.file_path, user_read_write)
 | 
			
		||||
         if not os.path.isfile(lockdir + "/" + lockfile):
 | 
			
		||||
-             import stat
 | 
			
		||||
-             with open(lockdir + "/" + lockfile, 'w'):
 | 
			
		||||
-                 pass
 | 
			
		||||
-             # must have the lock file with the correct group permissisions g+rw
 | 
			
		||||
-             os.chmod(lockdir + "/" + lockfile, stat.S_IRWXG | stat.S_IRWXU)
 | 
			
		||||
-             os.chown(lockdir + "/" + lockfile,-1,345)
 | 
			
		||||
+            with open(lockdir + "/" + lockfile, 'w'):
 | 
			
		||||
+                pass
 | 
			
		||||
+        if os.path.isfile(lockdir + "/" + lockfile):
 | 
			
		||||
+            import stat
 | 
			
		||||
+            import grp
 | 
			
		||||
+            if oct(stat.S_IMODE(os.stat(lockdir + "/" + lockfile).st_mode)) != '0770':
 | 
			
		||||
+                # Must have the lock file with the correct group and permissisions g+rw
 | 
			
		||||
+                os.chmod(lockdir + "/" + lockfile, stat.S_IRWXG | stat.S_IRWXU)
 | 
			
		||||
+                groupinfo = grp.getgrnam('sys_protected')
 | 
			
		||||
+                os.chown(lockdir + "/" + lockfile,-1,groupinfo.gr_gid)
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
     def delete_password(self, service, username):
 | 
			
		||||
@@ -0,0 +1,16 @@
 | 
			
		||||
The upstream commit 1e422ed of keyring moves non-preferred keyring
 | 
			
		||||
backends to keyrings.alt package, so porting chown_keyringlock_file.patch
 | 
			
		||||
to package keyrings.alt
 | 
			
		||||
 | 
			
		||||
Index: keyring-5.3/keyrings/alt/file_base.py
 | 
			
		||||
===================================================================
 | 
			
		||||
--- keyring-5.3.orig/keyrings/alt/file_base.py
 | 
			
		||||
+++ keyring-5.3/keyrings/alt/file_base.py
 | 
			
		||||
@@ -196,6 +196,7 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
                  pass
 | 
			
		||||
              # must have the lock file with the correct group permissisions g+rw
 | 
			
		||||
              os.chmod(lockdir + "/" + lockfile, stat.S_IRWXG | stat.S_IRWXU)
 | 
			
		||||
+             os.chown(lockdir + "/" + lockfile,-1,345)
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
     def delete_password(self, service, username):
 | 
			
		||||
@@ -0,0 +1,112 @@
 | 
			
		||||
The upstream commit 1e422ed of keyring moves non-preferred keyring
 | 
			
		||||
backends to keyrings.alt package, so moving fix_keyring_lockfile_location.patch
 | 
			
		||||
to package keyrings.alt
 | 
			
		||||
 | 
			
		||||
--- a/keyrings/alt/file_base.py
 | 
			
		||||
+++ b/keyrings/alt/file_base.py
 | 
			
		||||
@@ -14,6 +14,7 @@ from keyring.util import platform_, prop
 | 
			
		||||
 from .escape import escape as escape_for_ini
 | 
			
		||||
 from oslo_concurrency import lockutils
 | 
			
		||||
 
 | 
			
		||||
+lockfile = "keyringlock"
 | 
			
		||||
 
 | 
			
		||||
 class FileBacked:
 | 
			
		||||
     @abc.abstractproperty
 | 
			
		||||
@@ -153,11 +154,12 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
         return (escape_for_ini(service) + r'\0' + escape_for_ini(username)).encode()
 | 
			
		||||
 
 | 
			
		||||
     def _write_config_value(self, service, key, value):
 | 
			
		||||
+        # ensure the file exists
 | 
			
		||||
+        self._ensure_file_path()
 | 
			
		||||
 
 | 
			
		||||
-        with lockutils.lock("keyringlock",external=True,lock_path="/tmp"):
 | 
			
		||||
+        lockdir = os.path.dirname(self.file_path)
 | 
			
		||||
 
 | 
			
		||||
-            # ensure the file exists
 | 
			
		||||
-            self._ensure_file_path()
 | 
			
		||||
+        with lockutils.lock(lockfile,external=True,lock_path=lockdir):
 | 
			
		||||
 
 | 
			
		||||
             config = None
 | 
			
		||||
             try:
 | 
			
		||||
@@ -206,14 +208,13 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
-
 | 
			
		||||
-
 | 
			
		||||
     def _ensure_file_path(self):
 | 
			
		||||
         """
 | 
			
		||||
         Ensure the storage path exists.
 | 
			
		||||
         If it doesn't, create it with "go-rwx" permissions.
 | 
			
		||||
         """
 | 
			
		||||
         storage_root = os.path.dirname(self.file_path)
 | 
			
		||||
+        lockdir = storage_root
 | 
			
		||||
         needs_storage_root = storage_root and not os.path.isdir(storage_root)
 | 
			
		||||
         if needs_storage_root:  # pragma: no cover
 | 
			
		||||
             os.makedirs(storage_root)
 | 
			
		||||
@@ -223,12 +224,21 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
                 pass
 | 
			
		||||
             user_read_write = 0o644
 | 
			
		||||
             os.chmod(self.file_path, user_read_write)
 | 
			
		||||
+        if not os.path.isfile(lockdir + "/" + lockfile):
 | 
			
		||||
+             import stat
 | 
			
		||||
+             with open(lockdir + "/" + lockfile, 'w'):
 | 
			
		||||
+                 pass
 | 
			
		||||
+             # must have the lock file with the correct group permissisions g+rw
 | 
			
		||||
+             os.chmod(lockdir + "/" + lockfile, stat.S_IRWXG | stat.S_IRWXU)
 | 
			
		||||
+
 | 
			
		||||
 
 | 
			
		||||
     def delete_password(self, service, username):
 | 
			
		||||
         """Delete the password for the username of the service."""
 | 
			
		||||
         service = escape_for_ini(service)
 | 
			
		||||
         username = escape_for_ini(username)
 | 
			
		||||
-        with lockutils.lock("keyringlock",external=True,lock_path="/tmp"):
 | 
			
		||||
+
 | 
			
		||||
+        lockdir = os.path.dirname(self.file_path)
 | 
			
		||||
+        with lockutils.lock(lockfile,external=True,lock_path=lockdir):
 | 
			
		||||
             config = configparser.RawConfigParser()
 | 
			
		||||
             if os.path.exists(self.file_path):
 | 
			
		||||
                 config.read(self.file_path)
 | 
			
		||||
Index: keyring-5.3/keyring/backends/file.py
 | 
			
		||||
===================================================================
 | 
			
		||||
--- keyring-5.3.orig/keyrings/alt/file.py
 | 
			
		||||
+++ keyring-5.3/keyrings/alt/file.py
 | 
			
		||||
@@ -108,18 +108,6 @@ class EncryptedKeyring(Encrypted, Keyrin
 | 
			
		||||
         # set a reference password, used to check that the password provided
 | 
			
		||||
         #  matches for subsequent checks.
 | 
			
		||||
 
 | 
			
		||||
-        # try to pre-create the /tmp/keyringlock if it doesn't exist
 | 
			
		||||
-        lockfile = "/tmp/keyringlock"
 | 
			
		||||
-        if os.geteuid() == 0 and (not os.path.exists(lockfile)):
 | 
			
		||||
-             from pwd import getpwnam
 | 
			
		||||
-             import stat
 | 
			
		||||
-             nonrootuser = "sysadmin"
 | 
			
		||||
-             with open(lockfile, 'w'):
 | 
			
		||||
-                 pass
 | 
			
		||||
-             # must have the lock file with the correct group permissisions g+rw
 | 
			
		||||
-             os.chmod(lockfile, stat.S_IRWXG | stat.S_IRWXU)
 | 
			
		||||
-
 | 
			
		||||
-
 | 
			
		||||
         self.set_password(
 | 
			
		||||
             'keyring-setting', 'password reference', 'password reference value'
 | 
			
		||||
         )
 | 
			
		||||
@@ -134,9 +122,10 @@ class EncryptedKeyring(Encrypted, Keyrin
 | 
			
		||||
             return False
 | 
			
		||||
         self._migrate()
 | 
			
		||||
 
 | 
			
		||||
+        lockdir = os.path.dirname(self.file_path)
 | 
			
		||||
         # lock access to the file_path here, make sure it's not being written
 | 
			
		||||
         # to while while we're checking for keyring-setting
 | 
			
		||||
-        with lockutils.lock("keyringlock",external=True,lock_path="/tmp"):
 | 
			
		||||
+        with lockutils.lock(lockfile,external=True,lock_path=lockdir):
 | 
			
		||||
             config = configparser.RawConfigParser()
 | 
			
		||||
             config.read(self.file_path)
 | 
			
		||||
             try:
 | 
			
		||||
@@ -145,7 +134,6 @@ class EncryptedKeyring(Encrypted, Keyrin
 | 
			
		||||
                 )
 | 
			
		||||
             except (configparser.NoSectionError, configparser.NoOptionError):
 | 
			
		||||
                 # The current file doesn't have the keyring-setting, check the backup
 | 
			
		||||
-                logging.warning("_check_file: The current file doesn't have the keyring-setting, check the backup")
 | 
			
		||||
                 if os.path.exists(self.backup_file_path):
 | 
			
		||||
                     config = configparser.RawConfigParser()
 | 
			
		||||
                     config.read(self.backup_file_path)
 | 
			
		||||
							
								
								
									
										51
									
								
								security/keyrings.alt/debian/patches/lock_keyring_file.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								security/keyrings.alt/debian/patches/lock_keyring_file.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
The upstream commit 1e422ed of keyring moves non-preferred keyring
 | 
			
		||||
backends to keyrings.alt package, so porting lock_keyring_file.patch
 | 
			
		||||
to package keyrings.alt
 | 
			
		||||
 | 
			
		||||
Index: keyring-5.3/keyrings/alt/file_base.py
 | 
			
		||||
===================================================================
 | 
			
		||||
--- keyring-5.3.orig/keyrings/alt/file_base.py
 | 
			
		||||
+++ keyring-5.3/keyrings/alt/file_base.py
 | 
			
		||||
@@ -2,6 +2,7 @@ from __future__ import with_statement
 | 
			
		||||
 
 | 
			
		||||
 import os
 | 
			
		||||
 import abc
 | 
			
		||||
+import time
 | 
			
		||||
 import configparser
 | 
			
		||||
 from base64 import encodebytes, decodebytes
 | 
			
		||||
 
 | 
			
		||||
@@ -138,6 +139,17 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
         config = configparser.RawConfigParser()
 | 
			
		||||
         config.read(self.file_path)
 | 
			
		||||
 
 | 
			
		||||
+        # obtain lock for the keyring file
 | 
			
		||||
+        lock = ''
 | 
			
		||||
+        i = 60
 | 
			
		||||
+        while i:
 | 
			
		||||
+            if not os.path.isfile('/tmp/.keyringlock'):
 | 
			
		||||
+                lock = open('/tmp/.keyringlock', 'w')
 | 
			
		||||
+                break
 | 
			
		||||
+            else:
 | 
			
		||||
+                time.sleep(0.500)
 | 
			
		||||
+                i=i-1
 | 
			
		||||
+
 | 
			
		||||
         service = escape_for_ini(service)
 | 
			
		||||
         key = escape_for_ini(key)
 | 
			
		||||
 
 | 
			
		||||
@@ -146,9 +158,13 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
             config.add_section(service)
 | 
			
		||||
         config.set(service, key, value)
 | 
			
		||||
 
 | 
			
		||||
-        # save the keyring back to the file
 | 
			
		||||
-        with open(self.file_path, 'w') as config_file:
 | 
			
		||||
-            config.write(config_file)
 | 
			
		||||
+        if i:
 | 
			
		||||
+            # save the keyring back to the file
 | 
			
		||||
+            with open(self.file_path, 'w') as config_file:
 | 
			
		||||
+                config.write(config_file)
 | 
			
		||||
+            lock.close()
 | 
			
		||||
+            os.remove('/tmp/.keyringlock')
 | 
			
		||||
+
 | 
			
		||||
 
 | 
			
		||||
     def _ensure_file_path(self):
 | 
			
		||||
         """
 | 
			
		||||
@@ -0,0 +1,52 @@
 | 
			
		||||
The upstream commit 1e422ed of keyring moves non-preferred keyring
 | 
			
		||||
backends to keyrings.alt package, so porting lock_keyring_file2.patch
 | 
			
		||||
to package keyrings.alt
 | 
			
		||||
 | 
			
		||||
Index: keyring-5.3/keyrings/alt/file_base.py
 | 
			
		||||
===================================================================
 | 
			
		||||
--- keyring-5.3.orig/keyrings/alt/file_base.py
 | 
			
		||||
+++ keyring-5.3/keyrings/alt/file_base.py
 | 
			
		||||
@@ -135,10 +135,6 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
         # ensure the file exists
 | 
			
		||||
         self._ensure_file_path()
 | 
			
		||||
 
 | 
			
		||||
-        # load the keyring from the disk
 | 
			
		||||
-        config = configparser.RawConfigParser()
 | 
			
		||||
-        config.read(self.file_path)
 | 
			
		||||
-
 | 
			
		||||
         # obtain lock for the keyring file
 | 
			
		||||
         lock = ''
 | 
			
		||||
         i = 60
 | 
			
		||||
@@ -150,18 +146,23 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
                 time.sleep(0.500)
 | 
			
		||||
                 i=i-1
 | 
			
		||||
 
 | 
			
		||||
-        service = escape_for_ini(service)
 | 
			
		||||
-        key = escape_for_ini(key)
 | 
			
		||||
-
 | 
			
		||||
-        # update the keyring with the password
 | 
			
		||||
-        if not config.has_section(service):
 | 
			
		||||
-            config.add_section(service)
 | 
			
		||||
-        config.set(service, key, value)
 | 
			
		||||
-
 | 
			
		||||
         if i:
 | 
			
		||||
-            # save the keyring back to the file
 | 
			
		||||
+            # Load the keyring from the disk
 | 
			
		||||
+            config = configparser.RawConfigParser()
 | 
			
		||||
+            config.read(self.file_path)
 | 
			
		||||
+
 | 
			
		||||
+            service = escape_for_ini(service)
 | 
			
		||||
+            key = escape_for_ini(key)
 | 
			
		||||
+
 | 
			
		||||
+            # Update the keyring with the password
 | 
			
		||||
+            if not config.has_section(service):
 | 
			
		||||
+                config.add_section(service)
 | 
			
		||||
+            config.set(service, key, value)
 | 
			
		||||
+
 | 
			
		||||
+            # Save the keyring back to the file
 | 
			
		||||
             with open(self.file_path, 'w') as config_file:
 | 
			
		||||
                 config.write(config_file)
 | 
			
		||||
+
 | 
			
		||||
             lock.close()
 | 
			
		||||
             os.remove('/tmp/.keyringlock')
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,64 @@
 | 
			
		||||
The upstream commit 1e422ed of keyring moves non-preferred keyring
 | 
			
		||||
backends to keyrings.alt package, so moving the codes related to keyring
 | 
			
		||||
backends of no_keyring_password.patch to package keyrings.alt
 | 
			
		||||
 | 
			
		||||
diff --git a/keyrings/alt/file_base.py b/keyrings/alt/file_base.py
 | 
			
		||||
--- a/keyrings/alt/file_base.py
 | 
			
		||||
+++ b/keyrings/alt/file_base.py
 | 
			
		||||
@@ -163,7 +163,7 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
             # create the file without group/world permissions
 | 
			
		||||
             with open(self.file_path, 'w'):
 | 
			
		||||
                 pass
 | 
			
		||||
-            user_read_write = 0o600
 | 
			
		||||
+            user_read_write = 0o644
 | 
			
		||||
             os.chmod(self.file_path, user_read_write)
 | 
			
		||||
 
 | 
			
		||||
     def delete_password(self, service, username):
 | 
			
		||||
diff --git a/keyrings/alt/file.py b/keyrings/alt/file.py
 | 
			
		||||
index f899880..ef6db1d 100644
 | 
			
		||||
--- a/keyrings/alt/file.py
 | 
			
		||||
+++ b/keyrings/alt/file.py
 | 
			
		||||
@@ -52,11 +52,18 @@ class Encrypted:
 | 
			
		||||
 
 | 
			
		||||
     def _get_new_password(self):
 | 
			
		||||
         while True:
 | 
			
		||||
-            password = getpass.getpass("Please set a password for your new keyring: ")
 | 
			
		||||
-            confirm = getpass.getpass('Please confirm the password: ')
 | 
			
		||||
-            if password != confirm:  # pragma: no cover
 | 
			
		||||
-                sys.stderr.write("Error: Your passwords didn't match\n")
 | 
			
		||||
-                continue
 | 
			
		||||
+#****************************************************************
 | 
			
		||||
+# Forging the Keyring password to allow automation and still keep
 | 
			
		||||
+# the password encoded. TODO to be revisited when Barbican keyring
 | 
			
		||||
+# Will be used with the complete PKI solution
 | 
			
		||||
+#****************************************************************
 | 
			
		||||
+#            password = getpass.getpass("Please set a password for your new keyring: ")
 | 
			
		||||
+#            confirm = getpass.getpass('Please confirm the password: ')
 | 
			
		||||
+#            if password != confirm:  # pragma: no cover
 | 
			
		||||
+#                sys.stderr.write("Error: Your passwords didn't match\n")
 | 
			
		||||
+#                continue
 | 
			
		||||
+            password =  "Please set a password for your new keyring: "
 | 
			
		||||
+
 | 
			
		||||
             if '' == password.strip():  # pragma: no cover
 | 
			
		||||
                 # forbid the blank password
 | 
			
		||||
                 sys.stderr.write("Error: blank passwords aren't allowed.\n")
 | 
			
		||||
@@ -172,9 +179,16 @@ class EncryptedKeyring(Encrypted, Keyrin
 | 
			
		||||
         Unlock this keyring by getting the password for the keyring from the
 | 
			
		||||
         user.
 | 
			
		||||
         """
 | 
			
		||||
-        self.keyring_key = getpass.getpass(
 | 
			
		||||
-            'Please enter password for encrypted keyring: '
 | 
			
		||||
-        )
 | 
			
		||||
+#****************************************************************
 | 
			
		||||
+# Forging the Keyring password to allow automation and still keep
 | 
			
		||||
+# the password encoded. TODO to be revisited when Barbican keyring
 | 
			
		||||
+# Will be used with the complete PKI solution
 | 
			
		||||
+#****************************************************************
 | 
			
		||||
+#        self.keyring_key = getpass.getpass(
 | 
			
		||||
+#            'Please enter password for encrypted keyring: '
 | 
			
		||||
+#        )
 | 
			
		||||
+        self.keyring_key = "Please set a password for your new keyring: "
 | 
			
		||||
+
 | 
			
		||||
         try:
 | 
			
		||||
             ref_pw = self.get_password('keyring-setting', 'password reference')
 | 
			
		||||
             assert ref_pw == 'password reference value'
 | 
			
		||||
							
								
								
									
										136
									
								
								security/keyrings.alt/debian/patches/remove-reader-lock.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								security/keyrings.alt/debian/patches/remove-reader-lock.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,136 @@
 | 
			
		||||
The upstream commit 1e422ed of keyring moves non-preferred keyring
 | 
			
		||||
backends to keyrings.alt package, so porting remove-reader-lock.patch
 | 
			
		||||
to package keyrings.alt
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 keyring/backends/file.py |   85 ++++++++++++++++++++++-------------------------
 | 
			
		||||
 1 file changed, 41 insertions(+), 44 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/keyrings/alt/file_base.py
 | 
			
		||||
+++ b/keyrings/alt/file_base.py
 | 
			
		||||
@@ -14,6 +14,7 @@ from keyring.backend import KeyringBacke
 | 
			
		||||
 from keyring.util import platform_, properties
 | 
			
		||||
 from .escape import escape as escape_for_ini
 | 
			
		||||
 from oslo_concurrency import lockutils
 | 
			
		||||
+from tempfile import mkstemp
 | 
			
		||||
 
 | 
			
		||||
 lockfile = "keyringlock"
 | 
			
		||||
 
 | 
			
		||||
@@ -144,9 +145,9 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
         # ensure the file exists
 | 
			
		||||
         self._ensure_file_path()
 | 
			
		||||
 
 | 
			
		||||
-        lockdir = os.path.dirname(self.file_path)
 | 
			
		||||
+        keyringdir = os.path.dirname(self.file_path)
 | 
			
		||||
 
 | 
			
		||||
-        with lockutils.lock(lockfile,external=True,lock_path=lockdir):
 | 
			
		||||
+        with lockutils.lock(lockfile, external=True, lock_path=keyringdir):
 | 
			
		||||
 
 | 
			
		||||
             config = None
 | 
			
		||||
             try:
 | 
			
		||||
@@ -165,15 +166,20 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
                 config.add_section(service)
 | 
			
		||||
             config.set(service, key, value)
 | 
			
		||||
 
 | 
			
		||||
-            # Save the keyring back to the file
 | 
			
		||||
-            storage_root = os.path.dirname(self.file_path)
 | 
			
		||||
-            tmpfile = "tmpfile.%s" % os.getpid()
 | 
			
		||||
-            with open(storage_root + "/" + tmpfile, 'w') as config_file:
 | 
			
		||||
-                config.write(config_file)
 | 
			
		||||
-            # copy will overwrite but move will not
 | 
			
		||||
-            shutil.copy(storage_root + "/" + tmpfile,self.file_path)
 | 
			
		||||
-            # wipe out tmpfile here
 | 
			
		||||
-            os.remove(storage_root + "/" + tmpfile)
 | 
			
		||||
+            # remove any residual temporary files here
 | 
			
		||||
+            try:
 | 
			
		||||
+                for tmpfile in glob.glob("%s/tmp*" % keyringdir):
 | 
			
		||||
+                    os.remove(tmpfile)
 | 
			
		||||
+            except:
 | 
			
		||||
+                logging.warning("_check_file: tmpfile removal failed")
 | 
			
		||||
+
 | 
			
		||||
+            # Write the keyring to a temp file, then move the new file
 | 
			
		||||
+            # to avoid overwriting the existing inode
 | 
			
		||||
+            (fd, fname) = mkstemp(dir=keyringdir)
 | 
			
		||||
+            with os.fdopen(fd, "w") as config_file:
 | 
			
		||||
+                 config.write(config_file)
 | 
			
		||||
+            os.chmod(fname, os.stat(self.file_path).st_mode)
 | 
			
		||||
+            shutil.move(fname, self.file_path)
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
@@ -211,8 +217,8 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
         service = escape_for_ini(service)
 | 
			
		||||
         username = escape_for_ini(username)
 | 
			
		||||
 
 | 
			
		||||
-        lockdir = os.path.dirname(self.file_path)
 | 
			
		||||
-        with lockutils.lock(lockfile,external=True,lock_path=lockdir):
 | 
			
		||||
+        keyringdir = os.path.dirname(self.file_path)
 | 
			
		||||
+        with lockutils.lock(lockfile, external=True, lock_path=keyringdir):
 | 
			
		||||
             config = configparser.RawConfigParser()
 | 
			
		||||
             if os.path.exists(self.file_path):
 | 
			
		||||
                 config.read(self.file_path)
 | 
			
		||||
@@ -221,13 +227,19 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
                     raise PasswordDeleteError("Password not found")
 | 
			
		||||
             except configparser.NoSectionError:
 | 
			
		||||
                 raise PasswordDeleteError("Password not found")
 | 
			
		||||
-            # update the file
 | 
			
		||||
-            storage_root = os.path.dirname(self.file_path)
 | 
			
		||||
-            tmpfile = "tmpfile.%s" % os.getpid()
 | 
			
		||||
-            with open(storage_root + "/" + tmpfile, 'w') as config_file:
 | 
			
		||||
+
 | 
			
		||||
+            # remove any residual temporary files here
 | 
			
		||||
+            try:
 | 
			
		||||
+                for tmpfile in glob.glob("%s/tmp*" % keyringdir):
 | 
			
		||||
+                    os.remove(tmpfile)
 | 
			
		||||
+            except:
 | 
			
		||||
+                logging.warning("_check_file: tmpfile removal failed")
 | 
			
		||||
+
 | 
			
		||||
+            # Write the keyring to a temp file, then move the new file
 | 
			
		||||
+            # to avoid overwriting the existing inode
 | 
			
		||||
+            (fd, fname) = mkstemp(dir=keyringdir)
 | 
			
		||||
+            with os.fdopen(fd, "w") as config_file:
 | 
			
		||||
                 config.write(config_file)
 | 
			
		||||
-            # copy will overwrite but move will not
 | 
			
		||||
-            shutil.copy(storage_root + "/" + tmpfile,self.file_path)
 | 
			
		||||
-            # wipe out tmpfile
 | 
			
		||||
-            os.remove(storage_root + "/" + tmpfile)
 | 
			
		||||
+            os.chmod(fname, os.stat(self.file_path).st_mode)
 | 
			
		||||
+            shutil.move(fname, self.file_path)
 | 
			
		||||
 
 | 
			
		||||
--- a/keyrings/alt/file.py
 | 
			
		||||
+++ b/keyrings/alt/file.py
 | 
			
		||||
@@ -120,26 +120,14 @@ class EncryptedKeyring(Encrypted, Keyrin
 | 
			
		||||
             return False
 | 
			
		||||
         self._migrate()
 | 
			
		||||
 
 | 
			
		||||
-        lockdir = os.path.dirname(self.file_path)
 | 
			
		||||
-        # lock access to the file_path here, make sure it's not being written
 | 
			
		||||
-        # to while while we're checking for keyring-setting
 | 
			
		||||
-        with lockutils.lock(lockfile,external=True,lock_path=lockdir):
 | 
			
		||||
-            config = configparser.RawConfigParser()
 | 
			
		||||
-            config.read(self.file_path)
 | 
			
		||||
-            try:
 | 
			
		||||
-                config.get(
 | 
			
		||||
-                    escape_for_ini('keyring-setting'), escape_for_ini('password reference'),
 | 
			
		||||
-                )
 | 
			
		||||
-            except (configparser.NoSectionError, configparser.NoOptionError):
 | 
			
		||||
-                return False
 | 
			
		||||
-
 | 
			
		||||
-            # remove any residual temporary files here
 | 
			
		||||
-            try:
 | 
			
		||||
-                for tmpfile in glob.glob(os.path.dirname(self.file_path) + "/" + "tmpfile.*"):
 | 
			
		||||
-                    os.remove(tmpfile)
 | 
			
		||||
-            except:
 | 
			
		||||
-                logging.warning("_check_file: tmpfile removal failed")
 | 
			
		||||
-
 | 
			
		||||
+        config = configparser.RawConfigParser()
 | 
			
		||||
+        config.read(self.file_path)
 | 
			
		||||
+        try:
 | 
			
		||||
+            config.get(
 | 
			
		||||
+                escape_for_ini('keyring-setting'), escape_for_ini('password reference'),
 | 
			
		||||
+            )
 | 
			
		||||
+        except (configparser.NoSectionError, configparser.NoOptionError):
 | 
			
		||||
+            return False
 | 
			
		||||
 
 | 
			
		||||
         try:
 | 
			
		||||
             self._check_scheme(config)
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
The upstream commit 1e422ed of keyring moves non-preferred keyring
 | 
			
		||||
backends to keyrings.alt package, so porting remove_others_perms_on_keyringcfg_file.patch
 | 
			
		||||
to package keyrings.alt
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 keyring/backends/file.py |    2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/keyrings/alt/file_base.py
 | 
			
		||||
+++ b/keyrings/alt/file_base.py
 | 
			
		||||
@@ -197,7 +197,7 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
             # create the file without group/world permissions
 | 
			
		||||
             with open(self.file_path, 'w'):
 | 
			
		||||
                 pass
 | 
			
		||||
-            user_read_write = 0o644
 | 
			
		||||
+            user_read_write = 0o640
 | 
			
		||||
             os.chmod(self.file_path, user_read_write)
 | 
			
		||||
         if not os.path.isfile(lockdir + "/" + lockfile):
 | 
			
		||||
             with open(lockdir + "/" + lockfile, 'w'):
 | 
			
		||||
							
								
								
									
										10
									
								
								security/keyrings.alt/debian/patches/series
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								security/keyrings.alt/debian/patches/series
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
no_keyring_password.patch
 | 
			
		||||
lock_keyring_file.patch
 | 
			
		||||
lock_keyring_file2.patch
 | 
			
		||||
use_new_lock.patch
 | 
			
		||||
fix_keyring_lockfile_location.patch
 | 
			
		||||
use_temporary_file.patch
 | 
			
		||||
chown_keyringlock_file.patch
 | 
			
		||||
chmod_keyringlock2.patch
 | 
			
		||||
remove-reader-lock.patch
 | 
			
		||||
remove_others_perms_on_keyringcfg_file.patch
 | 
			
		||||
							
								
								
									
										245
									
								
								security/keyrings.alt/debian/patches/use_new_lock.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										245
									
								
								security/keyrings.alt/debian/patches/use_new_lock.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,245 @@
 | 
			
		||||
The upstream commit 1e422ed of keyring moves non-preferred keyring
 | 
			
		||||
backends to keyrings.alt package, so moving the codes related to keyring
 | 
			
		||||
backends of use_new_lock.patch to package keyrings.alt
 | 
			
		||||
 | 
			
		||||
--- a/keyrings/alt/file_base.py
 | 
			
		||||
+++ b/keyrings/alt/file_base.py
 | 
			
		||||
@@ -3,6 +3,8 @@ from __future__ import with_statement
 | 
			
		||||
 import os
 | 
			
		||||
 import abc
 | 
			
		||||
 import time
 | 
			
		||||
+import logging
 | 
			
		||||
+import shutil
 | 
			
		||||
 import configparser
 | 
			
		||||
 from base64 import encodebytes, decodebytes
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +12,7 @@ from keyring.errors import PasswordDelet
 | 
			
		||||
 from keyring.backend import KeyringBackend
 | 
			
		||||
 from keyring.util import platform_, properties
 | 
			
		||||
 from .escape import escape as escape_for_ini
 | 
			
		||||
+from oslo_concurrency import lockutils
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
 class FileBacked:
 | 
			
		||||
@@ -27,6 +30,14 @@ class FileBacked:
 | 
			
		||||
         """
 | 
			
		||||
         return os.path.join(platform_.data_root(), self.filename)
 | 
			
		||||
 
 | 
			
		||||
+    @properties.NonDataProperty
 | 
			
		||||
+    def backup_file_path(self):
 | 
			
		||||
+        """
 | 
			
		||||
+        The path to the file where passwords are stored. This property
 | 
			
		||||
+        may be overridden by the subclass or at the instance level.
 | 
			
		||||
+        """
 | 
			
		||||
+        return os.path.join(platform_.data_root(), self.backup_filename)
 | 
			
		||||
+
 | 
			
		||||
     @abc.abstractproperty
 | 
			
		||||
     def scheme(self):
 | 
			
		||||
         """
 | 
			
		||||
@@ -112,6 +123,16 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
             password = None
 | 
			
		||||
         return password
 | 
			
		||||
 
 | 
			
		||||
+
 | 
			
		||||
+    def filecopy(self,src,dest):
 | 
			
		||||
+        """copy file src to dest with default buffer size
 | 
			
		||||
+        """
 | 
			
		||||
+        with open(src, 'r') as f1:
 | 
			
		||||
+            with open(dest, 'w') as f2:
 | 
			
		||||
+                shutil.copyfileobj(f1,f2)
 | 
			
		||||
+                f2.flush()
 | 
			
		||||
+
 | 
			
		||||
+
 | 
			
		||||
     def set_password(self, service, username, password):
 | 
			
		||||
         """Write the password in the file."""
 | 
			
		||||
         if not username:
 | 
			
		||||
@@ -132,24 +153,36 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
         return (escape_for_ini(service) + r'\0' + escape_for_ini(username)).encode()
 | 
			
		||||
 
 | 
			
		||||
     def _write_config_value(self, service, key, value):
 | 
			
		||||
-        # ensure the file exists
 | 
			
		||||
-        self._ensure_file_path()
 | 
			
		||||
 
 | 
			
		||||
-        # obtain lock for the keyring file
 | 
			
		||||
-        lock = ''
 | 
			
		||||
-        i = 60
 | 
			
		||||
-        while i:
 | 
			
		||||
-            if not os.path.isfile('/tmp/.keyringlock'):
 | 
			
		||||
-                lock = open('/tmp/.keyringlock', 'w')
 | 
			
		||||
-                break
 | 
			
		||||
-            else:
 | 
			
		||||
-                time.sleep(0.500)
 | 
			
		||||
-                i=i-1
 | 
			
		||||
+        with lockutils.lock("keyringlock",external=True,lock_path="/tmp"):
 | 
			
		||||
+
 | 
			
		||||
+            # ensure the file exists
 | 
			
		||||
+            self._ensure_file_path()
 | 
			
		||||
+
 | 
			
		||||
+            config = None
 | 
			
		||||
+            try:
 | 
			
		||||
+                # Load the keyring from the disk
 | 
			
		||||
+                config = configparser.RawConfigParser()
 | 
			
		||||
+                config.read(self.file_path)
 | 
			
		||||
+            except configparser.ParsingError as e:
 | 
			
		||||
+                logging.warning("set_password: keyring file corrupted, Reverting to Backup")
 | 
			
		||||
+                # Revert to the backup file (copy backup over current file)
 | 
			
		||||
+                try:
 | 
			
		||||
+                    src = self.backup_file_path
 | 
			
		||||
+                    dest = self.file_path
 | 
			
		||||
+                    self.filecopy(src,dest)
 | 
			
		||||
+                except shutil.Error as e:
 | 
			
		||||
+                    logging.warning("set_password: Revert from Backup failed. Error: %s" % e)
 | 
			
		||||
+                    raise
 | 
			
		||||
+                # Load the keyring from the disk, if this fails exception is raised
 | 
			
		||||
+                try:
 | 
			
		||||
+                    config = configparser.RawConfigParser()
 | 
			
		||||
+                    config.read(self.file_path)
 | 
			
		||||
+                except:
 | 
			
		||||
+                    e = sys.exc_info()[0]
 | 
			
		||||
+                    logging.warning("set_password: Both keyring files are non useable. Error: %s" % e)
 | 
			
		||||
+                    raise
 | 
			
		||||
 
 | 
			
		||||
-        if i:
 | 
			
		||||
-            # Load the keyring from the disk
 | 
			
		||||
-            config = configparser.RawConfigParser()
 | 
			
		||||
-            config.read(self.file_path)
 | 
			
		||||
 
 | 
			
		||||
             service = escape_for_ini(service)
 | 
			
		||||
             key = escape_for_ini(key)
 | 
			
		||||
@@ -159,12 +192,20 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
                 config.add_section(service)
 | 
			
		||||
             config.set(service, key, value)
 | 
			
		||||
 
 | 
			
		||||
+            # Make a back up of the keyring file here
 | 
			
		||||
+            try:
 | 
			
		||||
+                src = self.file_path
 | 
			
		||||
+                dest = self.backup_file_path
 | 
			
		||||
+                self.filecopy(src,dest)
 | 
			
		||||
+            except shutil.Error as e:
 | 
			
		||||
+                logging.warning("set_password: Backup failed. Error: %s" % e)
 | 
			
		||||
+
 | 
			
		||||
             # Save the keyring back to the file
 | 
			
		||||
             with open(self.file_path, 'w') as config_file:
 | 
			
		||||
                 config.write(config_file)
 | 
			
		||||
 
 | 
			
		||||
-            lock.close()
 | 
			
		||||
-            os.remove('/tmp/.keyringlock')
 | 
			
		||||
+
 | 
			
		||||
+
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
     def _ensure_file_path(self):
 | 
			
		||||
@@ -187,14 +228,15 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
         """Delete the password for the username of the service."""
 | 
			
		||||
         service = escape_for_ini(service)
 | 
			
		||||
         username = escape_for_ini(username)
 | 
			
		||||
-        config = configparser.RawConfigParser()
 | 
			
		||||
-        if os.path.exists(self.file_path):
 | 
			
		||||
-            config.read(self.file_path)
 | 
			
		||||
-        try:
 | 
			
		||||
-            if not config.remove_option(service, username):
 | 
			
		||||
+        with lockutils.lock("keyringlock",external=True,lock_path="/tmp"):
 | 
			
		||||
+            config = configparser.RawConfigParser()
 | 
			
		||||
+            if os.path.exists(self.file_path):
 | 
			
		||||
+                config.read(self.file_path)
 | 
			
		||||
+            try:
 | 
			
		||||
+                if not config.remove_option(service, username):
 | 
			
		||||
+                    raise PasswordDeleteError("Password not found")
 | 
			
		||||
+            except configparser.NoSectionError:
 | 
			
		||||
                 raise PasswordDeleteError("Password not found")
 | 
			
		||||
-        except configparser.NoSectionError:
 | 
			
		||||
-            raise PasswordDeleteError("Password not found")
 | 
			
		||||
-        # update the file
 | 
			
		||||
-        with open(self.file_path, 'w') as config_file:
 | 
			
		||||
-            config.write(config_file)
 | 
			
		||||
+            # update the file
 | 
			
		||||
+            with open(self.file_path, 'w') as config_file:
 | 
			
		||||
+                config.write(config_file)
 | 
			
		||||
Index: keyring-5.3/keyrings/alt/file.py
 | 
			
		||||
===================================================================
 | 
			
		||||
--- keyring-5.3.orig/keyrings/alt/file.py
 | 
			
		||||
+++ keyring-5.3/keyrings/alt/file.py
 | 
			
		||||
@@ -19,6 +19,7 @@ class PlaintextKeyring(Keyring):
 | 
			
		||||
     "Applicable for all platforms, but not recommended"
 | 
			
		||||
 
 | 
			
		||||
     filename = 'keyring_pass.cfg'
 | 
			
		||||
+    backup_filename = 'crypted_pass_backup.cfg'
 | 
			
		||||
     scheme = 'no encyption'
 | 
			
		||||
     version = '1.0'
 | 
			
		||||
 
 | 
			
		||||
@@ -73,6 +74,7 @@ class EncryptedKeyring(Encrypted, Keyrin
 | 
			
		||||
     """PyCryptodome File Keyring"""
 | 
			
		||||
 
 | 
			
		||||
     filename = 'crypted_pass.cfg'
 | 
			
		||||
+    backup_filename = 'crypted_pass_backup.cfg'
 | 
			
		||||
     pw_prefix = 'pw:'.encode()
 | 
			
		||||
 
 | 
			
		||||
     @properties.ClassProperty
 | 
			
		||||
@@ -105,6 +107,19 @@ class EncryptedKeyring(Encrypted, Keyrin
 | 
			
		||||
         self.keyring_key = self._get_new_password()
 | 
			
		||||
         # set a reference password, used to check that the password provided
 | 
			
		||||
         #  matches for subsequent checks.
 | 
			
		||||
+
 | 
			
		||||
+        # try to pre-create the /tmp/keyringlock if it doesn't exist
 | 
			
		||||
+        lockfile = "/tmp/keyringlock"
 | 
			
		||||
+        if os.geteuid() == 0 and (not os.path.exists(lockfile)):
 | 
			
		||||
+             from pwd import getpwnam
 | 
			
		||||
+             import stat
 | 
			
		||||
+             nonrootuser = "sysadmin"
 | 
			
		||||
+             with open(lockfile, 'w'):
 | 
			
		||||
+                 pass
 | 
			
		||||
+             # must have the lock file with the correct group permissisions g+rw
 | 
			
		||||
+             os.chmod(lockfile, stat.S_IRWXG | stat.S_IRWXU)
 | 
			
		||||
+
 | 
			
		||||
+
 | 
			
		||||
         self.set_password(
 | 
			
		||||
             'keyring-setting', 'password reference', 'password reference value'
 | 
			
		||||
         )
 | 
			
		||||
@@ -118,14 +133,39 @@ class EncryptedKeyring(Encrypted, Keyrin
 | 
			
		||||
         if not os.path.exists(self.file_path):
 | 
			
		||||
             return False
 | 
			
		||||
         self._migrate()
 | 
			
		||||
-        config = configparser.RawConfigParser()
 | 
			
		||||
-        config.read(self.file_path)
 | 
			
		||||
-        try:
 | 
			
		||||
-            config.get(
 | 
			
		||||
-                escape_for_ini('keyring-setting'), escape_for_ini('password reference')
 | 
			
		||||
-            )
 | 
			
		||||
-        except (configparser.NoSectionError, configparser.NoOptionError):
 | 
			
		||||
-            return False
 | 
			
		||||
+
 | 
			
		||||
+        # lock access to the file_path here, make sure it's not being written
 | 
			
		||||
+        # to while while we're checking for keyring-setting
 | 
			
		||||
+        with lockutils.lock("keyringlock",external=True,lock_path="/tmp"):
 | 
			
		||||
+            config = configparser.RawConfigParser()
 | 
			
		||||
+            config.read(self.file_path)
 | 
			
		||||
+            try:
 | 
			
		||||
+                config.get(
 | 
			
		||||
+                    escape_for_ini('keyring-setting'), escape_for_ini('password reference'),
 | 
			
		||||
+                )
 | 
			
		||||
+            except (configparser.NoSectionError, configparser.NoOptionError):
 | 
			
		||||
+                # The current file doesn't have the keyring-setting, check the backup
 | 
			
		||||
+                logging.warning("_check_file: The current file doesn't have the keyring-setting, check the backup")
 | 
			
		||||
+                if os.path.exists(self.backup_file_path):
 | 
			
		||||
+                    config = configparser.RawConfigParser()
 | 
			
		||||
+                    config.read(self.backup_file_path)
 | 
			
		||||
+                    try:
 | 
			
		||||
+                        config.get(
 | 
			
		||||
+                            escape_for_ini('keyring-setting'), escape_for_ini('password reference')
 | 
			
		||||
+                        )
 | 
			
		||||
+                    except (configparser.NoSectionError, configparser.NoOptionError):
 | 
			
		||||
+                        return False
 | 
			
		||||
+                    # backup file has it, let's use it
 | 
			
		||||
+                    try:
 | 
			
		||||
+                        src = self.backup_file_path
 | 
			
		||||
+                        dest = self.file_path
 | 
			
		||||
+                        shutil.copy(src,dest)
 | 
			
		||||
+                    except shutil.Error as e:
 | 
			
		||||
+                        logging.warning("Revert from Backup failed. Error: %s" % e)
 | 
			
		||||
+                        return False
 | 
			
		||||
+                else:
 | 
			
		||||
+                    return False
 | 
			
		||||
+
 | 
			
		||||
         try:
 | 
			
		||||
             self._check_scheme(config)
 | 
			
		||||
         except AttributeError:
 | 
			
		||||
							
								
								
									
										165
									
								
								security/keyrings.alt/debian/patches/use_temporary_file.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								security/keyrings.alt/debian/patches/use_temporary_file.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,165 @@
 | 
			
		||||
The upstream commit 1e422ed of keyring moves non-preferred keyring
 | 
			
		||||
backends to keyrings.alt package, so moving the codes related to keyring
 | 
			
		||||
backends of use_temporary_file.patch to package keyrings.alt
 | 
			
		||||
 | 
			
		||||
--- a/keyrings/alt/file_base.py
 | 
			
		||||
+++ b/keyrings/alt/file_base.py
 | 
			
		||||
@@ -5,6 +5,7 @@ import abc
 | 
			
		||||
 import time
 | 
			
		||||
 import logging
 | 
			
		||||
 import shutil
 | 
			
		||||
+import glob
 | 
			
		||||
 import configparser
 | 
			
		||||
 from base64 import encodebytes, decodebytes
 | 
			
		||||
 
 | 
			
		||||
@@ -31,14 +32,6 @@ class FileBacked:
 | 
			
		||||
         """
 | 
			
		||||
         return os.path.join(platform_.data_root(), self.filename)
 | 
			
		||||
 
 | 
			
		||||
-    @properties.NonDataProperty
 | 
			
		||||
-    def backup_file_path(self):
 | 
			
		||||
-        """
 | 
			
		||||
-        The path to the file where passwords are stored. This property
 | 
			
		||||
-        may be overridden by the subclass or at the instance level.
 | 
			
		||||
-        """
 | 
			
		||||
-        return os.path.join(platform_.data_root(), self.backup_filename)
 | 
			
		||||
-
 | 
			
		||||
     @abc.abstractproperty
 | 
			
		||||
     def scheme(self):
 | 
			
		||||
         """
 | 
			
		||||
@@ -125,15 +118,6 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
         return password
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
-    def filecopy(self,src,dest):
 | 
			
		||||
-        """copy file src to dest with default buffer size
 | 
			
		||||
-        """
 | 
			
		||||
-        with open(src, 'r') as f1:
 | 
			
		||||
-            with open(dest, 'w') as f2:
 | 
			
		||||
-                shutil.copyfileobj(f1,f2)
 | 
			
		||||
-                f2.flush()
 | 
			
		||||
-
 | 
			
		||||
-
 | 
			
		||||
     def set_password(self, service, username, password):
 | 
			
		||||
         """Write the password in the file."""
 | 
			
		||||
         if not username:
 | 
			
		||||
@@ -167,23 +151,7 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
                 config = configparser.RawConfigParser()
 | 
			
		||||
                 config.read(self.file_path)
 | 
			
		||||
             except configparser.ParsingError as e:
 | 
			
		||||
-                logging.warning("set_password: keyring file corrupted, Reverting to Backup")
 | 
			
		||||
-                # Revert to the backup file (copy backup over current file)
 | 
			
		||||
-                try:
 | 
			
		||||
-                    src = self.backup_file_path
 | 
			
		||||
-                    dest = self.file_path
 | 
			
		||||
-                    self.filecopy(src,dest)
 | 
			
		||||
-                except shutil.Error as e:
 | 
			
		||||
-                    logging.warning("set_password: Revert from Backup failed. Error: %s" % e)
 | 
			
		||||
-                    raise
 | 
			
		||||
-                # Load the keyring from the disk, if this fails exception is raised
 | 
			
		||||
-                try:
 | 
			
		||||
-                    config = configparser.RawConfigParser()
 | 
			
		||||
-                    config.read(self.file_path)
 | 
			
		||||
-                except:
 | 
			
		||||
-                    e = sys.exc_info()[0]
 | 
			
		||||
-                    logging.warning("set_password: Both keyring files are non useable. Error: %s" % e)
 | 
			
		||||
-                    raise
 | 
			
		||||
+                logging.warning("set_password: keyring file corrupted")
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
             service = escape_for_ini(service)
 | 
			
		||||
@@ -194,17 +162,15 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
                 config.add_section(service)
 | 
			
		||||
             config.set(service, key, value)
 | 
			
		||||
 
 | 
			
		||||
-            # Make a back up of the keyring file here
 | 
			
		||||
-            try:
 | 
			
		||||
-                src = self.file_path
 | 
			
		||||
-                dest = self.backup_file_path
 | 
			
		||||
-                self.filecopy(src,dest)
 | 
			
		||||
-            except shutil.Error as e:
 | 
			
		||||
-                logging.warning("set_password: Backup failed. Error: %s" % e)
 | 
			
		||||
-
 | 
			
		||||
             # Save the keyring back to the file
 | 
			
		||||
-            with open(self.file_path, 'w') as config_file:
 | 
			
		||||
+            storage_root = os.path.dirname(self.file_path)
 | 
			
		||||
+            tmpfile = "tmpfile.%s" % os.getpid()
 | 
			
		||||
+            with open(storage_root + "/" + tmpfile, 'w') as config_file:
 | 
			
		||||
                 config.write(config_file)
 | 
			
		||||
+            # copy will overwrite but move will not
 | 
			
		||||
+            shutil.copy(storage_root + "/" + tmpfile,self.file_path)
 | 
			
		||||
+            # wipe out tmpfile here
 | 
			
		||||
+            os.remove(storage_root + "/" + tmpfile)
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
@@ -248,5 +214,12 @@ class Keyring(FileBacked, KeyringBackend
 | 
			
		||||
             except configparser.NoSectionError:
 | 
			
		||||
                 raise PasswordDeleteError("Password not found")
 | 
			
		||||
             # update the file
 | 
			
		||||
-            with open(self.file_path, 'w') as config_file:
 | 
			
		||||
+            storage_root = os.path.dirname(self.file_path)
 | 
			
		||||
+            tmpfile = "tmpfile.%s" % os.getpid()
 | 
			
		||||
+            with open(storage_root + "/" + tmpfile, 'w') as config_file:
 | 
			
		||||
                 config.write(config_file)
 | 
			
		||||
+            # copy will overwrite but move will not
 | 
			
		||||
+            shutil.copy(storage_root + "/" + tmpfile,self.file_path)
 | 
			
		||||
+            # wipe out tmpfile
 | 
			
		||||
+            os.remove(storage_root + "/" + tmpfile)
 | 
			
		||||
+
 | 
			
		||||
Index: keyring-5.3/keyrings/alt/file.py
 | 
			
		||||
===================================================================
 | 
			
		||||
--- keyring-5.3.orig/keyrings/alt/file.py
 | 
			
		||||
+++ keyring-5.3/keyrings/alt/file.py
 | 
			
		||||
@@ -19,7 +19,6 @@ class PlaintextKeyring(Keyring):
 | 
			
		||||
     "Applicable for all platforms, but not recommended"
 | 
			
		||||
 
 | 
			
		||||
     filename = 'keyring_pass.cfg'
 | 
			
		||||
-    backup_filename = 'crypted_pass_backup.cfg'
 | 
			
		||||
     scheme = 'no encyption'
 | 
			
		||||
     version = '1.0'
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +73,6 @@ class EncryptedKeyring(Encrypted, Keyrin
 | 
			
		||||
     """PyCryptodome File Keyring"""
 | 
			
		||||
 
 | 
			
		||||
     filename = 'crypted_pass.cfg'
 | 
			
		||||
-    backup_filename = 'crypted_pass_backup.cfg'
 | 
			
		||||
     pw_prefix = 'pw:'.encode()
 | 
			
		||||
 
 | 
			
		||||
     @properties.ClassProperty
 | 
			
		||||
@@ -133,26 +131,15 @@ class EncryptedKeyring(Encrypted, Keyrin
 | 
			
		||||
                     escape_for_ini('keyring-setting'), escape_for_ini('password reference'),
 | 
			
		||||
                 )
 | 
			
		||||
             except (configparser.NoSectionError, configparser.NoOptionError):
 | 
			
		||||
-                # The current file doesn't have the keyring-setting, check the backup
 | 
			
		||||
-                if os.path.exists(self.backup_file_path):
 | 
			
		||||
-                    config = configparser.RawConfigParser()
 | 
			
		||||
-                    config.read(self.backup_file_path)
 | 
			
		||||
-                    try:
 | 
			
		||||
-                        config.get(
 | 
			
		||||
-                            escape_for_ini('keyring-setting'), escape_for_ini('password reference')
 | 
			
		||||
-                        )
 | 
			
		||||
-                    except (configparser.NoSectionError, configparser.NoOptionError):
 | 
			
		||||
-                        return False
 | 
			
		||||
-                    # backup file has it, let's use it
 | 
			
		||||
-                    try:
 | 
			
		||||
-                        src = self.backup_file_path
 | 
			
		||||
-                        dest = self.file_path
 | 
			
		||||
-                        shutil.copy(src,dest)
 | 
			
		||||
-                    except shutil.Error as e:
 | 
			
		||||
-                        logging.warning("Revert from Backup failed. Error: %s" % e)
 | 
			
		||||
-                        return False
 | 
			
		||||
-                else:
 | 
			
		||||
-                    return False
 | 
			
		||||
+                return False
 | 
			
		||||
+
 | 
			
		||||
+            # remove any residual temporary files here
 | 
			
		||||
+            try:
 | 
			
		||||
+                for tmpfile in glob.glob(os.path.dirname(self.file_path) + "/" + "tmpfile.*"):
 | 
			
		||||
+                    os.remove(tmpfile)
 | 
			
		||||
+            except:
 | 
			
		||||
+                logging.warning("_check_file: tmpfile removal failed")
 | 
			
		||||
+
 | 
			
		||||
 
 | 
			
		||||
         try:
 | 
			
		||||
             self._check_scheme(config)
 | 
			
		||||
@@ -0,0 +1,13 @@
 | 
			
		||||
The source patch keyring_path_change.patch import
 | 
			
		||||
tsconfig, so add tsconfig to Depends
 | 
			
		||||
 | 
			
		||||
--- a/debian/control
 | 
			
		||||
+++ b/debian/control
 | 
			
		||||
@@ -20,6 +20,7 @@ Package: python3-keyring
 | 
			
		||||
 Architecture: all
 | 
			
		||||
 Depends: python3-jeepney (>= 0.4.2),
 | 
			
		||||
          python3-secretstorage (>= 3.2),
 | 
			
		||||
+         tsconfig
 | 
			
		||||
          ${misc:Depends},
 | 
			
		||||
          ${python3:Depends}
 | 
			
		||||
 Suggests: gnome-keyring, libkf5wallet-bin, python3-dbus, python3-keyrings.alt
 | 
			
		||||
							
								
								
									
										1
									
								
								security/python-keyring/debian/deb_patches/series
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								security/python-keyring/debian/deb_patches/series
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
debian-depend-tsconfig.patch
 | 
			
		||||
							
								
								
									
										8
									
								
								security/python-keyring/debian/meta_data.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								security/python-keyring/debian/meta_data.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
debver: 22.0.1-1
 | 
			
		||||
dl_pah:
 | 
			
		||||
  name: python-keyring-debian-22.2.0-1.tar.gz
 | 
			
		||||
  url: https://salsa.debian.org/python-team/packages/python-keyring/-/archive/debian/22.2.0-1/python-keyring-debian-22.2.0-1.tar.gz
 | 
			
		||||
  md5sum: b75d88573226d73cc9dbefa0128bb042
 | 
			
		||||
revision:
 | 
			
		||||
  dist: $STX_DIST
 | 
			
		||||
  PKG_GITREVCOUNT:
 | 
			
		||||
@@ -0,0 +1,23 @@
 | 
			
		||||
---
 | 
			
		||||
 keyring/util/platform_.py |    4 +++-
 | 
			
		||||
 1 file changed, 3 insertions(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/keyring/util/platform_.py
 | 
			
		||||
+++ b/keyring/util/platform_.py
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
 import os
 | 
			
		||||
 import platform
 | 
			
		||||
+from tsconfig.tsconfig import SW_VERSION
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
 def _settings_root_XP():
 | 
			
		||||
@@ -21,7 +22,8 @@ def _data_root_Linux():
 | 
			
		||||
     Use freedesktop.org Base Dir Specfication to determine storage
 | 
			
		||||
     location.
 | 
			
		||||
     """
 | 
			
		||||
-    fallback = os.path.expanduser('/opt/platform/.keyring/')
 | 
			
		||||
+    keyring_dir = os.path.join('/opt/platform/.keyring', SW_VERSION)
 | 
			
		||||
+    fallback = os.path.expanduser(keyring_dir)
 | 
			
		||||
     root = os.environ.get('XDG_DATA_HOME', None) or fallback
 | 
			
		||||
     return os.path.join(root, 'python_keyring')
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,13 @@
 | 
			
		||||
diff --git a/keyring/util/platform_.py b/keyring/util/platform_.py
 | 
			
		||||
index dcdffea..53b9eae 100644
 | 
			
		||||
--- a/keyring/util/platform_.py
 | 
			
		||||
+++ b/keyring/util/platform_.py
 | 
			
		||||
@@ -21,7 +21,7 @@ def _data_root_Linux():
 | 
			
		||||
     Use freedesktop.org Base Dir Specfication to determine storage
 | 
			
		||||
     location.
 | 
			
		||||
     """
 | 
			
		||||
-    fallback = os.path.expanduser('~/.local/share')
 | 
			
		||||
+    fallback = os.path.expanduser('/opt/platform/.keyring/')
 | 
			
		||||
     root = os.environ.get('XDG_DATA_HOME', None) or fallback
 | 
			
		||||
     return os.path.join(root, 'python_keyring')
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								security/python-keyring/debian/patches/series
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								security/python-keyring/debian/patches/series
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
no_keyring_password.patch
 | 
			
		||||
keyring_path_change.patch
 | 
			
		||||
		Reference in New Issue
	
	Block a user