Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cryptnox_cli/command/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def run_execute(self, card) -> int:
except (cryptnox_sdk_py.exceptions.CryptnoxException, NotImplementedError) as error:
print(error)
result = -1
except ui.ExitException:
except (ui.ExitException, security.ExitException):
print("Exited by user.")
result = -1
except Unauthorized as error:
Expand Down
53 changes: 48 additions & 5 deletions cryptnox_cli/command/helper/security.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,52 @@ class ExitException(Exception):
"""Raised when user has indicated he want's to exit the command"""


def _getpass(prompt='Password: ', mask='*'):
"""
Cross-platform getpass that raises KeyboardInterrupt on Ctrl+C.
On Windows, getch() returns 0x03 for Ctrl+C in raw mode,
sow we catch it directly without polling.
"""
import sys
if sys.platform == 'win32':
from msvcrt import getch
entered = []
sys.stdout.write(prompt)
sys.stdout.flush()
while True:
key = ord(getch())
if key == 3: # Ctrl+C
sys.stdout.write('\n')
sys.stdout.flush()
raise KeyboardInterrupt
elif key == 13: # Enter
sys.stdout.write('\n')
sys.stdout.flush()
return ''.join(entered)
elif key in (8, 127): # Backspace/Del
if entered:
sys.stdout.write('\b \b')
sys.stdout.flush()
entered.pop()
elif 32 <= key <= 126: # Printable ASCII
entered.append(chr(key))
sys.stdout.write(mask)
sys.stdout.flush()
else:
from stdiomask import getpass
return getpass(prompt, mask)


def _secret_with_exit(text, required=True):
"""
Local implementation of secret_with_exit to avoid circular import.
Replicates the functionality of ui.secret_with_exit.
"""
from stdiomask import getpass

while True:
value = getpass(text).strip()
if value.lower() == "exit":
raise ExitException
try:
value = _getpass(text).strip()
except KeyboardInterrupt:
raise ExitException()
if required and not value:
print("This entry is required")
else:
Expand Down Expand Up @@ -93,6 +128,9 @@ def check_pin_code(card, text: str = "Cryptnox PIN code: ") -> str:
pin_code = "1"
easy_mode = is_easy_mode(card.info)

if not easy_mode:
print("Press Ctrl+C to cancel.")

while not authorized:
if easy_mode:
print(f"Card is in {EASY_MODE_TEXT}. Using easy mode PIN automatically.")
Expand All @@ -112,6 +150,8 @@ def check_pin_code(card, text: str = "Cryptnox PIN code: ") -> str:
prompt_text = text
except cryptnox_sdk_py.exceptions.PinBlockedException:
raise
except ExitException:
raise
except cryptnox_sdk_py.exceptions.PinException:
print("Card requires a power cycle. Please remove and re-tap the card, then try again.")
raise
Expand Down Expand Up @@ -159,6 +199,9 @@ def process_command_with_puk(
**kwargs) -> bool:
easy_mode = is_easy_mode(card.info)

if not easy_mode:
print("Press Ctrl+C to cancel.")

while True:
if easy_mode:
print(f"Card is in {EASY_MODE_TEXT}. Using easy mode PUK automatically.")
Expand Down
7 changes: 5 additions & 2 deletions cryptnox_cli/command/helper/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from typing import List, Union, Dict

import cryptnox_sdk_py
from stdiomask import getpass
from .security import _getpass as getpass
from tabulate import tabulate

from . import security
Expand Down Expand Up @@ -60,7 +60,10 @@ def confirm(text: str, warning: str = "") -> bool:
def input_with_exit(text, required=True, input_method=None):
input_method = input_method or input
while True:
value = input_method(text).strip()
try:
value = input_method(text).strip()
except KeyboardInterrupt:
raise ExitException()
if value.lower() == "exit":
raise ExitException
if required and not value:
Expand Down
Loading