diff options
-rw-r--r-- | NK_C_API.cc | 7 | ||||
-rw-r--r-- | NK_C_API.h | 1 | ||||
-rw-r--r-- | NitrokeyManager.cc | 18 | ||||
-rw-r--r-- | include/NitrokeyManager.h | 3 | ||||
-rw-r--r-- | include/stick10_commands.h | 44 | ||||
-rw-r--r-- | 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(); @@ -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<GetHOTP>(); 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<WriteGeneralConfig>(); + 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<Authorize>(); + 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<CommandID::GET_STATUS> { 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<CommandID::GET_STATUS> { 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<CommandID::PW_SAFE_SEND_DATA> { class WriteGeneralConfig : Command<CommandID::WRITE_CONFIG> { 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<command_id(), struct CommandPayload, struct EmptyPayload> 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)) |