From 8c5b24092faf90672523e60e6eee12a83539ce11 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Wed, 27 Jul 2016 10:32:30 +0200 Subject: Handle write config command Signed-off-by: Szczepan Zalega --- NK_C_API.cc | 7 +++++++ NK_C_API.h | 1 + NitrokeyManager.cc | 18 ++++++++++++++++++ include/NitrokeyManager.h | 3 +++ include/stick10_commands.h | 44 ++++++++++++++++++++++++++++++++++++-------- unittest/test_bindings.py | 8 +++++--- 6 files changed, 70 insertions(+), 11 deletions(-) diff --git a/NK_C_API.cc b/NK_C_API.cc index 441acb9..e5febe1 100644 --- a/NK_C_API.cc +++ b/NK_C_API.cc @@ -106,6 +106,13 @@ extern int NK_unlock_user_password(const char* admin_password){ }); } +extern int NK_write_config(bool numlock, bool capslock, bool scrolllock, bool enable_user_password, bool delete_user_password, + const char *admin_temporary_password) { + auto m = NitrokeyManager::instance(); + return get_without_result( [&](){ + return m->write_config(numlock, capslock, scrolllock, enable_user_password, delete_user_password, admin_temporary_password); + }); +} extern const char * NK_status() { auto m = NitrokeyManager::instance(); diff --git a/NK_C_API.h b/NK_C_API.h index 29505fd..6058071 100644 --- a/NK_C_API.h +++ b/NK_C_API.h @@ -20,6 +20,7 @@ extern int NK_first_authenticate(const char* admin_password, const char* admin_t extern int NK_factory_reset(const char* admin_password); extern int NK_build_aes_key(const char* admin_password); extern int NK_unlock_user_password(const char* admin_password); +extern int NK_write_config(bool numlock, bool capslock, bool scrolllock, bool enable_user_password, bool delete_user_password, const char *admin_temporary_password); //otp extern const char * NK_get_totp_slot_name(uint8_t slot_number); extern const char * NK_get_hotp_slot_name(uint8_t slot_number); diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index 31436e5..53e355e 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -60,6 +60,7 @@ namespace nitrokey{ auto gh = get_payload(); gh.slot_number = get_internal_slot_number_for_hotp(slot_number); auto resp = GetHOTP::CommandTransaction::run(*device, gh); + //TODO handle user authorization requests (taken from config) return resp.code; } @@ -79,6 +80,7 @@ namespace nitrokey{ gt.last_interval = last_interval; gt.last_totp_time = last_totp_time; auto resp = GetTOTP::CommandTransaction::run(*device, gt); + //TODO handle user authorization requests (taken from config) return resp.code; } @@ -319,4 +321,20 @@ namespace nitrokey{ UnlockUserPassword::CommandTransaction::run(*device, p); } + void NitrokeyManager::write_config(bool numlock, bool capslock, bool scrolllock, bool enable_user_password, bool delete_user_password, const char *admin_temporary_password) { + auto p = get_payload(); + p.numlock = (uint8_t) numlock; + p.capslock = (uint8_t) capslock; + p.scrolllock = (uint8_t) scrolllock; + p.enable_user_password = (uint8_t) enable_user_password; + p.delete_user_password = (uint8_t) delete_user_password; + + auto auth = get_payload(); + strcpyT(auth.temporary_password, admin_temporary_password); + auth.crc_to_authorize = WriteGeneralConfig::CommandTransaction::getCRC(p); + Authorize::CommandTransaction::run(*device, auth); + + WriteGeneralConfig::CommandTransaction::run(*device, p); + } + } \ No newline at end of file diff --git a/include/NitrokeyManager.h b/include/NitrokeyManager.h index 47aca83..0f24b1f 100644 --- a/include/NitrokeyManager.h +++ b/include/NitrokeyManager.h @@ -67,6 +67,9 @@ namespace nitrokey { void unlock_user_password(const char *admin_password); + void write_config(bool numlock, bool capslock, bool scrolllock, bool enable_user_password, + bool delete_user_password, const char *admin_temporary_password); + private: NitrokeyManager(); ~NitrokeyManager(); diff --git a/include/stick10_commands.h b/include/stick10_commands.h index 8dc1b22..7a7e2f2 100644 --- a/include/stick10_commands.h +++ b/include/stick10_commands.h @@ -280,9 +280,16 @@ class GetStatus : Command { struct ResponsePayload { uint16_t firmware_version; uint8_t card_serial[4]; - uint8_t general_config[3]; - uint8_t otp_password_config[2]; - + union { + uint8_t general_config[5]; + struct{ + uint8_t numlock; + uint8_t capslock; + uint8_t scrolllock; + uint8_t enable_user_password; + uint8_t delete_user_password; + }; + }; bool isValid() const { return true; } std::string dissect() const { @@ -294,10 +301,13 @@ class GetStatus : Command { ss << "general_config:\t" << ::nitrokey::misc::hexdump((const char *)(general_config), sizeof general_config); - ss << "otp_password_config:\t" - << ::nitrokey::misc::hexdump((const char *)(otp_password_config), - sizeof otp_password_config); - return ss.str(); + ss << "numlock:\t" << (bool)numlock << std::endl; + ss << "capslock:\t" << (bool)capslock << std::endl; + ss << "scrolllock:\t" << (bool)scrolllock << std::endl; + ss << "enable_user_password:\t" << (bool) enable_user_password << std::endl; + ss << "delete_user_password:\t" << (bool) delete_user_password << std::endl; + + return ss.str(); } } __packed; @@ -553,7 +563,25 @@ class PasswordSafeSendSlotViaHID : Command { class WriteGeneralConfig : Command { public: struct CommandPayload { - uint8_t config[5]; + union{ + uint8_t config[5]; + struct{ + uint8_t numlock; + uint8_t capslock; + uint8_t scrolllock; + uint8_t enable_user_password; + uint8_t delete_user_password; + }; + }; + std::string dissect() const { + std::stringstream ss; + ss << "numlock:\t" << (bool)numlock << std::endl; + ss << "capslock:\t" << (bool)capslock << std::endl; + ss << "scrolllock:\t" << (bool)scrolllock << std::endl; + ss << "enable_user_password:\t" << (bool) enable_user_password << std::endl; + ss << "delete_user_password:\t" << (bool) delete_user_password << std::endl; + return ss.str(); + } } __packed; typedef Transaction diff --git a/unittest/test_bindings.py b/unittest/test_bindings.py index f3c3ee7..e94a6d6 100644 --- a/unittest/test_bindings.py +++ b/unittest/test_bindings.py @@ -37,10 +37,11 @@ def C(request): ffi.cdef(declaration) C = ffi.dlopen("../build/libnitrokey.so") + C.NK_set_debug(False) C.NK_login(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) assert C.NK_user_authenticate(DefaultPasswords.USER, DefaultPasswords.USER_TEMP) == DeviceErrorCode.STATUS_OK - # C.NK_set_debug(True) + # C.NK_status() def fin(): print ('\nFinishing connection to device') @@ -164,10 +165,11 @@ def test_TOTP_RFC(C): def test_get_slot_names(C): C.NK_set_debug(True) + assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_erase_totp_slot(0, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK # erasing slot invalidates temporary password, so requesting authentication - # assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - # assert C.NK_erase_hotp_slot(0, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK + assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK + assert C.NK_erase_hotp_slot(0, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK for i in range(16): name = ffi.string(C.NK_get_totp_slot_name(i)) -- cgit v1.2.1