From 8a938be4ffa97490d89206cc1fd079a057cfc65c Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Tue, 26 Jul 2016 10:59:24 +0200 Subject: Manage retry counts of user and admin passwords Signed-off-by: Szczepan Zalega --- NK_C_API.cc | 31 +++++++++++++++++++++++++++++-- NK_C_API.h | 2 ++ NitrokeyManager.cc | 11 ++++++++++- include/NitrokeyManager.h | 3 +++ include/stick10_commands.h | 4 ++-- unittest/test_bindings.py | 19 ++++++++++++++++++- 6 files changed, 64 insertions(+), 6 deletions(-) diff --git a/NK_C_API.cc b/NK_C_API.cc index 77bd181..7de5bbd 100644 --- a/NK_C_API.cc +++ b/NK_C_API.cc @@ -5,6 +5,17 @@ using namespace nitrokey; static uint8_t NK_last_command_status = 0; +template +auto get_with_result(T func){ + try { + return func(); + } + catch (CommandFailedException & commandFailedException){ + NK_last_command_status = commandFailedException.last_command_status; + return commandFailedException.last_command_status; + } +} + extern "C" { extern uint8_t NK_get_last_command_status(){ @@ -211,7 +222,7 @@ extern int NK_enable_password_safe(const char *user_pin){ extern int NK_get_password_safe_slot_status(){ auto m = NitrokeyManager::instance(); try { - m->get_password_safe_slot_status(); + m->get_password_safe_slot_status(); //TODO FIXME } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; @@ -220,4 +231,20 @@ extern int NK_get_password_safe_slot_status(){ return 0; } -} \ No newline at end of file +extern uint8_t NK_get_user_retry_count(){ + auto m = NitrokeyManager::instance(); + return get_with_result([&](){ + return m->get_user_retry_count(); + }); +} + +extern uint8_t NK_get_admin_retry_count(){ + auto m = NitrokeyManager::instance(); + return get_with_result([&](){ + return m->get_admin_retry_count(); + }); +} + + +} + diff --git a/NK_C_API.h b/NK_C_API.h index 16c75ee..75702cc 100644 --- a/NK_C_API.h +++ b/NK_C_API.h @@ -25,6 +25,8 @@ extern int NK_totp_get_time(); extern uint8_t NK_get_last_command_status(); extern int NK_change_admin_PIN(char *current_PIN, char *new_PIN); extern int NK_change_user_PIN(char *current_PIN, char *new_PIN); +extern uint8_t NK_get_user_retry_count(); +extern uint8_t NK_get_admin_retry_count(); extern int NK_enable_password_safe(const char *user_pin); extern int NK_get_password_safe_slot_status(); } diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index fd2189e..d684853 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -220,7 +220,16 @@ namespace nitrokey{ } void NitrokeyManager::get_password_safe_slot_status() { - GetPasswordSafeSlotStatus::CommandTransaction::run(*device); + GetPasswordSafeSlotStatus::CommandTransaction::run(*device); //TODO FIXME + } + + uint8_t NitrokeyManager::get_user_retry_count() { + auto response = GetUserPasswordRetryCount::CommandTransaction::run(*device); + return response.password_retry_count; + } + uint8_t NitrokeyManager::get_admin_retry_count() { + auto response = GetPasswordRetryCount::CommandTransaction::run(*device); + return response.password_retry_count; } diff --git a/include/NitrokeyManager.h b/include/NitrokeyManager.h index 6f4ab75..6588711 100644 --- a/include/NitrokeyManager.h +++ b/include/NitrokeyManager.h @@ -44,6 +44,9 @@ namespace nitrokey { void get_password_safe_slot_status(); + uint8_t get_admin_retry_count(); + uint8_t get_user_retry_count(); + private: NitrokeyManager(); ~NitrokeyManager(); diff --git a/include/stick10_commands.h b/include/stick10_commands.h index c8eda03..31041d0 100644 --- a/include/stick10_commands.h +++ b/include/stick10_commands.h @@ -313,7 +313,7 @@ class GetPasswordRetryCount : Command { bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; - ss << " password_retry_count\t" << password_retry_count << std::endl; + ss << " password_retry_count\t" << (int)password_retry_count << std::endl; return ss.str(); } } __packed; @@ -331,7 +331,7 @@ class GetUserPasswordRetryCount bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; - ss << " password_retry_count\t" << password_retry_count << std::endl; + ss << " password_retry_count\t" << (int)password_retry_count << std::endl; return ss.str(); } } __packed; diff --git a/unittest/test_bindings.py b/unittest/test_bindings.py index ac77140..51e1233 100644 --- a/unittest/test_bindings.py +++ b/unittest/test_bindings.py @@ -35,10 +35,10 @@ def C(request): ffi.cdef(declaration) C = ffi.dlopen("../build/libnitrokey.so") - C.NK_set_debug(False) C.NK_login('12345678', '123123123') # C.NK_set_debug(True) + def fin(): print ('\nFinishing connection to device') C.NK_logout() @@ -50,6 +50,7 @@ def C(request): def test_enable_password_safe(C): + # lock device assert C.NK_enable_password_safe('wrong_password') == DeviceErrorCode.WRONG_PASSWORD assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK @@ -72,6 +73,22 @@ def test_user_PIN_change(C): assert C.NK_change_user_PIN('123123123', DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK +def test_admin_retry_counts(C): + assert C.NK_get_admin_retry_count() == 3 + assert C.NK_change_admin_PIN('wrong_password', '123123123') == DeviceErrorCode.WRONG_PASSWORD + assert C.NK_get_admin_retry_count() == 3 - 1 + assert C.NK_change_admin_PIN(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK + assert C.NK_get_admin_retry_count() == 3 + + +def test_user_retry_counts(C): + assert C.NK_get_user_retry_count() == 3 + assert C.NK_enable_password_safe('wrong_password') == DeviceErrorCode.WRONG_PASSWORD + assert C.NK_get_user_retry_count() == 3 - 1 + assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK + assert C.NK_get_user_retry_count() == 3 + + def test_HOTP_RFC(C): # https://tools.ietf.org/html/rfc4226#page-32 C.NK_write_hotp_slot(1, 'python_test', RFC_SECRET, 0, '123123123') -- cgit v1.2.1