--- /dev/null
+Index: keyring-5.3/keyring/backends/file.py
+===================================================================
+--- keyring-5.3.orig/keyring/backends/file.py
++++ keyring-5.3/keyring/backends/file.py
+@@ -9,6 +9,7 @@ import abc
+ import time
+ import logging
+ import shutil
++import glob
+
+ from ..py27compat import configparser
+
+@@ -36,13 +37,6 @@ class FileBacked(object):
+ """
+ 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)
+
+ class BaseKeyring(FileBacked, KeyringBackend):
+ """
+@@ -91,15 +85,6 @@ class BaseKeyring(FileBacked, KeyringBac
+ 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.
+ """
+@@ -125,23 +110,7 @@ class BaseKeyring(FileBacked, KeyringBac
+ 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")
+
+
+ # Update the keyring with the password
+@@ -149,17 +118,15 @@ class BaseKeyring(FileBacked, KeyringBac
+ config.add_section(service)
+ config.set(service, username, password_base64)
+
+- # 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)
+
+
+
+@@ -203,8 +170,15 @@ class BaseKeyring(FileBacked, KeyringBac
+ 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)
++
+
+ class PlaintextKeyring(BaseKeyring):
+ """Simple File Keyring with no encryption"""
+@@ -213,7 +187,6 @@ class PlaintextKeyring(BaseKeyring):
+ "Applicable for all platforms, but not recommended"
+
+ filename = 'keyring_pass.cfg'
+- backup_filename = 'crypted_pass_backup.cfg'
+
+ def encrypt(self, password):
+ """Directly return the password itself.
+@@ -267,7 +240,6 @@ class EncryptedKeyring(Encrypted, BaseKe
+ """PyCrypto File Keyring"""
+
+ filename = 'crypted_pass.cfg'
+- backup_filename = 'crypted_pass_backup.cfg'
+ pw_prefix = 'pw:'.encode()
+
+ @properties.ClassProperty
+@@ -326,27 +298,15 @@ class EncryptedKeyring(Encrypted, BaseKe
+ 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")
++
+
+ return True
+