Skip to content

Commit

Permalink
CryptedFileKeyring is not a BasicFileKeyring.
Browse files Browse the repository at this point in the history
Update the test suite and derive CryptedFileKeyring from KeyringBackend since
CryptedFileKeyring provides the same interface as BasicFileKeyring except the
encrypt and decrypt methods.

The passwords are now encoded as base64 in the ini file. Otherwise passwords
containing special characters may produce problems.
  • Loading branch information
Sebastian Ramacher committed Jun 9, 2012
1 parent ed9c9f3 commit cbf509b
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
23 changes: 19 additions & 4 deletions keyring/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,11 +436,26 @@ def supported(self):
"""
return 0

class CryptedFileKeyring(BasicFileKeyring):
class CryptedFileKeyring(KeyringBackend):
"""PyCrypto File Keyring"""

@properties.NonDataProperty
def 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(keyring.util.platform.data_root(), self.filename)

filename = 'crypted_pass.cfg'

def _relocate_file(self):
old_location = os.path.join(os.path.expanduser('~'), self.filename)
new_location = self.file_path
keyring.util.loc_compat.relocate_file(old_location, new_location)
# disable this function - it only needs to be run once
self._relocate_file = lambda: None

def supported(self):
"""Applicable for all platforms, but not recommend"
"""
Expand Down Expand Up @@ -537,7 +552,7 @@ def _convert_old_keyring(self, keyring_password=None):
for opt in config.options(section):
cipher = AES.new(password, AES.MODE_CFB, '\0' * AES.block_size)
p = config.get(section, opt).decode()
p = cipher.decrypt(p.decode('base64'))
p = cipher.decrypt(p.decode('base64')).encode('base64').replace('\n','')
config.set(section, opt, p)

self._write_config(config, keyring_password)
Expand Down Expand Up @@ -593,7 +608,7 @@ def get_password(self, service, username):
# fetch the password
try:
password = config.get(service, username)
password = password.decode('utf-8')
password = password.decode('base64').decode('utf-8')
except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
password = None
return password
Expand All @@ -608,7 +623,7 @@ def set_password(self, service, username, password):

config, keyring_password = self._read_config()

password = password.encode('utf-8')
password = password.encode('utf-8').encode('base64').replace('\n','')
# write the modification
if not config.has_section(service):
config.add_section(service)
Expand Down
6 changes: 5 additions & 1 deletion keyring/tests/test_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ def is_kwallet_supported():
def is_crypto_supported():
try:
__import__('Crypto.Cipher.AES')
__import__('crypt')
__import__('Crypto.Protocol.KDF')
__import__('Crypto.Random')
except ImportError:
return False
return True
Expand Down Expand Up @@ -370,6 +371,9 @@ def setUp(self):
def init_keyring(self):
return keyring.backend.CryptedFileKeyring()

def test_encrypt_decrypt(self):
pass


@unittest.skipUnless(is_win32_crypto_supported(),
"Need Windows")
Expand Down

0 comments on commit cbf509b

Please # to comment.