aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSzczepan Zalega <szczepan@nitrokey.com>2017-06-01 19:28:36 +0200
committerSzczepan Zalega <szczepan@nitrokey.com>2017-06-01 19:28:36 +0200
commitb964508cd1a8e3ec61b5f5eddfa79cf6c99bc8db (patch)
tree873acc36830128bf40ddbbddd0e0ca49534a9677
parent06c0deb7935a9390a67bc02d6c323e64c785a026 (diff)
downloadlibnitrokey-b964508cd1a8e3ec61b5f5eddfa79cf6c99bc8db.tar.gz
libnitrokey-b964508cd1a8e3ec61b5f5eddfa79cf6c99bc8db.tar.bz2
First CLI implementationwip-command_line_client
Signed-off-by: Szczepan Zalega <szczepan@nitrokey.com>
-rwxr-xr-xunittest/libnitrokey.py232
-rw-r--r--unittest/setup.py15
2 files changed, 247 insertions, 0 deletions
diff --git a/unittest/libnitrokey.py b/unittest/libnitrokey.py
new file mode 100755
index 0000000..f5a7f70
--- /dev/null
+++ b/unittest/libnitrokey.py
@@ -0,0 +1,232 @@
+#!/usr/bin/env python
+
+"""
+Use the following to run locally:
+
+$ sudo pip install virtualenv
+$ virtualenv venv
+$ . venv/bin/activate
+$ pip install --editable .
+$ libnitrokey --help
+"""
+
+import click
+import itertools
+import cffi
+
+ffi = cffi.FFI()
+
+gs = ffi.string
+device_type = None
+
+
+def connect():
+ fp = '../NK_C_API.h'
+
+ declarations = []
+ with open(fp, 'r') as f:
+ declarations = f.readlines()
+
+ a = iter(declarations)
+ for declaration in a:
+ if declaration.startswith('NK_C_API'):
+ declaration = declaration.replace('NK_C_API', '').strip()
+ while not ';' in declaration:
+ declaration += (next(a)).strip()
+ ffi.cdef(declaration, override=True)
+
+ C = None
+ import os, sys
+
+ path_build = [".", os.path.join(".", "build"), os.path.join("..", "build")]
+ names = ["libnitrokey-log.so", "libnitrokey.so"]
+ paths = itertools.product(path_build, names)
+ tested = []
+ for p in paths:
+ p = os.path.join(p[0], p[1])
+ tested.append(p)
+ if os.path.exists(p):
+ C = ffi.dlopen(p)
+ break
+ if not C:
+ print("No library file found")
+ print("Tested paths:" + repr(tested))
+ sys.exit(1)
+
+ C.NK_set_debug(False)
+
+ nk_login = C.NK_login_auto()
+ if nk_login != 1:
+ print('No devices detected!')
+ assert nk_login != 0 # returns 0 if not connected or wrong model or 1 when connected
+ global device_type
+ firmware_version = C.NK_get_major_firmware_version()
+ model = 'P' if firmware_version in [7, 8] else 'S'
+ device_type = (model, firmware_version)
+
+ # assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
+ # assert C.NK_user_authenticate(DefaultPasswords.USER, DefaultPasswords.USER_TEMP) == DeviceErrorCode.STATUS_OK
+
+ # C.NK_status()
+
+ C.NK_set_debug(True)
+ return C
+
+
+C = connect()
+
+
+@click.group()
+@click.option('--debug', default=0, help='debug level')
+def cli(debug):
+ C.NK_set_debug(debug != 0)
+ pass
+
+
+@click.command()
+def status():
+ """Show device's status"""
+ print (gs(C.NK_status()))
+ if device_type[0] == 'S':
+ print (gs(C.NK_get_status_storage_as_string()))
+ return C.NK_get_last_command_status()
+
+
+@click.command()
+def device_serial_number():
+ """Show device's serial number"""
+ print (gs(C.NK_device_serial_number()))
+ return C.NK_get_last_command_status()
+
+
+def abort_callback(ctx, param, value):
+ if not value:
+ ctx.abort()
+
+
+@click.command()
+@click.option('--yes', is_flag=True, callback=abort_callback,
+ expose_value=False, prompt='Do you want to continue?')
+def lock_device():
+ """Lock the device - lock volumes and password safe"""
+ print C.NK_lock_device() or "Locked"
+ return C.NK_get_last_command_status()
+
+
+#
+# @click.command()
+# def NK_first_authenticate():
+# """Show device status"""
+# print C.NK_first_authenticate()
+# return C.NK_get_last_command_status()
+#
+#
+# @click.command()
+# def NK_user_authenticate():
+# """Show device status"""
+# print C.NK_user_authenticate()
+# return C.NK_get_last_command_status()
+
+
+# @click.command()
+# def NK_factory_reset():
+# """Show device status"""
+# print C.NK_factory_reset()
+# return C.NK_get_last_command_status()
+#
+#
+# @click.command()
+# def NK_build_aes_key():
+# """Show device status"""
+# print C.NK_build_aes_key()
+# return C.NK_get_last_command_status()
+#
+#
+# @click.command()
+# @click.argument('slot_number')
+# def NK_unlock_user_password(slot_number):
+# """Show device status"""
+# print C.NK_unlock_user_password()
+# return C.NK_get_last_command_status()
+
+
+@click.command()
+@click.argument('slot_number')
+def get_totp_slot_name(slot_number):
+ """Show TOTP slot name"""
+ print gs(C.NK_get_totp_slot_name(int(slot_number))) or "OTP slot not programmed"
+ return C.NK_get_last_command_status()
+
+
+@click.command()
+@click.argument('slot_number')
+def get_hotp_slot_name(slot_number):
+ """Show HOTP slot name"""
+ print gs(C.NK_get_hotp_slot_name(int(slot_number))) or "OTP slot not programmed"
+ return C.NK_get_last_command_status()
+
+
+#
+# @click.command()
+# def NK_erase_hotp_slot():
+# """Show device status"""
+# print C.NK_erase_hotp_slot()
+# return C.NK_get_last_command_status()
+#
+#
+# @click.command()
+# def NK_erase_totp_slot():
+# """NK_erase_totp_slot"""
+# print C.NK_erase_totp_slot()
+# return C.NK_get_last_command_status()
+
+
+@click.command()
+@click.argument('slot_number')
+def get_hotp_code(slot_number):
+ """Get HOTP code"""
+ print gs(C.NK_get_hotp_code(int(slot_number))) or "OTP slot not programmed"
+ return C.NK_get_last_command_status()
+
+
+@click.command()
+@click.argument('slot_number')
+def get_totp_code(slot_number):
+ """Get TOTP code"""
+ print gs(C.NK_get_totp_code(int(slot_number), 0, 0, 0)) or "OTP slot not programmed"
+ return C.NK_get_last_command_status()
+
+
+@click.command()
+@click.option('--user_pin', prompt=True, confirmation_prompt=True,
+ hide_input=True)
+def unlock_encrypted_volume(user_pin):
+ """Unlock encrypted volume"""
+ print C.NK_unlock_encrypted_volume(str(user_pin)) or "Unlocked"
+ return C.NK_get_last_command_status()
+
+
+@click.command()
+@click.option('--hidden_volume_password', prompt=True, confirmation_prompt=True,
+ hide_input=True)
+def unlock_hidden_volume(hidden_volume_password):
+ """Unlock hidden volume"""
+ print C.NK_unlock_hidden_volume(str(hidden_volume_password)) or "Unlocked"
+ return C.NK_get_last_command_status()
+
+
+cli.add_command(status)
+cli.add_command(device_serial_number)
+cli.add_command(lock_device)
+cli.add_command(unlock_encrypted_volume)
+cli.add_command(unlock_hidden_volume)
+
+cli.add_command(get_hotp_code)
+cli.add_command(get_totp_code)
+cli.add_command(get_hotp_slot_name)
+cli.add_command(get_totp_slot_name)
+
+if __name__ == '__main__':
+ cli()
+ C.NK_logout()
+
diff --git a/unittest/setup.py b/unittest/setup.py
new file mode 100644
index 0000000..8d2fe9d
--- /dev/null
+++ b/unittest/setup.py
@@ -0,0 +1,15 @@
+from setuptools import setup
+
+setup(
+ name='libnitrokey',
+ version='0.1',
+ py_modules=['libnitrokey'],
+ install_requires=[
+ 'Click',
+ 'cffi',
+ ],
+ entry_points='''
+ [console_scripts]
+ libnitrokey=libnitrokey:cli
+ ''',
+) \ No newline at end of file