Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better pin handling #76

Closed
wants to merge 4 commits into from
Closed
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
47 changes: 32 additions & 15 deletions solo/cli/key.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,13 @@ def make_credential(serial, host, user, udp, prompt, pin):

import solo.hmac_secret

#check for PIN
if not pin:
pin = getpass.getpass("PIN (leave empty for no PIN: ")
if not pin:
dev = solo.client.find(serial, udp=udp)
if dev.has_pin() is False:
#remove PIN if no PIN set
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

silently removing the PIN is incorrect and misleading -- if there is no PIN set and the user specifies a PIN, he should get an error

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay yeah silently is maybe bad, I just wanted to try and resolve this without the user needing to actially do anything extra, making it easier to use

pin = None
elif not pin:
#Ask for PIN is set and not in command
pin = getpass.getpass("PIN: ")

solo.hmac_secret.make_credential(
host=host, user_id=user, serial=serial, output=True, prompt=prompt, udp=udp, pin=pin
Expand Down Expand Up @@ -177,11 +179,13 @@ def challenge_response(serial, host, user, prompt, credential_id, challenge, udp

import solo.hmac_secret

#check for PIN
if not pin:
pin = getpass.getpass("PIN (leave empty for no PIN: ")
if not pin:
dev = solo.client.find(serial, udp=udp)
if dev.has_pin() is False:
#remove PIN if no PIN set
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as above

pin = None
elif not pin:
#Ask for PIN is set and not in command
pin = getpass.getpass("PIN: ")

solo.hmac_secret.simple_secret(
credential_id,
Expand Down Expand Up @@ -292,6 +296,10 @@ def reset(serial):
@click.option("-s", "--serial", help="Serial number of Solo to use")
# @click.option("--new-pin", help="change current pin")
def change_pin(serial):
client = solo.client.find(serial)
if not client.has_pin():
print("This Device does not have a PIN yet, use set-pin instead")
sys.exit(1)
"""Change pin of current key"""
old_pin = getpass.getpass("Please enter old pin: ")
new_pin = getpass.getpass("Please enter new pin: ")
Expand All @@ -300,7 +308,7 @@ def change_pin(serial):
click.echo("New pin are mismatched. Please try again!")
return
try:
solo.client.find(serial).change_pin(old_pin, new_pin)
client.change_pin(old_pin, new_pin)
click.echo("Done. Please use new pin to verify key")
except Exception as e:
print(e)
Expand All @@ -310,14 +318,18 @@ def change_pin(serial):
@click.option("-s", "--serial", help="Serial number of Solo to use")
# @click.option("--new-pin", help="change current pin")
def set_pin(serial):
client = solo.client.find(serial)
if client.has_pin():
print("This Device already has a PIN, use change-pin instead")
sys.exit(1)
"""Set pin of current key"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docstring should be first

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so that's a special string? I thought that was just a comment

new_pin = getpass.getpass("Please enter new pin: ")
confirm_pin = getpass.getpass("Please confirm new pin: ")
if new_pin != confirm_pin:
click.echo("New pin are mismatched. Please try again!")
return
try:
solo.client.find(serial).set_pin(new_pin)
client.set_pin(new_pin)
click.echo("Done. Please use new pin to verify key")
except Exception as e:
print(e)
Expand All @@ -333,14 +345,19 @@ def verify(pin, serial, udp):
"""Verify key is valid Solo Secure or Solo Hacker."""

# Any longer and this needs to go in a submodule
print("Please press the button on your Solo key")
try:
cert = solo.client.find(serial, udp=udp).make_credential(pin=pin)
dev = solo.client.find(serial, udp=udp)
if dev.has_pin() is False:
#remove PIN if no PIN set
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see above

pin = None
elif not pin:
#Ask for PIN is set and not in command
pin = getpass.getpass("PIN: ")

print("Please press the button on your Solo key")
cert = dev.make_credential(pin=pin)
except Fido2ClientError as e:
cause = str(e.cause)
if "PIN required" in cause:
print("Your key has a PIN set. Please pass it using `--pin <your PIN>`")
sys.exit(1)
# error 0x31
if "PIN_INVALID" in cause:
print("Your key has a different PIN. Please try to remember it :)")
Expand Down
4 changes: 4 additions & 0 deletions solo/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,3 +409,7 @@ def isCorrectVersion(current, target):
self.verify_flash(sig)

return sig

def has_pin (self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra space

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what extra space? when I have spaceds at the end of the line the PR quality checker says bad.

haspin = (self.client.info.options["clientPin"])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return self.client.info.options["clientPin"]

return (haspin)