1 Index: keyring-5.3/keyring/backends/file.py
2 ===================================================================
3 --- keyring-5.3.orig/keyring/backends/file.py
4 +++ keyring-5.3/keyring/backends/file.py
5 @@ -9,6 +9,7 @@ import abc
11 from ..py27compat import configparser
13 @@ -36,13 +37,6 @@ class FileBacked(object):
15 return os.path.join(platform_.data_root(), self.filename)
17 - @properties.NonDataProperty
18 - def backup_file_path(self):
20 - The path to the file where passwords are stored. This property
21 - may be overridden by the subclass or at the instance level.
23 - return os.path.join(platform_.data_root(), self.backup_filename)
25 class BaseKeyring(FileBacked, KeyringBackend):
27 @@ -91,15 +85,6 @@ class BaseKeyring(FileBacked, KeyringBac
31 - def filecopy(self,src,dest):
32 - """copy file src to dest with default buffer size
34 - with open(src, 'r') as f1:
35 - with open(dest, 'w') as f2:
36 - shutil.copyfileobj(f1,f2)
40 def set_password(self, service, username, password):
41 """Write the password in the file.
43 @@ -125,23 +110,7 @@ class BaseKeyring(FileBacked, KeyringBac
44 config = configparser.RawConfigParser()
45 config.read(self.file_path)
46 except configparser.ParsingError as e:
47 - logging.warning("set_password: keyring file corrupted, Reverting to Backup")
48 - # Revert to the backup file (copy backup over current file)
50 - src = self.backup_file_path
51 - dest = self.file_path
52 - self.filecopy(src,dest)
53 - except shutil.Error as e:
54 - logging.warning("set_password: Revert from Backup failed. Error: %s" % e)
56 - # Load the keyring from the disk, if this fails exception is raised
58 - config = configparser.RawConfigParser()
59 - config.read(self.file_path)
61 - e = sys.exc_info()[0]
62 - logging.warning("set_password: Both keyring files are non useable. Error: %s" % e)
64 + logging.warning("set_password: keyring file corrupted")
67 # Update the keyring with the password
68 @@ -149,17 +118,15 @@ class BaseKeyring(FileBacked, KeyringBac
69 config.add_section(service)
70 config.set(service, username, password_base64)
72 - # Make a back up of the keyring file here
74 - src = self.file_path
75 - dest = self.backup_file_path
76 - self.filecopy(src,dest)
77 - except shutil.Error as e:
78 - logging.warning("set_password: Backup failed. Error: %s" % e)
80 # Save the keyring back to the file
81 - with open(self.file_path, 'w') as config_file:
82 + storage_root = os.path.dirname(self.file_path)
83 + tmpfile = "tmpfile.%s" % os.getpid()
84 + with open(storage_root + "/" + tmpfile, 'w') as config_file:
85 config.write(config_file)
86 + # copy will overwrite but move will not
87 + shutil.copy(storage_root + "/" + tmpfile,self.file_path)
88 + # wipe out tmpfile here
89 + os.remove(storage_root + "/" + tmpfile)
93 @@ -203,8 +170,15 @@ class BaseKeyring(FileBacked, KeyringBac
94 except configparser.NoSectionError:
95 raise PasswordDeleteError("Password not found")
97 - with open(self.file_path, 'w') as config_file:
98 + storage_root = os.path.dirname(self.file_path)
99 + tmpfile = "tmpfile.%s" % os.getpid()
100 + with open(storage_root + "/" + tmpfile, 'w') as config_file:
101 config.write(config_file)
102 + # copy will overwrite but move will not
103 + shutil.copy(storage_root + "/" + tmpfile,self.file_path)
105 + os.remove(storage_root + "/" + tmpfile)
108 class PlaintextKeyring(BaseKeyring):
109 """Simple File Keyring with no encryption"""
110 @@ -213,7 +187,6 @@ class PlaintextKeyring(BaseKeyring):
111 "Applicable for all platforms, but not recommended"
113 filename = 'keyring_pass.cfg'
114 - backup_filename = 'crypted_pass_backup.cfg'
116 def encrypt(self, password):
117 """Directly return the password itself.
118 @@ -267,7 +240,6 @@ class EncryptedKeyring(Encrypted, BaseKe
119 """PyCrypto File Keyring"""
121 filename = 'crypted_pass.cfg'
122 - backup_filename = 'crypted_pass_backup.cfg'
123 pw_prefix = 'pw:'.encode()
125 @properties.ClassProperty
126 @@ -326,27 +298,15 @@ class EncryptedKeyring(Encrypted, BaseKe
127 escape_for_ini('password reference'),
129 except (configparser.NoSectionError, configparser.NoOptionError):
130 - # The current file doesn't have the keyring-setting, check the backup
131 - if os.path.exists(self.backup_file_path):
132 - config = configparser.RawConfigParser()
133 - config.read(self.backup_file_path)
136 - escape_for_ini('keyring-setting'),
137 - escape_for_ini('password reference'),
139 - except (configparser.NoSectionError, configparser.NoOptionError):
141 - # backup file has it, let's use it
143 - src = self.backup_file_path
144 - dest = self.file_path
145 - shutil.copy(src,dest)
146 - except shutil.Error as e:
147 - logging.warning("Revert from Backup failed. Error: %s" % e)
153 + # remove any residual temporary files here
155 + for tmpfile in glob.glob(os.path.dirname(self.file_path) + "/" + "tmpfile.*"):
158 + logging.warning("_check_file: tmpfile removal failed")