From 6c20e7ebcbab02d1f55f67632b5ad6e8685674dd Mon Sep 17 00:00:00 2001 From: Marcos Mokarzel Date: Fri, 11 Oct 2019 16:57:37 -0700 Subject: [PATCH] Test if the provided key is valid when create an iothub client to fail fast and generate a better log. [issue #1220] --- .../iothub_convenience_sample.c | 6 +- .../src/iothub_client_authorization.c | 27 ++++++- .../iothub_client_authorization_ut.c | 75 ++++++++++++------- 3 files changed, 75 insertions(+), 33 deletions(-) diff --git a/iothub_client/samples/iothub_convenience_sample/iothub_convenience_sample.c b/iothub_client/samples/iothub_convenience_sample/iothub_convenience_sample.c index b3952eaa91..b0eb3eadb6 100644 --- a/iothub_client/samples/iothub_convenience_sample/iothub_convenience_sample.c +++ b/iothub_client/samples/iothub_convenience_sample/iothub_convenience_sample.c @@ -188,7 +188,7 @@ static void connection_status_callback(IOTHUB_CLIENT_CONNECTION_STATUS result, I static void send_confirm_callback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback) { (void)userContextCallback; - // When a message is sent this callback will get envoked + // When a message is sent this callback will get invoked g_message_count_send_confirmations++; (void)printf("Confirmation callback received for message %lu with result %s\r\n", (unsigned long)g_message_count_send_confirmations, MU_ENUM_TO_STRING(IOTHUB_CLIENT_CONFIRMATION_RESULT, result)); } @@ -235,7 +235,7 @@ int main(void) device_handle = IoTHubDeviceClient_CreateFromConnectionString(connectionString, protocol); if (device_handle == NULL) { - (void)printf("Failure createing Iothub device. Hint: Check you connection string.\r\n"); + (void)printf("Failure creating Iothub device. Hint: Check you connection string.\r\n"); } else { @@ -261,7 +261,7 @@ int main(void) // Setting connection status callback to get indication of connection to iothub (void)IoTHubDeviceClient_SetConnectionStatusCallback(device_handle, connection_status_callback, NULL); - // Set any option that are neccessary. + // Set any option that are necessary. // For available options please see the iothub_sdk_options.md documentation // Setting Log Tracing. diff --git a/iothub_client/src/iothub_client_authorization.c b/iothub_client/src/iothub_client_authorization.c index ab5d6daa68..5b248cf6d2 100644 --- a/iothub_client/src/iothub_client_authorization.c +++ b/iothub_client/src/iothub_client_authorization.c @@ -11,6 +11,8 @@ #include "azure_c_shared_utility/strings.h" #include "azure_c_shared_utility/sastoken.h" #include "azure_c_shared_utility/shared_util_options.h" +#include "azure_c_shared_utility/azure_base64.h" +#include "azure_c_shared_utility/buffer_.h" #ifdef USE_PROV_MODULE #include "azure_prov_client/internal/iothub_auth_client.h" @@ -93,10 +95,31 @@ static IOTHUB_AUTHORIZATION_DATA* initialize_auth_client(const char* device_id, IOTHUB_AUTHORIZATION_HANDLE IoTHubClient_Auth_Create(const char* device_key, const char* device_id, const char* device_sas_token, const char *module_id) { IOTHUB_AUTHORIZATION_DATA* result; + bool is_key_valid; + + if (device_key == NULL) + { + is_key_valid = true; + } + else + { + /* Codes_SRS_IoTHub_Authorization_21_021: [ If the provided key is not base64 encoded, IoTHubClient_Auth_Create shall return NULL. ] */ + BUFFER_HANDLE key = Azure_Base64_Decode(device_key); + if (key != NULL) + { + is_key_valid = true; + } + else + { + is_key_valid = false; + } + BUFFER_delete(key); + } + /* Codes_SRS_IoTHub_Authorization_07_001: [if device_id is NULL IoTHubClient_Auth_Create, shall return NULL. ] */ - if (device_id == NULL) + if ((device_id == NULL) || (!is_key_valid)) { - LogError("Invalid Parameter device_id: %p", device_id); + LogError("Invalid Parameter %s", ((device_id == NULL) ? "device_id: NULL" : "key")); result = NULL; } else diff --git a/iothub_client/tests/iothub_client_authorization_ut/iothub_client_authorization_ut.c b/iothub_client/tests/iothub_client_authorization_ut/iothub_client_authorization_ut.c index 8a4e829975..5de3ca5cac 100644 --- a/iothub_client/tests/iothub_client_authorization_ut/iothub_client_authorization_ut.c +++ b/iothub_client/tests/iothub_client_authorization_ut/iothub_client_authorization_ut.c @@ -30,6 +30,8 @@ static void my_gballoc_free(void* ptr) #include "azure_c_shared_utility/strings.h" #include "azure_c_shared_utility/sastoken.h" #include "azure_c_shared_utility/xio.h" +#include "azure_c_shared_utility/buffer_.h" +#include "azure_c_shared_utility/azure_base64.h" #ifdef USE_PROV_MODULE #include "azure_prov_client/internal/iothub_auth_client.h" @@ -141,6 +143,7 @@ TEST_SUITE_INITIALIZE(suite_init) REGISTER_UMOCK_ALIAS_TYPE(STRING_HANDLE, void*); REGISTER_UMOCK_ALIAS_TYPE(XDA_HANDLE, void*); REGISTER_UMOCK_ALIAS_TYPE(IOTHUB_SECURITY_HANDLE, void*); + REGISTER_UMOCK_ALIAS_TYPE(BUFFER_HANDLE, void*); REGISTER_GLOBAL_MOCK_HOOK(gballoc_malloc, my_gballoc_malloc); REGISTER_GLOBAL_MOCK_FAIL_RETURN(gballoc_malloc, NULL); @@ -155,6 +158,8 @@ TEST_SUITE_INITIALIZE(suite_init) REGISTER_GLOBAL_MOCK_RETURN(get_time, TEST_TIME_VALUE); REGISTER_GLOBAL_MOCK_FAIL_RETURN(get_time, ((time_t)(-1))); + REGISTER_GLOBAL_MOCK_RETURNS(Azure_Base64_Decode, (BUFFER_HANDLE)0x1, NULL); + REGISTER_GLOBAL_MOCK_RETURN(STRING_c_str, TEST_STRING_VALUE); REGISTER_GLOBAL_MOCK_HOOK(STRING_delete, my_STRING_delete); REGISTER_GLOBAL_MOCK_HOOK(STRING_construct, my_STRING_construct); @@ -210,6 +215,12 @@ static void setup_IoTHubClient_Auth_CreateFromDeviceAuth_mocks(bool module_id, D static void setup_IoTHubClient_Auth_Create_mocks(bool device_key, bool module_id) { + if (device_key) + { + STRICT_EXPECTED_CALL(Azure_Base64_Decode(IGNORED_PTR_ARG)); + STRICT_EXPECTED_CALL(BUFFER_delete(IGNORED_PTR_ARG)); + } + STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); STRICT_EXPECTED_CALL(mallocAndStrcpy_s(IGNORED_PTR_ARG, DEVICE_ID)); if (module_id) @@ -246,11 +257,13 @@ static int should_skip_index(size_t current_index, const size_t skip_array[], si return result; } -/* Codes_SRS_IoTHub_Authorization_07_001: [if device_key or device_id is NULL IoTHubClient_Auth_Create, shall return NULL. ] */ +/* Tests_SRS_IoTHub_Authorization_07_001: [if device_key or device_id is NULL IoTHubClient_Auth_Create, shall return NULL. ] */ TEST_FUNCTION(IoTHubClient_Auth_Create_id_NULL_succeed) { //arrange umock_c_reset_all_calls(); + STRICT_EXPECTED_CALL(Azure_Base64_Decode(IGNORED_PTR_ARG)); + STRICT_EXPECTED_CALL(BUFFER_delete(IGNORED_PTR_ARG)); //act IOTHUB_AUTHORIZATION_HANDLE handle = IoTHubClient_Auth_Create(DEVICE_KEY, NULL, NULL, NULL); @@ -263,9 +276,9 @@ TEST_FUNCTION(IoTHubClient_Auth_Create_id_NULL_succeed) IoTHubClient_Auth_Destroy(handle); } -/* Codes_SRS_IoTHub_Authorization_07_002: [IoTHubClient_Auth_Create shall allocate a IOTHUB_AUTHORIZATION_HANDLE that is needed for subsequent calls. ] */ -/* Codes_SRS_IoTHub_Authorization_07_003: [ IoTHubClient_Auth_Create shall set the credential type to IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY. ] */ -/* Codes_SRS_IoTHub_Authorization_07_004: [ If successful IoTHubClient_Auth_Create shall return a IOTHUB_AUTHORIZATION_HANDLE value. ] */ +/* Tests_SRS_IoTHub_Authorization_07_002: [IoTHubClient_Auth_Create shall allocate a IOTHUB_AUTHORIZATION_HANDLE that is needed for subsequent calls. ] */ +/* Tests_SRS_IoTHub_Authorization_07_003: [ IoTHubClient_Auth_Create shall set the credential type to IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY. ] */ +/* Tests_SRS_IoTHub_Authorization_07_004: [ If successful IoTHubClient_Auth_Create shall return a IOTHUB_AUTHORIZATION_HANDLE value. ] */ TEST_FUNCTION(IoTHubClient_Auth_Create_succeed) { //arrange @@ -304,9 +317,9 @@ TEST_FUNCTION(IoTHubClient_Auth_Create_unknown_status_succeed) IoTHubClient_Auth_Destroy(handle); } -/* Codes_SRS_IoTHub_Authorization_07_002: [IoTHubClient_Auth_Create shall allocate a IOTHUB_AUTHORIZATION_HANDLE that is needed for subsequent calls. ] */ -/* Codes_SRS_IoTHub_Authorization_07_003: [ IoTHubClient_Auth_Create shall set the credential type to IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY. ] */ -/* Codes_SRS_IoTHub_Authorization_07_004: [ If successful IoTHubClient_Auth_Create shall return a IOTHUB_AUTHORIZATION_HANDLE value. ] */ +/* Tests_SRS_IoTHub_Authorization_07_002: [IoTHubClient_Auth_Create shall allocate a IOTHUB_AUTHORIZATION_HANDLE that is needed for subsequent calls. ] */ +/* Tests_SRS_IoTHub_Authorization_07_003: [ IoTHubClient_Auth_Create shall set the credential type to IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY. ] */ +/* Tests_SRS_IoTHub_Authorization_07_004: [ If successful IoTHubClient_Auth_Create shall return a IOTHUB_AUTHORIZATION_HANDLE value. ] */ TEST_FUNCTION(IoTHubClient_Auth_Create_device_key_NULL_succeed) { //arrange @@ -345,9 +358,9 @@ TEST_FUNCTION(IoTHubClient_Auth_Create_module_id_succeed) } -/* Codes_SRS_IoTHub_Authorization_07_002: [IoTHubClient_Auth_Create shall allocate a IOTHUB_AUTHORIZATION_HANDLE that is needed for subsequent calls. ] */ -/* Codes_SRS_IoTHub_Authorization_07_004: [ If successful IoTHubClient_Auth_Create shall return a IOTHUB_AUTHORIZATION_HANDLE value. ] */ -/* Codes_SRS_IoTHub_Authorization_07_020: [ else IoTHubClient_Auth_Create shall set the credential type to IOTHUB_CREDENTIAL_TYPE_SAS_TOKEN. ] */ +/* Tests_SRS_IoTHub_Authorization_07_002: [IoTHubClient_Auth_Create shall allocate a IOTHUB_AUTHORIZATION_HANDLE that is needed for subsequent calls. ] */ +/* Tests_SRS_IoTHub_Authorization_07_004: [ If successful IoTHubClient_Auth_Create shall return a IOTHUB_AUTHORIZATION_HANDLE value. ] */ +/* Tests_SRS_IoTHub_Authorization_07_020: [ else IoTHubClient_Auth_Create shall set the credential type to IOTHUB_CREDENTIAL_TYPE_SAS_TOKEN. ] */ TEST_FUNCTION(IoTHubClient_Auth_Create_with_sas_succeed) { //arrange @@ -370,7 +383,8 @@ TEST_FUNCTION(IoTHubClient_Auth_Create_with_sas_succeed) IoTHubClient_Auth_Destroy(handle); } -/* Codes_SRS_IoTHub_Authorization_07_019: [ On error IoTHubClient_Auth_Create shall return NULL. ] */ +/* Tests_SRS_IoTHub_Authorization_07_019: [ On error IoTHubClient_Auth_Create shall return NULL. ] */ +/* Tests_SRS_IoTHub_Authorization_21_021: [ If the provided key is not base64 encoded, IoTHubClient_Auth_Create shall return NULL. ] */ TEST_FUNCTION(IoTHubClient_Auth_Create_fail) { //arrange @@ -387,6 +401,11 @@ TEST_FUNCTION(IoTHubClient_Auth_Create_fail) size_t count = umock_c_negative_tests_call_count(); for (size_t index = 0; index < count; index++) { + if (index == 1) + { + continue; + } + umock_c_negative_tests_reset(); umock_c_negative_tests_fail_call(index); @@ -469,7 +488,7 @@ TEST_FUNCTION(IoTHubClient_Auth_CreateFromDeviceAuth_fail) } #endif -/* Codes_SRS_IoTHub_Authorization_07_005: [ if handle is NULL IoTHubClient_Auth_Destroy shall do nothing. ] */ +/* Tests_SRS_IoTHub_Authorization_07_005: [ if handle is NULL IoTHubClient_Auth_Destroy shall do nothing. ] */ TEST_FUNCTION(IoTHubClient_Auth_Destroy_handle_NULL_succeed) { //arrange @@ -483,7 +502,7 @@ TEST_FUNCTION(IoTHubClient_Auth_Destroy_handle_NULL_succeed) //cleanup } -/* Codes_SRS_IoTHub_Authorization_07_006: [ IoTHubClient_Auth_Destroy shall free all resources associated with the IOTHUB_AUTHORIZATION_HANDLE handle. ] */ +/* Tests_SRS_IoTHub_Authorization_07_006: [ IoTHubClient_Auth_Destroy shall free all resources associated with the IOTHUB_AUTHORIZATION_HANDLE handle. ] */ TEST_FUNCTION(IoTHubClient_Auth_Destroy_succeed) { //arrange @@ -559,7 +578,7 @@ TEST_FUNCTION(IoTHubClient_Auth_Set_x509_Type_no_x509_succeed) } -/* Codes_SRS_IoTHub_Authorization_07_007: [ if handle is NULL IoTHub_Auth_Get_Credential_Type shall return IOTHUB_CREDENTIAL_TYPE_UNKNOWN. ] */ +/* Tests_SRS_IoTHub_Authorization_07_007: [ if handle is NULL IoTHub_Auth_Get_Credential_Type shall return IOTHUB_CREDENTIAL_TYPE_UNKNOWN. ] */ TEST_FUNCTION(IoTHubClient_Auth_Get_Credential_Type_handle_NULL) { //arrange @@ -574,7 +593,7 @@ TEST_FUNCTION(IoTHubClient_Auth_Get_Credential_Type_handle_NULL) //cleanup } -/* Codes_SRS_IoTHub_Authorization_07_008: [ IoTHub_Auth_Get_Credential_Type shall return the credential type that is set upon creation. ] */ +/* Tests_SRS_IoTHub_Authorization_07_008: [ IoTHub_Auth_Get_Credential_Type shall return the credential type that is set upon creation. ] */ TEST_FUNCTION(IoTHubClient_Auth_Get_Credential_Type_succeed) { //arrange @@ -741,7 +760,7 @@ TEST_FUNCTION(IoTHubClient_Auth_Get_x509_info_cred_type_fails) #endif -/* Codes_SRS_IoTHub_Authorization_07_009: [ if handle or scope are NULL, IoTHubClient_Auth_Get_ConnString shall return NULL. ] */ +/* Tests_SRS_IoTHub_Authorization_07_009: [ if handle or scope are NULL, IoTHubClient_Auth_Get_ConnString shall return NULL. ] */ TEST_FUNCTION(IoTHubClient_Auth_Get_ConnString_handle_NULL) { //arrange @@ -756,7 +775,7 @@ TEST_FUNCTION(IoTHubClient_Auth_Get_ConnString_handle_NULL) //cleanup } -/* Codes_SRS_IoTHub_Authorization_07_009: [ if handle or scope are NULL, IoTHubClient_Auth_Get_ConnString shall return NULL. ] */ +/* Tests_SRS_IoTHub_Authorization_07_009: [ if handle or scope are NULL, IoTHubClient_Auth_Get_ConnString shall return NULL. ] */ TEST_FUNCTION(IoTHubClient_Auth_Get_ConnString_scope_NULL_fail) { //arrange @@ -775,9 +794,9 @@ TEST_FUNCTION(IoTHubClient_Auth_Get_ConnString_scope_NULL_fail) } #ifdef USE_PROV_MODULE -/* Codes_SRS_IoTHub_Authorization_07_010: [ IoTHubClient_Auth_Get_ConnString shall construct the expiration time using the expire_time. ] */ -/* Codes_SRS_IoTHub_Authorization_07_011: [ IoTHubClient_Auth_Get_ConnString shall call SASToken_CreateString to construct the sas token. ] */ -/* Codes_SRS_IoTHub_Authorization_07_012: [ On success IoTHubClient_Auth_Get_ConnString shall allocate and return the sas token in a char*. ] */ +/* Tests_SRS_IoTHub_Authorization_07_010: [ IoTHubClient_Auth_Get_ConnString shall construct the expiration time using the expire_time. ] */ +/* Tests_SRS_IoTHub_Authorization_07_011: [ IoTHubClient_Auth_Get_ConnString shall call SASToken_CreateString to construct the sas token. ] */ +/* Tests_SRS_IoTHub_Authorization_07_012: [ On success IoTHubClient_Auth_Get_ConnString shall allocate and return the sas token in a char*. ] */ TEST_FUNCTION(IoTHubClient_Auth_Get_ConnString_device_auth_succeed) { //arrange @@ -845,7 +864,7 @@ TEST_FUNCTION(IoTHubClient_Auth_Get_ModuleId_succeed) } -/* Codes_SRS_IoTHub_Authorization_07_020: [ If any error is encountered IoTHubClient_Auth_Get_ConnString shall return NULL. ] */ +/* Tests_SRS_IoTHub_Authorization_07_020: [ If any error is encountered IoTHubClient_Auth_Get_ConnString shall return NULL. ] */ TEST_FUNCTION(IoTHubClient_Auth_Get_ConnString_fail) { //arrange @@ -884,7 +903,7 @@ TEST_FUNCTION(IoTHubClient_Auth_Get_ConnString_fail) umock_c_negative_tests_deinit(); } -/* Codes_SRS_IoTHub_Authorization_07_013: [ if handle is NULL, IoTHubClient_Auth_Get_DeviceId shall return NULL. ] */ +/* Tests_SRS_IoTHub_Authorization_07_013: [ if handle is NULL, IoTHubClient_Auth_Get_DeviceId shall return NULL. ] */ TEST_FUNCTION(IoTHubClient_Auth_Get_DeviceId_handle_NULL) { //arrange @@ -899,7 +918,7 @@ TEST_FUNCTION(IoTHubClient_Auth_Get_DeviceId_handle_NULL) //cleanup } -/* Codes_SRS_IoTHub_Authorization_07_014: [ IoTHubClient_Auth_Get_DeviceId shall return the device_id specified upon creation. ] */ +/* Tests_SRS_IoTHub_Authorization_07_014: [ IoTHubClient_Auth_Get_DeviceId shall return the device_id specified upon creation. ] */ TEST_FUNCTION(IoTHubClient_Auth_Get_DeviceId_succeed) { //arrange @@ -918,7 +937,7 @@ TEST_FUNCTION(IoTHubClient_Auth_Get_DeviceId_succeed) IoTHubClient_Auth_Destroy(handle); } -/* Codes_SRS_IoTHub_Authorization_07_022: [ if handle is NULL, IoTHubClient_Auth_Get_DeviceKey shall return NULL. ] */ +/* Tests_SRS_IoTHub_Authorization_07_022: [ if handle is NULL, IoTHubClient_Auth_Get_DeviceKey shall return NULL. ] */ TEST_FUNCTION(IoTHubClient_Auth_Get_DeviceKey_handle_NULL) { //arrange @@ -933,7 +952,7 @@ TEST_FUNCTION(IoTHubClient_Auth_Get_DeviceKey_handle_NULL) //cleanup } -/* Codes_SRS_IoTHub_Authorization_07_023: [ IoTHubClient_Auth_Get_DeviceKey shall return the device_key specified upon creation. ] */ +/* Tests_SRS_IoTHub_Authorization_07_023: [ IoTHubClient_Auth_Get_DeviceKey shall return the device_key specified upon creation. ] */ TEST_FUNCTION(IoTHubClient_Auth_Get_Devicekey_succeed) { //arrange @@ -952,7 +971,7 @@ TEST_FUNCTION(IoTHubClient_Auth_Get_Devicekey_succeed) IoTHubClient_Auth_Destroy(handle); } -/* Codes_SRS_IoTHub_Authorization_07_015: [ if handle is NULL, IoTHubClient_Auth_Is_SasToken_Valid shall return false. ] */ +/* Tests_SRS_IoTHub_Authorization_07_015: [ if handle is NULL, IoTHubClient_Auth_Is_SasToken_Valid shall return false. ] */ TEST_FUNCTION(IoTHubClient_Auth_Is_SasToken_Valid_handle_NULL_fail) { //arrange @@ -967,7 +986,7 @@ TEST_FUNCTION(IoTHubClient_Auth_Is_SasToken_Valid_handle_NULL_fail) //cleanup } -/* Codes_SRS_IoTHub_Authorization_07_018: [ otherwise IoTHubClient_Auth_Is_SasToken_Valid shall return the value returned by SASToken_Validate. ] */ +/* Tests_SRS_IoTHub_Authorization_07_018: [ otherwise IoTHubClient_Auth_Is_SasToken_Valid shall return the value returned by SASToken_Validate. ] */ TEST_FUNCTION(IoTHubClient_Auth_Is_SasToken_Valid_succeed) { //arrange @@ -985,7 +1004,7 @@ TEST_FUNCTION(IoTHubClient_Auth_Is_SasToken_Valid_succeed) IoTHubClient_Auth_Destroy(handle); } -/* Codes_SRS_IoTHub_Authorization_07_018: [ otherwise IoTHubClient_Auth_Is_SasToken_Valid shall return the value returned by SASToken_Validate. ] */ +/* Tests_SRS_IoTHub_Authorization_07_018: [ otherwise IoTHubClient_Auth_Is_SasToken_Valid shall return the value returned by SASToken_Validate. ] */ TEST_FUNCTION(IoTHubClient_Auth_Is_SasToken_Valid_sas_token_succeed) { //arrange