diff --git a/CHANGELOG.md b/CHANGELOG.md index c0295c1..5bd2a9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Security: Mutual Authentication (mTLS or two way TLS) - Rename command line options for MTLS cert and Key - Update to use nanomsg v. 1.1.4 +- requestNewAuthToken will clear the token if it fails. ## [1.0.2] - 2019-02-08 - Refactored connection.c and updated corresponding unit tests diff --git a/src/auth_token.c b/src/auth_token.c index ce24df9..d785bf8 100644 --- a/src/auth_token.c +++ b/src/auth_token.c @@ -66,17 +66,11 @@ int requestNewAuthToken(char *newToken, size_t len, int r_count) struct token_data data; data.size = 0; + data.data = newToken; curl = curl_easy_init(); if(curl) { - //this memory will be dynamically grown by write call back fn as required - data.data = (char *) malloc(sizeof(char) * 1); - if(NULL == data.data) - { - ParodusError("Failed to allocate memory.\n"); - return -1; - } data.data[0] = '\0'; createCurlheader(mac_header, serial_header, uuid_header, transaction_uuid, list, &headers_list); @@ -137,11 +131,8 @@ int requestNewAuthToken(char *newToken, size_t len, int r_count) { ParodusError("curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); curl_easy_cleanup(curl); - if(data.data) - { - free(data.data); - data.data = NULL; - } + data.size = 0; + memset (data.data, 0, len); return -1; } else @@ -149,19 +140,15 @@ int requestNewAuthToken(char *newToken, size_t len, int r_count) if(response_code == 200) { ParodusInfo("cURL success\n"); - strncpy(newToken, data.data, len); } } - if(data.data) - { - free(data.data); - data.data = NULL; - } curl_easy_cleanup(curl); } else { ParodusError("curl init failure\n"); + data.size = 0; + memset (data.data, 0, len); return -1; } @@ -179,6 +166,7 @@ void getAuthToken(ParodusCfg *cfg) int status = -1; int retry_count = 0; + memset (cfg->webpa_auth_token, 0, sizeof(cfg->webpa_auth_token)); if( cfg->hw_mac != NULL && strlen(cfg->hw_mac) !=0 ) { if( cfg->client_cert_path !=NULL && strlen(cfg->client_cert_path) !=0 ) @@ -225,28 +213,23 @@ void getAuthToken(ParodusCfg *cfg) */ size_t write_callback_fn(void *buffer, size_t size, size_t nmemb, struct token_data *data) { + ParodusCfg *cfg; + size_t max_data_size = sizeof (cfg->webpa_auth_token); size_t index = data->size; size_t n = (size * nmemb); - char* tmp; - data->size += (size * nmemb); + data->size += n; - tmp = realloc(data->data, data->size + 1); /* +1 for '\0' */ - - if(tmp) { - data->data = tmp; - } else { - if(data->data) { - free(data->data); - } - ParodusError("Failed to allocate memory for data\n"); + if (data->size >= max_data_size) { + ParodusError("Auth token data overruns buffer\n"); + data->size = 0; return 0; } memcpy((data->data + index), buffer, n); data->data[data->size] = '\0'; - return size * nmemb; + return n; } /* @brief function to generate random uuid. diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a1195a4..9117421 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -193,6 +193,17 @@ target_link_libraries (test_auth_token -lcmocka -Wl,--no-as-needed -lcimplog -lcjson -lcjwt -ltrower-base64 -lssl -lcrypto -lrt -lm -lcurl -luuid ) + +#------------------------------------------------------------------------------- +# test_auth_token_more +#------------------------------------------------------------------------------- +add_test(NAME test_auth_token_more COMMAND ${MEMORY_CHECK} ./test_auth_token_more) +add_executable(test_auth_token_more test_auth_token_more.c ../src/config.c ../src/auth_token.c ../src/string_helpers.c) +target_link_libraries (test_auth_token_more -lcmocka + -Wl,--no-as-needed -lcimplog + -lcjson -lcjwt -ltrower-base64 -lssl -lcrypto -lrt -lm -lcurl -luuid +) + #------------------------------------------------------------------------------- # test_crud_interface #------------------------------------------------------------------------------- diff --git a/tests/test_auth_token.c b/tests/test_auth_token.c index d73d73c..38f3b04 100644 --- a/tests/test_auth_token.c +++ b/tests/test_auth_token.c @@ -40,11 +40,19 @@ typedef enum { CURLINFO_TOTAL_TIME } CURLINFO; +struct token_data test_data; + int curl_easy_perform(CURL *curl) { UNUSED(curl); + char *msg = "response"; + int rtn; + function_called(); - return (int) mock(); + rtn = (int) mock(); + if (0 == rtn) + write_callback_fn (msg, 1, strlen(msg), &test_data); + return rtn; } int curl_easy_getinfo(CURL *curl, CURLINFO CURLINFO_RESPONSE_CODE, long response_code) @@ -67,6 +75,7 @@ void getAuthToken_Null() getAuthToken(&cfg); set_parodus_cfg(&cfg); assert( cfg.client_cert_path == NULL); + assert_int_equal (0, (int) cfg.webpa_auth_token[0]); } void getAuthToken_MacNull() @@ -77,8 +86,10 @@ void getAuthToken_MacNull() getAuthToken(&cfg); set_parodus_cfg(&cfg); assert( cfg.client_cert_path == NULL); + assert_int_equal (0, (int) cfg.webpa_auth_token[0]); } +#if 0 void test_requestNewAuthToken_init_fail () { char token[32]; @@ -106,7 +117,7 @@ void test_requestNewAuthToken_init_fail () assert_int_equal (output, -1); free(cfg.token_server_url); } - +#endif void test_requestNewAuthToken_failure () { @@ -121,6 +132,8 @@ void test_requestNewAuthToken_failure () parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac)); set_parodus_cfg(&cfg); + test_data.size = 0; + test_data.data = token; will_return (curl_easy_perform, -1); expect_function_calls (curl_easy_perform, 1); @@ -132,6 +145,7 @@ void test_requestNewAuthToken_failure () requestNewAuthToken (token, sizeof(token), 2); assert_int_equal (output, -1); + assert_int_equal (0, (int) token[0]); free(cfg.token_server_url); } @@ -150,6 +164,8 @@ void test_requestNewAuthToken () parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac)); set_parodus_cfg(&cfg); + test_data.size = 0; + test_data.data = token; will_return (curl_easy_perform, 0); expect_function_calls (curl_easy_perform, 1); will_return (curl_easy_getinfo, 0); @@ -160,6 +176,7 @@ void test_requestNewAuthToken () output = requestNewAuthToken (token, sizeof(token), 1); assert_int_equal (output, 0); + assert_string_equal (token, "response"); free(cfg.token_server_url); } @@ -197,6 +214,8 @@ void test_getAuthToken () expect_function_calls (curl_easy_getinfo, 1); /* To test curl success case */ + test_data.size = 0; + test_data.data = cfg.webpa_auth_token; will_return (curl_easy_perform, 0); expect_function_calls (curl_easy_perform, 1); @@ -207,7 +226,7 @@ void test_getAuthToken () expect_function_calls (curl_easy_getinfo, 1); getAuthToken(&cfg); - + assert_string_equal (cfg.webpa_auth_token, "response"); free(cfg.client_cert_path); free(cfg.token_server_url); } @@ -224,6 +243,7 @@ void test_getAuthTokenFailure () parStrncpy(cfg.hw_serial_number, "Fer23u948590", sizeof(cfg.hw_serial_number)); parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac)); set_parodus_cfg(&cfg); + will_return (curl_easy_perform, -1); expect_function_calls (curl_easy_perform, 1); @@ -261,20 +281,35 @@ void test_getAuthTokenFailure () void test_write_callback_fn () { - void *buffer; - size_t size = 1; - size_t nmemb =8; + ParodusCfg *cfg; + size_t max_data_size = sizeof (cfg->webpa_auth_token); + char *buffer1 = "response1"; + size_t buf1len = strlen(buffer1); + char *buffer2 = "R2"; + size_t buf2len = strlen(buffer2); + char buffer3[max_data_size]; int out_len=0; struct token_data data; data.size = 0; - buffer = strdup("response"); - data.data = (char *) malloc(sizeof(char) * 5); + data.data = (char *) malloc(max_data_size); data.data[0] = '\0'; - out_len = write_callback_fn(buffer, size, nmemb, &data); - assert_string_equal(data.data, buffer); - assert_int_equal( out_len, strlen(buffer)); + out_len = write_callback_fn(buffer1, 1, buf1len, &data); + assert_string_equal(data.data, buffer1); + assert_int_equal (out_len, buf1len); + assert_int_equal (data.size, buf1len); + + out_len = write_callback_fn(buffer2, 1, buf2len, &data); + assert_string_equal(data.data, "response1R2"); + assert_int_equal (out_len, buf2len); + assert_int_equal (data.size, buf1len+buf2len); + + memset (buffer3, 'x', max_data_size); + out_len = write_callback_fn(buffer3, 1, max_data_size, &data); + assert_int_equal (out_len, 0); + assert_int_equal (data.size, 0); + free(data.data); } @@ -285,14 +320,14 @@ void test_write_callback_fn () int main(void) { const struct CMUnitTest tests[] = { + cmocka_unit_test(test_write_callback_fn), cmocka_unit_test(test_requestNewAuthToken), - cmocka_unit_test(test_requestNewAuthToken_init_fail), + // cmocka_unit_test(test_requestNewAuthToken_init_fail), cmocka_unit_test(test_requestNewAuthToken_failure), cmocka_unit_test(getAuthToken_Null), cmocka_unit_test(getAuthToken_MacNull), cmocka_unit_test(test_getAuthToken), cmocka_unit_test(test_getAuthTokenFailure), - cmocka_unit_test(test_write_callback_fn), }; return cmocka_run_group_tests(tests, NULL, NULL); diff --git a/tests/test_auth_token_more.c b/tests/test_auth_token_more.c new file mode 100644 index 0000000..343164e --- /dev/null +++ b/tests/test_auth_token_more.c @@ -0,0 +1,109 @@ +/** + * Copyright 2010-2016 Comcast Cable Communications Management, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../src/config.h" +#include "../src/auth_token.h" +#include "../src/ParodusInternal.h" + +extern int requestNewAuthToken(char *newToken, size_t len, int r_count); + +/*----------------------------------------------------------------------------*/ +/* Mocks */ +/*----------------------------------------------------------------------------*/ +typedef void CURL; + +typedef enum { + CURLINFO_RESPONSE_CODE = 2, + CURLINFO_TOTAL_TIME +} CURLINFO; + +struct token_data test_data; + +CURL *curl_easy_init () +{ + function_called(); + return (CURL *) mock(); +} + +int curl_easy_perform(CURL *curl) +{ + UNUSED(curl); + char *msg = "response"; + int rtn; + + function_called(); + rtn = (int) mock(); + if (0 == rtn) + write_callback_fn (msg, 1, strlen(msg), &test_data); + return rtn; +} + +int curl_easy_getinfo(CURL *curl, CURLINFO CURLINFO_RESPONSE_CODE, long response_code) +{ + UNUSED(curl); + UNUSED(CURLINFO_RESPONSE_CODE); + UNUSED(response_code); + function_called(); + return (int) mock(); +} +/*----------------------------------------------------------------------------*/ +/* Tests */ +/*----------------------------------------------------------------------------*/ +void test_requestNewAuthToken_init_fail () +{ + char token[32]; + ParodusCfg cfg; + int output = -1; + memset(&cfg,0,sizeof(cfg)); + + cfg.token_server_url = strdup("https://dev.comcast.net/token"); + parStrncpy(cfg.cert_path , "/etc/ssl/certs/ca-certificates.crt", sizeof(cfg.cert_path)); + parStrncpy(cfg.hw_serial_number, "Fer23u948590", sizeof(cfg.hw_serial_number)); + parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac)); + + set_parodus_cfg(&cfg); + + will_return (curl_easy_init, NULL); + expect_function_calls (curl_easy_init, 1); + + requestNewAuthToken (token, sizeof(token), 2); + assert_int_equal (output, -1); + assert_int_equal (0, (int) token[0]); + free(cfg.token_server_url); +} + +/*----------------------------------------------------------------------------*/ +/* External Functions */ +/*----------------------------------------------------------------------------*/ + +int main(void) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_requestNewAuthToken_init_fail) + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +}