diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c335200..aa50b37b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -297,6 +297,10 @@ if (WAN_FAILOVER_SUPPORTED) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWAN_FAILOVER_SUPPORTED ") endif (WAN_FAILOVER_SUPPORTED) +if (PARODUS_SECERT_ENABLE) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPARODUS_SECERT_ENABLE ") +endif (PARODUS_SECERT_ENABLE) + link_directories ( ${LIBRARY_DIR} ${COMMON_LIBRARY_DIR} ${LIBRARY_DIR64} ) add_subdirectory(src) if (BUILD_TESTING) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8b7af651..031e55b8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,6 +17,10 @@ set(SOURCES main.c mutex.c networking.c nopoll_helpers.c heartBeat.c nopoll_hand upstream.c downstream.c thread_tasks.c partners_check.c token.c event_handler.c crud_interface.c crud_tasks.c crud_internal.c close_retry.c auth_token.c privilege.c) +if (NOT BUILD_YOCTO) +set(SOURCES ${SOURCES} rdkconfig_generic.c) +endif (NOT BUILD_YOCTO) + if (ENABLE_SESHAT) set(SOURCES ${SOURCES} seshat_interface.c) else() @@ -65,4 +69,8 @@ endif (ENABLE_SESHAT) if (ENABLE_WEBCFGBIN) target_link_libraries (parodus -lrbus) endif (ENABLE_WEBCFGBIN) + +if (PARODUS_SECERT_ENABLE) +target_link_libraries (parodus -lrdkconfig -lsecure_wrapper) +endif (PARODUS_SECERT_ENABLE) install (TARGETS parodus DESTINATION bin) diff --git a/src/auth_token.c b/src/auth_token.c index 18468e84..79f6e196 100644 --- a/src/auth_token.c +++ b/src/auth_token.c @@ -32,6 +32,14 @@ #include #include +#ifdef PARODUS_SECERT_ENABLE +# ifndef BUILD_YOCTO +#include "rdkconfig_generic.h" +#else +#include "rdkconfig.h" +# endif +#endif + #define MAX_BUF_SIZE 256 #define CURL_TIMEOUT_SEC 25L #define MAX_CURL_RETRY_COUNT 3 @@ -48,6 +56,59 @@ int getGlobalResponseCode() { return g_response_code; } + +#ifdef PARODUS_SECERT_ENABLE +void getConfigPwd(uint8_t **pPasswd, size_t *pPasswdSize) +{ + uint8_t *temp=NULL; + size_t tempSize; + int index = -1; + + if(rdkconfig_get(&temp, &tempSize, get_parodus_cfg()->ssl_reference_name)) + { + ParodusError("Error in getting passcode\n"); + return; + } + else + { + if (temp != NULL) + { + index = strcspn(temp, "\t\r\n"); + if((index > 0) && (index <= tempSize)) + { + temp[index] = '\0'; + } + else + { + temp[tempSize] = '\0'; + } + if(strcmp(get_parodus_cfg()->ssl_reference_name,"/tmp/.cfgStaticxpki") == 0) + tempSize++; + + *pPasswdSize = tempSize; + *pPasswd = malloc(tempSize); + if(*pPasswd != NULL) + { + memcpy(*pPasswd, temp, tempSize); + ParodusInfo("Passcode decoded successfully\n"); + } + else + { + ParodusError("Failed to allocate memory for Passcode\n"); + } + + if (rdkconfig_free(&temp, tempSize) == RDKCONFIG_FAIL) + { + ParodusError("%s, Memory deallocation failed \n",__FUNCTION__); + } + } + else + { + ParodusError("Memory allocation failed in rdkconfig_get\n"); + } + } +} +#endif /* * @brief Initialize curl object with required options. create newToken using libcurl. * @param[out] newToken auth token string obtained from JWT curl response @@ -67,6 +128,8 @@ int requestNewAuthToken(char *newToken, size_t len, int r_count) char webpa_interface[64]={'\0'}; double total; + uint8_t *pPasswd=NULL; + size_t pPasswdSize; struct token_data data; data.size = 0; data.data = newToken; @@ -111,6 +174,32 @@ int requestNewAuthToken(char *newToken, size_t len, int r_count) curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_WHATEVER); } +#ifdef PARODUS_SECERT_ENABLE + /* Set the SSL engine and SSL certificate type for the CURL request */ + if(get_parodus_cfg()->ssl_engine != NULL && strcmp(get_parodus_cfg()->ssl_engine, "NA") != 0) + { + curl_easy_setopt(curl, CURLOPT_SSLENGINE, get_parodus_cfg()->ssl_engine); + } + + if(get_parodus_cfg()->ssl_cert_type != NULL) + { + curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, get_parodus_cfg()->ssl_cert_type); + } + + if((get_parodus_cfg()->ssl_cert_type != NULL) && (strcmp(get_parodus_cfg()->ssl_cert_type, "P12") == 0)) + { + ParodusInfo("Getting passcode for : %s\n",get_parodus_cfg()->client_cert_path); + getConfigPwd(&pPasswd, &pPasswdSize); + if(pPasswd != NULL && pPasswdSize > 0) + { + curl_easy_setopt(curl, CURLOPT_KEYPASSWD, pPasswd); + } + else + { + ParodusError("Failed to get pPasswd for pk12\n"); + } + } +#endif /* set the cert for client authentication */ curl_easy_setopt(curl, CURLOPT_SSLCERT, get_parodus_cfg()->client_cert_path); @@ -149,12 +238,30 @@ int requestNewAuthToken(char *newToken, size_t len, int r_count) { ParodusError("Failed response from auth token server %s\n", data.data); curl_easy_cleanup(curl); + #ifdef PARODUS_SECERT_ENABLE + if(pPasswd != NULL && pPasswdSize > 0) + { + if (rdkconfig_free(&pPasswd, pPasswdSize) == RDKCONFIG_FAIL) + { + ParodusError("%s, Memory deallocation failed \n",__FUNCTION__); + } + } + #endif data.size = 0; memset (data.data, 0, len); return -1; } } curl_easy_cleanup(curl); + #ifdef PARODUS_SECERT_ENABLE + if(pPasswd != NULL && pPasswdSize > 0) + { + if (rdkconfig_free(&pPasswd, pPasswdSize) == RDKCONFIG_FAIL) + { + ParodusError("%s, Memory deallocation failed \n",__FUNCTION__); + } + } + #endif } else { diff --git a/src/config.c b/src/config.c index fac309e5..9ad5f689 100644 --- a/src/config.c +++ b/src/config.c @@ -451,6 +451,9 @@ int parseCommandLine(int argc,char **argv,ParodusCfg * cfg) {"force-ipv6", no_argument, 0, '6'}, {"boot-time-retry-wait", required_argument, 0, 'w'}, {"client-cert-path", required_argument, 0, 'P'}, + {"ssl-engine", required_argument, 0, 'E'}, + {"ssl-cert-type", required_argument, 0, 'T'}, + {"ssl-reference-name", required_argument, 0, 'N'}, {"token-server-url", required_argument, 0, 'U'}, {"crud-config-file", required_argument, 0, 'C'}, {"connection-health-file", required_argument, 0, 'S'}, @@ -478,6 +481,9 @@ int parseCommandLine(int argc,char **argv,ParodusCfg * cfg) cfg->connection_health_file = NULL; cfg->close_reason_file = NULL; cfg->client_cert_path = NULL; + cfg->ssl_engine = NULL; + cfg->ssl_cert_type = NULL; + cfg->ssl_reference_name = NULL; cfg->token_server_url = NULL; cfg->cloud_status = NULL; cfg->cloud_disconnect = NULL; @@ -491,7 +497,7 @@ int parseCommandLine(int argc,char **argv,ParodusCfg * cfg) /* getopt_long stores the option index here. */ int option_index = 0; c = getopt_long (argc, argv, - "m:s:f:d:r:n:b:u:t:o:i:l:q:p:e:D:j:a:k:c:T:w:J:46:C:S:R:K:M", + "m:s:f:d:r:n:b:u:t:o:i:l:q:p:e:D:j:a:k:c:E:T:N:w:J:46:C:S:R:K:M", long_options, &option_index); /* Detect the end of the options. */ @@ -660,6 +666,21 @@ int parseCommandLine(int argc,char **argv,ParodusCfg * cfg) ParodusInfo("client_cert_path is %s\n", cfg->client_cert_path); break; + case 'E': + cfg->ssl_engine = strdup(optarg); + ParodusInfo("ssl_engine is %s\n",cfg->ssl_engine); + break; + + case 'T': + cfg->ssl_cert_type = strdup(optarg); + ParodusInfo("ssl_cert_type is %s\n",cfg->ssl_cert_type); + break; + + case 'N': + cfg->ssl_reference_name = strdup(optarg); + ParodusInfo("ssl_reference_name is %s\n",cfg->ssl_reference_name); + break; + case 'U': cfg->token_server_url = strdup(optarg); ParodusInfo("token_server_url is %s\n", cfg->token_server_url); @@ -752,6 +773,21 @@ void free_cfg(ParodusCfg *cfg) free(cfg->client_cert_path); cfg->client_cert_path = NULL; } + if(cfg->ssl_engine != NULL) + { + free(cfg->ssl_engine); + cfg->ssl_engine = NULL; + } + if(cfg->ssl_cert_type != NULL) + { + free(cfg->ssl_cert_type); + cfg->ssl_cert_type = NULL; + } + if(cfg->ssl_reference_name != NULL) + { + free(cfg->ssl_reference_name); + cfg->ssl_reference_name = NULL; + } if(cfg->crud_config_file != NULL) { free(cfg->crud_config_file); @@ -811,6 +847,9 @@ void setDefaultValuesToCfg(ParodusCfg *cfg) cfg->connection_health_file = NULL; cfg->close_reason_file = NULL; cfg->client_cert_path = NULL; + cfg->ssl_engine = NULL; + cfg->ssl_cert_type = NULL; + cfg->ssl_reference_name = NULL; cfg->token_server_url = NULL; #ifdef FEATURE_DNS_QUERY cfg->record_jwt_file = NULL; @@ -1002,6 +1041,33 @@ void loadParodusCfg(ParodusCfg * config,ParodusCfg *cfg) ParodusPrint("client_cert_path is NULL. set to empty\n"); } + if(config->ssl_engine != NULL) + { + cfg->ssl_engine = strdup(config->ssl_engine); + } + else + { + ParodusPrint("ssl_engine is NULL. set to empty\n"); + } + + if(config->ssl_cert_type != NULL) + { + cfg->ssl_cert_type = strdup(config->ssl_cert_type); + } + else + { + ParodusPrint("ssl_cert_type is NULL. set to empty\n"); + } + + if(config->ssl_reference_name != NULL) + { + cfg->ssl_reference_name = strdup(config->ssl_reference_name); + } + else + { + ParodusPrint("ssl_reference_name is NULL. set to empty\n"); + } + if(config->token_server_url != NULL) { cfg->token_server_url = strdup(config->token_server_url); diff --git a/src/config.h b/src/config.h index be8cba3c..ed509dfd 100644 --- a/src/config.h +++ b/src/config.h @@ -104,6 +104,9 @@ typedef struct char token_acquisition_script[64]; char token_read_script[64]; char *client_cert_path; + char *ssl_engine; + char *ssl_cert_type; + char *ssl_reference_name; char *token_server_url; char *connection_health_file; char *close_reason_file; diff --git a/src/rdkconfig_generic.c b/src/rdkconfig_generic.c new file mode 100644 index 00000000..e490191e --- /dev/null +++ b/src/rdkconfig_generic.c @@ -0,0 +1,50 @@ +/** + * Copyright 2024 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. + * + */ +/** + * @file rdkconfig_generic.c + * + * @description This file is to fetch authorization token during parodus cloud connection. + * + */ + +#include +#include + +#include "rdkconfig_generic.h" +#include "parodus_log.h" + +int rdkconfig_get( uint8_t **buf, size_t *buffsize, const char *reference ) +{ + /* This is stub function, No need implemetation */ + ParodusInfo("Inside rdkconfig_get stub function.\n"); + return RDKCONFIG_OK; +} + +int rdkconfig_set( const char *reference, uint8_t *buf, size_t buffsize ) +{ + /* This is stub function, No need implemetation */ + ParodusInfo("Inside rdkconfig_set stub function.\n"); + return RDKCONFIG_OK; +} + +int rdkconfig_free( uint8_t **buf, size_t buffsize ) +{ + ParodusInfo("Inside rdkconfig_free stub function.\n"); + free(*buf ); + *buf = NULL; + return RDKCONFIG_OK; +} diff --git a/src/rdkconfig_generic.h b/src/rdkconfig_generic.h new file mode 100644 index 00000000..24cbab15 --- /dev/null +++ b/src/rdkconfig_generic.h @@ -0,0 +1,47 @@ +/** + * Copyright 2024 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. + * + */ +/** + * @file partners_check.h + * + * @description This describes functions to validate partner_id. + * + */ + +#ifndef _RDKCONFIG_GENERIC_H_ +#define _RDKCONFIG_GENERIC_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define RDKCONFIG_OK 0 +#define RDKCONFIG_FAIL 1 + +int rdkconfig_get( uint8_t **buf, size_t *buffsize, const char *reference ); + +int rdkconfig_set( const char *reference, uint8_t *buf, size_t buffsize ); + +int rdkconfig_free( uint8_t **buf, size_t buffsize ); + +#ifdef __cplusplus +} +#endif + +#endif /* _RDKCONFIG_GENERIC_H_ */