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:
parent
506d721e42
commit
de2af4d74d
@ -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
|
Loading…
x
Reference in New Issue
Block a user