Skip to content

Commit

Permalink
[bug] refactoring and allowing passphrases with spaces
Browse files Browse the repository at this point in the history
  • Loading branch information
NavaL committed Nov 22, 2016
1 parent ffcc0e4 commit 77eb9e7
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 11 deletions.
26 changes: 20 additions & 6 deletions gnupg/_parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,6 @@ def _get_options_group(group=None):
'--status-fd',
'--verify-options',
'--command-fd',
'--passphrase',
])
#: These have their own parsers and don't really fit into a group
other_options = frozenset(['--debug-level',
Expand Down Expand Up @@ -814,7 +813,8 @@ def progress(status_code):
class KeyExtensionInterface(object):
""" Interface that guards against misuse of --edit-key combined with --command-fd"""

def __init__(self, validity):
def __init__(self, validity, passphrase=None):
self._passphrase = passphrase
self._validity_option = validity
self._clean_key_extension_option()

Expand All @@ -824,13 +824,26 @@ def _clean_key_extension_option(self):
if not allowed_entry:
raise UsageError("Key extension option: %s is not valid" % self._validity_option)

def _input_passphrase(self, _input):
if self._passphrase:
return "%s%s\n" % (_input, self._passphrase)
return _input

def _main_key_command(self):
main_key_input = "expire\n%s\n" % self._validity_option
return self._input_passphrase(main_key_input)

def _sub_key_command(self, sub_key_number=1):
sub_key_input = "key %d\nexpire\n%s\n" % (sub_key_number, self._validity_option)
return self._input_passphrase(sub_key_input)

def gpg_interactive_input(self, extend_subkey=True):
""" processes series of inputs normally supplied on --edit-key but passed through stdin
this ensures that no other --edit-key command is actually passing through.
"""
_input = "expire\n%s\n" % self._validity_option
_input = self._main_key_command()
if extend_subkey:
_input = "%skey 1\nexpire\n%s\n" % (_input, self._validity_option)
_input += self._sub_key_command()
return "%ssave\n" % _input


Expand All @@ -847,8 +860,9 @@ def _handle_status(self, key, value):
:raises: :exc:`~exceptions.ValueError` if the status message is unknown.
"""
if key in ("USERID_HINT", "NEED_PASSPHRASE", "KEYEXPIRED",
"SIGEXPIRED", "GOOD_PASSPHRASE", "GOT_IT", "GET_LINE"):
if key in ("USERID_HINT", "NEED_PASSPHRASE",
"GET_HIDDEN", "SIGEXPIRED", "KEYEXPIRED",
"GOOD_PASSPHRASE", "GOT_IT", "GET_LINE"):
pass
elif key in ("BAD_PASSPHRASE", "MISSING_PASSPHRASE"):
self.status = key.replace("_", " ").lower()
Expand Down
8 changes: 3 additions & 5 deletions gnupg/gnupg.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,14 +563,12 @@ def extend_key(self, keyid, validity='1y', passphrase=None, extend_subkey=True):
the new expiration date can be obtained by .list_keys()
"""

args = ["--batch"]
if passphrase:
args.append("--passphrase %s" % passphrase)
args.extend(["--command-fd 0", "--edit-key %s" % keyid])
args = ["--command-fd 0", "--edit-key %s" % keyid]

p = self._open_subprocess(args)
result = self._result_map['extension'](self)
extension_input = KeyExtensionInterface(validity).gpg_interactive_input(extend_subkey)
passphrase = passphrase.encode(self._encoding) if passphrase else passphrase
extension_input = KeyExtensionInterface(validity, passphrase).gpg_interactive_input(extend_subkey)
p.stdin.write(extension_input)
self._collect_output(p, result, stdin=p.stdin)
return result
Expand Down
18 changes: 18 additions & 0 deletions gnupg/test/test_gnupg.py
Original file line number Diff line number Diff line change
Expand Up @@ -1381,6 +1381,23 @@ def test_key_extension(self):
self.assertEqual(next_week, datetime.date.fromtimestamp(int(fecthed_key['expires'])))
self.assertEqual(key.fingerprint, fecthed_key['fingerprint'])

def test_passphrase_with_space_on_key_extension(self):
"""Test that wrong passphrase does not allow extension."""
today = datetime.date.today()
date_format = '%Y-%m-%d'
tomorrow = today + datetime.timedelta(days=1)
password_with_space = "passphrase with space"
key = self.generate_key("Haha", "ho.ho", passphrase=password_with_space,
expire_date=tomorrow.strftime(date_format))

self.gpg.extend_key(key.fingerprint, validity='1w', passphrase=password_with_space)
next_week = today + datetime.timedelta(weeks=1)

current_keys = self.gpg.list_keys()
for fecthed_key in current_keys:
self.assertEqual(next_week, datetime.date.fromtimestamp(int(fecthed_key['expires'])))
self.assertEqual(key.fingerprint, fecthed_key['fingerprint'])

def test_wrong_passphrase_on_key_extension(self):
"""Test that wrong passphrase does not allow extension."""
today = datetime.date.today()
Expand Down Expand Up @@ -1476,6 +1493,7 @@ def test_invalid_extension_period_throws_exception_on_key_extension(self):
'test_import_only']),
'recvkeys': set(['test_recv_keys_default']),
'extend': set(['test_key_extension',
'test_passphrase_with_space_on_key_extension',
'test_wrong_passphrase_on_key_extension',
'test_invalid_extension_period_throws_exception_on_key_extension']),
}
Expand Down

0 comments on commit 77eb9e7

Please sign in to comment.