+++ /dev/null
----
- keyring/backends/file.py | 85 ++++++++++++++++++++++-------------------------
- 1 file changed, 41 insertions(+), 44 deletions(-)
-
---- a/keyring/backends/file.py
-+++ b/keyring/backends/file.py
-@@ -18,6 +18,7 @@ from ..backend import KeyringBackend
- from ..util import platform_, properties
- from ..util.escape import escape as escape_for_ini
- from oslo_concurrency import lockutils
-+from tempfile import mkstemp
-
-
- lockfile = "keyringlock"
-@@ -102,11 +103,9 @@ class BaseKeyring(FileBacked, KeyringBac
- # encode with base64
- password_base64 = base64.encodestring(password_encrypted).decode()
-
-- 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 = None
- try:
- # Load the keyring from the disk
-@@ -121,16 +120,20 @@ class BaseKeyring(FileBacked, KeyringBac
- config.add_section(service)
- config.set(service, username, password_base64)
-
-- # 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)
-
-
- def _ensure_file_path(self):
-@@ -167,8 +170,8 @@ class BaseKeyring(FileBacked, KeyringBac
- 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)
-@@ -177,15 +180,21 @@ class BaseKeyring(FileBacked, KeyringBac
- 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)
-
-
- class PlaintextKeyring(BaseKeyring):
-@@ -294,27 +303,15 @@ class EncryptedKeyring(Encrypted, BaseKe
- 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
-
- return True
-