From 506ef3fd7f8017adba2b77967b78328c1bf41b18 Mon Sep 17 00:00:00 2001 From: Alex Kozyrev Date: Mon, 21 Jan 2019 11:52:51 -0500 Subject: [PATCH] MTCE: reading BMC passwords from Barbican secret storage. Use Openstack Barbican API to retrieve BMC passwords stored by SysInv. See SysInv commit for details on how to write password to Barbican. MTCE is going to find corresponding secret by host uuid and retrieve secret payload associated with it. mtcSecretApi_get is used to find secret reference, based on a hostname. mtcSecretApi_read is used to read a password using the reference found on a prevoius step. Also, did a little cleanup and removed old unused token handling code. Depends-On: I7102a9662f3757c062ab310737f4ba08379d0100 Change-Id: I66011dc95bb69ff536bd5888c08e3987bd666082 Story: 2003108 Task: 27700 Signed-off-by: Alex Kozyrev --- devstack/lib/stx-metal | 2 + mtce-common/centos/mtce-common.spec | 1 + mtce-common/src/common/Makefile | 2 + mtce-common/src/common/hostUtil.cpp | 8 + mtce-common/src/common/hostUtil.h | 1 + mtce-common/src/common/httpUtil.cpp | 124 ++++---- mtce-common/src/common/httpUtil.h | 52 +++- mtce-common/src/common/jsonUtil.cpp | 74 +++++ mtce-common/src/common/jsonUtil.h | 67 ++++- mtce-common/src/common/logMacros.h | 5 +- mtce-common/src/common/nodeBase.h | 2 +- mtce-common/src/common/nodeUtil.cpp | 67 ----- mtce-common/src/common/nodeUtil.h | 11 +- mtce-common/src/common/secretUtil.cpp | 348 +++++++++++++++++++++++ mtce-common/src/common/secretUtil.h | 63 ++++ mtce-common/src/common/tokenUtil.cpp | 93 +++--- mtce-common/src/common/tokenUtil.h | 4 +- mtce-common/src/daemon/daemon_common.h | 6 + mtce-common/src/daemon/daemon_config.cpp | 26 +- mtce/src/common/nodeClass.cpp | 38 ++- mtce/src/common/nodeClass.h | 13 +- mtce/src/heartbeat/Makefile | 2 +- mtce/src/heartbeat/hbsStubs.cpp | 1 - mtce/src/hwmon/hwmonClass.cpp | 78 +++-- mtce/src/hwmon/hwmonClass.h | 27 +- mtce/src/hwmon/hwmonFsm.cpp | 18 +- mtce/src/hwmon/hwmonHdlr.cpp | 6 + mtce/src/hwmon/hwmonInit.cpp | 6 + mtce/src/maintenance/Makefile | 2 - mtce/src/maintenance/mtcHttpUtil.cpp | 2 + mtce/src/maintenance/mtcInvApi.cpp | 6 - mtce/src/maintenance/mtcKeyApi.cpp | 183 ------------ mtce/src/maintenance/mtcKeyApi.h | 25 -- mtce/src/maintenance/mtcNodeCtrl.cpp | 13 +- mtce/src/maintenance/mtcNodeHdlrs.cpp | 15 +- mtce/src/scripts/mtc.conf | 1 + 36 files changed, 899 insertions(+), 493 deletions(-) create mode 100755 mtce-common/src/common/secretUtil.cpp create mode 100755 mtce-common/src/common/secretUtil.h delete mode 100755 mtce/src/maintenance/mtcKeyApi.cpp delete mode 100755 mtce/src/maintenance/mtcKeyApi.h diff --git a/devstack/lib/stx-metal b/devstack/lib/stx-metal index 8c30340e..f140acac 100644 --- a/devstack/lib/stx-metal +++ b/devstack/lib/stx-metal @@ -169,6 +169,7 @@ function install_mtce_common { "common/regexUtil.h" \ "common/threadUtil.h" \ "common/tokenUtil.h" \ + "common/secretUtil.h" \ ) sudo install -m 755 -d ${inc_dir_common} sudo install -m 644 -t ${inc_dir_common} ${commonhdr_file[*]} @@ -957,6 +958,7 @@ function cleanup_metal { "regexUtil.h" \ "threadUtil.h" \ "tokenUtil.h" \ + "secretUtil.h" \ "daemon_ini.h" \ "daemon_common.h" \ "daemon_option.h" \ diff --git a/mtce-common/centos/mtce-common.spec b/mtce-common/centos/mtce-common.spec index 738d82fa..b0837f7c 100644 --- a/mtce-common/centos/mtce-common.spec +++ b/mtce-common/centos/mtce-common.spec @@ -140,6 +140,7 @@ install -m 644 -p -D %{_buildsubdir}/common/pingUtil.h %{buildroot}%{_includedir install -m 644 -p -D %{_buildsubdir}/common/regexUtil.h %{buildroot}%{_includedir}/mtce-common install -m 644 -p -D %{_buildsubdir}/common/threadUtil.h %{buildroot}%{_includedir}/mtce-common install -m 644 -p -D %{_buildsubdir}/common/tokenUtil.h %{buildroot}%{_includedir}/mtce-common +install -m 644 -p -D %{_buildsubdir}/common/secretUtil.h %{buildroot}%{_includedir}/mtce-common %clean rm -v -rf $RPM_BUILD_ROOT diff --git a/mtce-common/src/common/Makefile b/mtce-common/src/common/Makefile index 9c9788bf..ce759211 100755 --- a/mtce-common/src/common/Makefile +++ b/mtce-common/src/common/Makefile @@ -22,6 +22,7 @@ SRCS = regexUtil.cpp \ jsonUtil.cpp \ httpUtil.cpp \ tokenUtil.cpp \ + secretUtil.cpp \ msgClass.cpp COMMON_OBJS = regexUtil.o \ @@ -39,6 +40,7 @@ COMMON_OBJS = regexUtil.o \ jsonUtil.o \ httpUtil.o \ tokenUtil.o \ + secretUtil.o \ msgClass.o OBJS = $(SRCS:.cpp=.o) diff --git a/mtce-common/src/common/hostUtil.cpp b/mtce-common/src/common/hostUtil.cpp index dc75442c..588ef852 100644 --- a/mtce-common/src/common/hostUtil.cpp +++ b/mtce-common/src/common/hostUtil.cpp @@ -56,6 +56,11 @@ string hostUtil_getServiceIp ( mtc_service_enum service ) ip = "localhost" ; break ; } + case SERVICE_SECRET: + { + ip = cfg_ptr->barbican_api_host; + break ; + } default: { slog ("Unsupported service (%d)\n", service ); @@ -97,6 +102,9 @@ int hostUtil_getServicePort ( mtc_service_enum service ) case SERVICE_TOKEN: return(cfg_ptr->keystone_port); + case SERVICE_SECRET: + return(cfg_ptr->barbican_api_port); + default: { slog ("Unsupported service (%d)\n", service ); diff --git a/mtce-common/src/common/hostUtil.h b/mtce-common/src/common/hostUtil.h index d207f4da..f58f9be4 100644 --- a/mtce-common/src/common/hostUtil.h +++ b/mtce-common/src/common/hostUtil.h @@ -70,6 +70,7 @@ typedef enum SERVICE_TOKEN = 1, SERVICE_SMGR = 2, SERVICE_VIM = 3, + SERVICE_SECRET = 4, } mtc_service_enum ; string hostUtil_getServiceIp ( mtc_service_enum service ); diff --git a/mtce-common/src/common/httpUtil.cpp b/mtce-common/src/common/httpUtil.cpp index d263971c..a4876644 100644 --- a/mtce-common/src/common/httpUtil.cpp +++ b/mtce-common/src/common/httpUtil.cpp @@ -20,7 +20,7 @@ using namespace std; #include "tokenUtil.h" /* for ... tokenUtil_handler */ #include "nodeUtil.h" /* for ... string_contains */ #include "timeUtil.h" /* for ... time_debug_type */ -#include "keyClass.h" /* for ... add_key, del_key */ +#include "keyClass.h" /* for ... add_key, del_key */ static keyClass keyValObject ; static char rest_api_filename[MAX_FILENAME_LEN]; @@ -66,10 +66,10 @@ const char * getHttpCmdType_str ( evhttp_cmd_type type ) * * ************************************************************************/ -int httpUtil_event_init ( libEvent * ptr , +int httpUtil_event_init ( libEvent * ptr , string hostname, - string service, - string ip, + string service, + string ip, int port ) { /* Default Starting States */ @@ -127,12 +127,12 @@ int httpUtil_event_init ( libEvent * ptr , /** Default the user agent to mtce ; other users and commands can override */ ptr->user_agent = "mtce/1.0" ; - ptr->admin_url.clear(); + ptr->admin_url.clear(); ptr->internal_url.clear(); ptr->public_url.clear(); /* HTTP Specific Info */ - ptr->type = EVHTTP_REQ_GET ; /* request type GET/PUT/PATCH etc */ + ptr->type = EVHTTP_REQ_GET ; /* request type GET/PUT/PATCH etc */ /* Result Info */ ptr->status = FAIL; @@ -154,8 +154,8 @@ void httpUtil_init ( void ) { httpUtil_event_init ( &nullEvent, "null", "null" , "0.0.0.0", 0); nullEvent.request = SERVICE_NONE ; - - snprintf (&rest_api_filename[0], MAX_FILENAME_LEN, "/var/log/%s_api.log", + + snprintf (&rest_api_filename[0], MAX_FILENAME_LEN, "/var/log/%s_api.log", program_invocation_short_name ); } @@ -200,7 +200,7 @@ void httpUtil_free_base ( libEvent & event ) event.base = NULL ; if ( event.conn ) { - hlog ("%s Free Connection (%p) --------- along with base\n", + hlog ("%s Free Connection (%p) --------- along with base\n", event.log_prefix.c_str(), event.conn ); evhttp_connection_free ( event.conn ); @@ -209,7 +209,7 @@ void httpUtil_free_base ( libEvent & event ) } else { - hlog1 ("%s Already Freed Event Base\n", event.log_prefix.c_str()); + hlog1 ("%s Already Freed Event Base\n", event.log_prefix.c_str()); } } @@ -230,7 +230,7 @@ int httpUtil_connect ( libEvent & event ) /* Open an http connection to specified IP and port */ event.conn = evhttp_connection_base_new ( event.base, NULL, - event.ip.c_str(), + event.ip.c_str(), event.port ); /* bind to the correctly-versioned local address */ if ( event.conn ) @@ -262,7 +262,7 @@ int httpUtil_request ( libEvent & event, void(*hdlr)(struct evhttp_request *, void *)) { int rc = PASS ; - + /* make a new request and bind the event handler to it */ event.req = evhttp_request_new( hdlr , event.base ); if ( ! event.req ) @@ -286,14 +286,14 @@ int httpUtil_request ( libEvent & event, int httpUtil_payload_add ( libEvent & event ) { int rc = PASS ; - + /* Returns the output buffer. */ event.buf = evhttp_request_get_output_buffer ( event.req ); - + /* Check for no buffer */ if ( ! event.buf ) { - elog ("%s evhttp_request_get_output_buffer returned null (%p)\n", + elog ("%s evhttp_request_get_output_buffer returned null (%p)\n", event.log_prefix.c_str(), event.req ); rc = FAIL ; @@ -311,7 +311,7 @@ int httpUtil_payload_add ( libEvent & event ) } else if ( rc == 0 ) { - elog ("%s no data added to output buffer (len=0)\n", + elog ("%s no data added to output buffer (len=0)\n", event.log_prefix.c_str()); rc = FAIL ; @@ -367,15 +367,15 @@ int httpUtil_header_add ( libEvent * ptr, http_headers_type * hdrs_ptr ) if ( hdrs_ptr->entries > MAX_HEADERS ) { - elog ("%s Too many headers (%d:%d)\n", + elog ("%s Too many headers (%d:%d)\n", ptr->log_prefix.c_str(), MAX_HEADERS, hdrs_ptr->entries ); return FAIL ; } for ( int i = 0 ; i < hdrs_ptr->entries ; i++ ) { /* Add the header */ - rc = evhttp_add_header( ptr->req->output_headers, - hdrs_ptr->entry[i].key.c_str() , + rc = evhttp_add_header( ptr->req->output_headers, + hdrs_ptr->entry[i].key.c_str(), hdrs_ptr->entry[i].value.c_str()); if ( rc ) { @@ -385,7 +385,7 @@ int httpUtil_header_add ( libEvent * ptr, http_headers_type * hdrs_ptr ) hdrs_ptr->entry[i].value.c_str()); rc = FAIL ; break ; - } + } } return (rc); } @@ -432,14 +432,14 @@ int httpUtil_get_response ( libEvent & event ) /* Get a stack buffer, zero it, copy to it and terminate it */ char * stack_buf_ptr = (char*)malloc (event.response_len+1); memset ( stack_buf_ptr, 0, event.response_len+1 ); - real_len = evbuffer_remove( event.req->input_buffer, stack_buf_ptr, + real_len = evbuffer_remove( event.req->input_buffer, stack_buf_ptr, event.response_len); if ( real_len != event.response_len ) { wlog ("%s Length differs from removed length (%ld:%ld)\n", event.log_prefix.c_str(), - event.response_len, + event.response_len, real_len ); } @@ -447,7 +447,7 @@ int httpUtil_get_response ( libEvent & event ) { hlog1 ("%s has no response data\n", event.log_prefix.c_str() ); } - /* Terminate the buffer , this is where the +1 above is required. + /* Terminate the buffer , this is where the +1 above is required. * Without it there is memory corruption reported by Linux */ *(stack_buf_ptr+event.response_len) = '\0'; @@ -538,7 +538,7 @@ void httpUtil_handler ( struct evhttp_request *req, void *arg ) return ; } - event_ptr = (libEvent*)temp; + event_ptr = (libEvent*)temp; if (( event_ptr->request >= SERVICE_LAST ) || ( event_ptr->request == SERVICE_NONE )) { slog ("HTTP Event Lookup Failed for http base (%p) <------\n", arg); @@ -549,18 +549,17 @@ void httpUtil_handler ( struct evhttp_request *req, void *arg ) event_ptr->status = httpUtil_status ( (*event_ptr) ) ; if ( event_ptr->status == HTTP_NOTFOUND ) { - elog ("%s returned (Not-Found) (%d)\n", - event_ptr->log_prefix.c_str(), + elog ("%s returned (Not-Found) (%d)\n", + event_ptr->log_prefix.c_str(), event_ptr->status); if ( event_ptr->type != EVHTTP_REQ_POST ) event_ptr->status = PASS ; - goto httpUtil_handler_done ; } else if (( event_ptr->status != PASS ) && ( ! req )) { - elog ("%s Request Timeout (%d)\n", + elog ("%s Request Timeout (%d)\n", event_ptr->log_prefix.c_str(), event_ptr->timeout); @@ -788,6 +787,11 @@ int httpUtil_api_request ( libEvent & event ) { ; } + else if (( event.request == BARBICAN_GET_SECRET ) || + ( event.request == BARBICAN_READ_SECRET )) + { + ; + } else { slog ("%s Unsupported Request (%d)\n", event.hostname.c_str(), event.request); @@ -799,7 +803,7 @@ int httpUtil_api_request ( libEvent & event ) if ( httpUtil_connect ( event )) { event.status = FAIL_CONNECT ; - goto httpUtil_api_request_done ; + goto httpUtil_api_request_done ; } if ( httpUtil_request ( event, &httpUtil_handler )) @@ -813,7 +817,7 @@ int httpUtil_api_request ( libEvent & event ) jlog ("%s Address : %s\n", event.hostname.c_str(), event.address.c_str()); } - if (( event.type != EVHTTP_REQ_GET ) && + if (( event.type != EVHTTP_REQ_GET ) && ( event.type != EVHTTP_REQ_DELETE )) { /* Add payload to the output buffer but only for PUT, POST and PATCH requests */ @@ -824,15 +828,15 @@ int httpUtil_api_request ( libEvent & event ) } if ( daemon_get_cfg_ptr()->debug_json ) { - if ((!string_contains(event.payload,"token")) && + if ((!string_contains(event.payload,"token")) && (!string_contains(event.payload,"assword"))) { - jlog ("%s Payload : %s\n", event.hostname.c_str(), + jlog ("%s Payload : %s\n", event.hostname.c_str(), event.payload.c_str() ); } else { - jlog ("%s Payload : ... contains private content ...\n", + jlog ("%s Payload : ... contains private content ...\n", event.hostname.c_str()); } @@ -848,7 +852,7 @@ int httpUtil_api_request ( libEvent & event ) hdrs.entry[hdr_entry].value = "admin"; hdr_entry++; - if (( event.type != EVHTTP_REQ_GET ) && + if (( event.type != EVHTTP_REQ_GET ) && ( event.type != EVHTTP_REQ_DELETE )) { hdrs.entry[hdr_entry].key = "Content-Length" ; @@ -859,14 +863,23 @@ int httpUtil_api_request ( libEvent & event ) hdrs.entry[hdr_entry].key = "User-Agent" ; hdrs.entry[hdr_entry].value = event.user_agent ; hdr_entry++; - + hdrs.entry[hdr_entry].key = "Content-Type" ; hdrs.entry[hdr_entry].value = "application/json" ; hdr_entry++; - hdrs.entry[hdr_entry].key = "Accept" ; - hdrs.entry[hdr_entry].value = "application/json" ; - hdr_entry++; + if ( event.request == BARBICAN_READ_SECRET ) + { + hdrs.entry[hdr_entry].key = "Accept" ; + hdrs.entry[hdr_entry].value = "application/octet-stream" ; + hdr_entry++; + } + else + { + hdrs.entry[hdr_entry].key = "Accept" ; + hdrs.entry[hdr_entry].value = "application/json" ; + hdr_entry++; + } if ( event.request != KEYSTONE_GET_TOKEN ) { @@ -912,8 +925,10 @@ int httpUtil_api_request ( libEvent & event ) } else { + hlog ("%s API Internal Address : %s\n", event.hostname.c_str(), event.address.c_str()); event.status = evhttp_make_request ( event.conn, event.req, event.type, event.address.data()); } + daemon_signal_hdlr (); if ( event.status == PASS ) { @@ -939,14 +954,15 @@ int httpUtil_api_request ( libEvent & event ) httpUtil_latency_log ( event, label.c_str(), __LINE__, MAX_DELAY_B4_LATENCY_LOG ); goto httpUtil_api_request_done ; } - else if ( event.request == KEYSTONE_GET_TOKEN ) + else if ( event.request == KEYSTONE_GET_TOKEN || + event.request == BARBICAN_GET_SECRET || + event.request == BARBICAN_READ_SECRET ) { hlog ("%s Requested (non-blocking) (timeout:%d secs)\n", event.log_prefix.c_str(), event.timeout); event.active = true ; event.status = event_base_loop(event.base, EVLOOP_NONBLOCK); httpUtil_latency_log ( event, label.c_str(), __LINE__, MAX_DELAY_B4_LATENCY_LOG ); /* Should be immediate ; non blocking */ return (event.status); - // goto httpUtil_api_request_done ; } else { @@ -979,9 +995,9 @@ httpUtil_api_request_done: void httpUtil_event_info ( libEvent & event ) { - ilog ("%s request to %s.%d Status:%d \n", - event.log_prefix.c_str(), - event.ip.c_str(), + ilog ("%s request to %s.%d Status:%d \n", + event.log_prefix.c_str(), + event.ip.c_str(), event.port, event.status); if ( event.request == KEYSTONE_GET_TOKEN ) @@ -1001,7 +1017,7 @@ void httpUtil_log_event ( libEvent * event_ptr ) { string event_sig = daemon_get_cfg_ptr()->debug_event ; msgSock_type * mtclogd_ptr = get_mtclogd_sockPtr (); - + send_log_message ( get_mtclogd_sockPtr(), event_ptr->hostname.data(), &rest_api_filename[0], &event_ptr->req_str[0] ); if ( event_ptr->request == KEYSTONE_GET_TOKEN ) @@ -1031,16 +1047,16 @@ void httpUtil_log_event ( libEvent * event_ptr ) if (!event_ptr->payload.empty()) { - if ((!string_contains(event_ptr->payload,"token")) && + if ((!string_contains(event_ptr->payload,"token")) && (!string_contains(event_ptr->payload,"assword"))) { - snprintf (&rest_api_log_str[0], MAX_API_LOG_LEN-1, + snprintf (&rest_api_log_str[0], MAX_API_LOG_LEN-1, "%s [%5d] %s seq:%d -> Payload : %s", pt(), getpid(), event_ptr->log_prefix.c_str(), event_ptr->sequence, event_ptr->payload.c_str() ); } else { - snprintf (&rest_api_log_str[0], MAX_API_LOG_LEN-1, + snprintf (&rest_api_log_str[0], MAX_API_LOG_LEN-1, "%s [%5d] %s seq:%d -> Payload : ... contains private content ...", pt(), getpid(), event_ptr->log_prefix.c_str(), event_ptr->sequence ); } @@ -1049,10 +1065,10 @@ void httpUtil_log_event ( libEvent * event_ptr ) if ( !event_ptr->response.empty() ) { - if ((!string_contains(event_ptr->response,"token")) && + if ((!string_contains(event_ptr->response,"token")) && (!string_contains(event_ptr->response,"assword"))) { - snprintf (&rest_api_log_str[0], MAX_API_LOG_LEN-1, + snprintf (&rest_api_log_str[0], MAX_API_LOG_LEN-1, "%s [%5d] %s seq:%d -> Response: %s", pt(), getpid(), event_ptr->log_prefix.c_str(), event_ptr->sequence, event_ptr->response.c_str() ); } @@ -1064,18 +1080,18 @@ void httpUtil_log_event ( libEvent * event_ptr ) } send_log_message ( mtclogd_ptr, event_ptr->hostname.data(), rest_api_filename, &rest_api_log_str[0] ); } - - snprintf (&rest_api_log_str[0], MAX_API_LOG_LEN-1, + + snprintf (&rest_api_log_str[0], MAX_API_LOG_LEN-1, "%s [%5d] %s %s '%s' seq:%d -> Status : %d {execution time %ld.%06ld secs}\n", pt(), getpid(), event_ptr->hostname.c_str(), - event_ptr->service.c_str(), + event_ptr->service.c_str(), event_ptr->operation.c_str(), event_ptr->sequence, event_ptr->http_status, - event_ptr->diff_time.secs, + event_ptr->diff_time.secs, event_ptr->diff_time.msecs ); - + if (( event_ptr->diff_time.secs > 2 ) || (event_ptr->http_status != HTTP_OK ) ) { int len = strlen (rest_api_log_str) ; diff --git a/mtce-common/src/common/httpUtil.h b/mtce-common/src/common/httpUtil.h index d846d29c..b0f66982 100644 --- a/mtce-common/src/common/httpUtil.h +++ b/mtce-common/src/common/httpUtil.h @@ -52,6 +52,7 @@ using namespace std; #define HTTP_KEYSTONE_GET_TIMEOUT (10) #define HTTP_SMGR_TIMEOUT (20) #define HTTP_VIM_TIMEOUT (20) +#define HTTP_SECRET_TIMEOUT (5) #define SMGR_MAX_RETRIES (3) @@ -61,12 +62,14 @@ using namespace std; #define SMGR_EVENT_SIG "smgrEvent" #define SYSINV_EVENT_SIG "sysinvEvent" +#define SECRET_EVENT_SIG "secretEvent" #define KEYSTONE_SIG "token" #define SENSOR_SIG "sensor" #define SYSINV_SIG "sysinv" #define SMGR_SIG "smgr" #define VIM_SIG "vim" +#define SECRET_SIG "secret" #define SYSINV_OPER__LOAD_HOST "load host" #define SYSINV_OPER__UPDATE_TASK "update task" @@ -108,6 +111,26 @@ typedef struct error renewal - flood avoidance */ } keyToken_type ; + +typedef enum +{ + MTC_SECRET__START = 0, + MTC_SECRET__GET_REF, + MTC_SECRET__GET_REF_FAIL, + MTC_SECRET__GET_REF_RECV, + MTC_SECRET__GET_PWD, + MTC_SECRET__GET_PWD_FAIL, + MTC_SECRET__GET_PWD_RECV, + MTC_SECRET__STAGES, +} mtc_secretStages_enum ; + +typedef struct +{ + string reference; + string payload ; + mtc_secretStages_enum stage ; +} barbicanSecret_type; + /** All supported Request Type Enums */ typedef enum { SERVICE_NONE, @@ -154,19 +177,22 @@ typedef enum { SMGR_HOST_LOCKED, SMGR_HOST_ENABLED, SMGR_HOST_DISABLED, - + KEYSTONE_TOKEN, KEYSTONE_GET_TOKEN, KEYSTONE_GET_SERVICE_LIST, KEYSTONE_GET_ENDPOINT_LIST, + BARBICAN_GET_SECRET, + BARBICAN_READ_SECRET, + SERVICE_LAST } libEvent_enum ; /** Local event control structure for REST API services - * - * Nova, Neutron, Keystone and Inventory + * + * Nova, Neutron, Keystone, Barbican and Inventory * */ struct libEvent @@ -177,7 +203,7 @@ struct libEvent bool mutex ; /**< single operation at a time */ bool active ; /**< true if waiting on response */ int stuck ; /**< Count mutex active stuck state */ - bool blocking ; /**< true if command is blocking */ + bool blocking ; /**< true if command is blocking */ bool found ; /**< true if query was found */ int timeout ; /**< Request timeout */ int count ; /**< retry recover counter */ @@ -204,7 +230,7 @@ struct libEvent /** Service Specific Request Info */ libEvent_enum request ; /**< Specify the request command */ - keyToken_type token ; /**< Copy of the active token */ + keyToken_type token ; /**< Copy of the active token */ string service ; /**< Service being executed */ string hostname ; /**< Target hostname */ string uuid ; /**< The UUID for this request */ @@ -222,12 +248,12 @@ struct libEvent string address ; /**< http url address */ string payload ; /**< the request's payload */ string user_agent ; /**< set the User-Agent header */ - + /** Result Info */ int status ; /**< Execution Status */ int http_status ; /**< raw http returned status */ int exec_time_msec ; /**< execution time in msec */ - node_inv_type inv_info ; + node_inv_type inv_info ; size_t response_len ; /**< the json response length */ string response ; /**< the json response string */ string result ; /**< Command specific result str */ @@ -288,10 +314,10 @@ typedef struct void httpUtil_init ( void ); -int httpUtil_event_init ( libEvent * ptr , +int httpUtil_event_init ( libEvent * ptr , string hostname, - string service, - string ip, + string service, + string ip, int port ); /** Add payload to the HTTP message body. */ @@ -310,14 +336,14 @@ int httpUtil_connect ( libEvent & event ); int httpUtil_request ( libEvent & event, void(*hdlr)(struct evhttp_request *, void *)); -/** Common REST API Request Utility */ +/** Common REST API Request Utility */ int httpUtil_api_request ( libEvent & event ); -/** Common REST API Request Utility */ +/** Common REST API Request Utility */ int httpUtil_request ( libEvent & event , bool block, void(*hdlr)(struct evhttp_request *, void *)); -/** Common REST API Receive Utility for non-blocking requests */ +/** Common REST API Receive Utility for non-blocking requests */ int httpUtil_receive ( libEvent & event ); /** HTTP response status checker */ diff --git a/mtce-common/src/common/jsonUtil.cpp b/mtce-common/src/common/jsonUtil.cpp index aafc20c9..15fe84d8 100644 --- a/mtce-common/src/common/jsonUtil.cpp +++ b/mtce-common/src/common/jsonUtil.cpp @@ -619,6 +619,80 @@ load_host_cleanup: return (rc); } +int jsonUtil_secret_load ( string & name, + char * json_str_ptr, + jsonUtil_secret_type & info ) +{ + int rc = PASS ; + json_bool status ; + + /* init to null to avoid trap on early cleanup call with + * bad non-null default pointer value */ + struct array_list * array_list_obj = (struct array_list *)(NULL); + struct json_object *raw_obj = (struct json_object *)(NULL); + struct json_object *secret_obj = (struct json_object *)(NULL); + struct json_object *ref_obj = (struct json_object *)(NULL); + + if (( json_str_ptr == NULL ) || ( *json_str_ptr == '\0' ) || + ( ! strncmp ( json_str_ptr, "(null)" , 6 ))) + { + elog ("Cannot tokenize a null json string\n"); + return (FAIL); + } + raw_obj = json_tokener_parse( json_str_ptr ); + if ( !raw_obj ) + { + elog ("No or invalid json string (%s)\n", json_str_ptr ); + rc = FAIL ; + goto secret_load_cleanup ; + } + + status = json_object_object_get_ex(raw_obj, MTC_JSON_SECRET_LIST, &secret_obj ); + if ( ( status == TRUE ) && ( secret_obj )) + { + array_list_obj = json_object_get_array(secret_obj ); + if ( array_list_obj ) + { + int len = array_list_length (array_list_obj ); + if ( len == 0 ) + { + wlog ( "No %s elements in array\n", MTC_JSON_SECRET_LIST ); + goto secret_load_cleanup; + } + for ( int i = 0 ; i < len ; i++ ) + { + ref_obj = _json_object_array_get_idx (secret_obj, i ); + if ( ref_obj ) + { + string secret_name = _json_get_key_value_string ( ref_obj, MTC_JSON_SECRET_NAME ); + if ( ( secret_name.length() > 0) && !secret_name.compare(name) ) + { + info.secret_ref = _json_get_key_value_string ( ref_obj, MTC_JSON_SECRET_REFERENCE ); + jlog ( "Found secret_ref %s\n", info.secret_ref.c_str() ); + break ; + } + } + } + } + else + { + elog ("%s Failed to find %s object array\n", name.c_str(), MTC_JSON_SECRET_LIST ); + } + } + else + { + elog ("%s Failed to find %s object\n", name.c_str(), MTC_JSON_SECRET_LIST ); + } + +secret_load_cleanup: + + if (raw_obj) json_object_put(raw_obj ); + if (secret_obj) json_object_put(secret_obj ); + if (ref_obj) json_object_put(ref_obj ); + + return (rc); +} + void jsonUtil_print ( jsonUtil_info_type & info, int index ) { if ( info.elements == 0 ) diff --git a/mtce-common/src/common/jsonUtil.h b/mtce-common/src/common/jsonUtil.h index 1786df3c..77797664 100644 --- a/mtce-common/src/common/jsonUtil.h +++ b/mtce-common/src/common/jsonUtil.h @@ -10,7 +10,7 @@ /** * @file * Wind River CGTS Platform Controller Maintenance - * + * * JSON Utility Header */ @@ -56,17 +56,57 @@ typedef struct string adminURL; /**< path to the nova server. */ } jsonUtil_auth_type ; -/** Module initialization interface. +#define MAX_JSON_SECRET_CONTENTS_NUM 7 +#define MTC_JSON_SECRET_LIST "secrets" +#define MTC_JSON_SECRET_TOTAL "total" +#define MTC_JSON_SECRET_PREVIOUS "previous" +#define MTC_JSON_SECRET_NEXT "next" +#define MTC_JSON_SECRET_ALGORITHM "algorithm" +#define MTC_JSON_SECRET_LENGTH "bit_length" +#define MTC_JSON_SECRET_CONTENT "content_types" +#define MTC_JSON_SECRET_CREATED "created" +#define MTC_JSON_SECRET_CREATOR "creator_id" +#define MTC_JSON_SECRET_EXPIRATION "expiration" +#define MTC_JSON_SECRET_MODE "mode" +#define MTC_JSON_SECRET_NAME "name" +#define MTC_JSON_SECRET_REFERENCE "secret_ref" +#define MTC_JSON_SECRET_TYPE "secret_type" +#define MTC_JSON_SECRET_STATUS "status" +#define MTC_JSON_SECRET_UPDATED "updated" + +typedef struct +{ + string type ; + string encoding ; +} content_type ; + +typedef struct +{ + string algorithm ; + int bit_length ; + content_type contents[MAX_JSON_SECRET_CONTENTS_NUM]; + string created ; + string creator_id ; + string expiration ; + string mode ; + string name ; + string secret_ref ; + string secret_type ; + string status ; + string updated ; +} jsonUtil_secret_type ; + +/** Module initialization interface. */ void jsonUtil_init ( jsonUtil_info_type & info ); -/** Print the authroization struct to stdio. +/** Print the authroization struct to stdio. */ void jsonUtil_print ( jsonUtil_info_type & info , int index ); void jsonUtil_print_inv ( node_inv_type & info ); int jsonUtil_get_key_val ( char * json_str_ptr, - string key, + string key, string & value ); int jsonUtil_get_key_val_int ( char * json_str_ptr, @@ -76,10 +116,11 @@ int jsonUtil_get_key_val_int ( char * json_str_ptr, /** Submit a request to get an authorization token and nova URL */ int jsonApi_auth_request ( string & hostname, string & payload ); -/** Parse through the authorization request's response json string +/** Parse through the authorization request's response json string * and load the relavent information into the passed in structure */ - int jsonUtil_inv_load ( char * json_str_ptr, - jsonUtil_info_type & info ); +int jsonUtil_inv_load ( char * json_str_ptr, jsonUtil_info_type & info ); + +int jsonUtil_secret_load ( string & name, char * json_str_ptr, jsonUtil_secret_type & info ); int jsonUtil_load_host ( char * json_str_ptr, node_inv_type & info ); int jsonUtil_load_host_state ( char * json_str_ptr, node_inv_type & info ); @@ -102,7 +143,7 @@ int jsonUtil_patch_load ( char * json_str_ptr, node_inv_type & info ); *- FAIL indicates bad or error reply in json string. * */ -int jsonApi_auth_load ( string & hostname, char * json_str_ptr, +int jsonApi_auth_load ( string & hostname, char * json_str_ptr, jsonUtil_auth_type & info ); @@ -110,9 +151,9 @@ int jsonApi_auth_load ( string & hostname, char * json_str_ptr, * This utility searches for an 'array_label' and then loops over the array * looking at each element for the specified 'search_key' and 'search_value' * Once found it searches that same element for the specified 'element_key' - * and loads its value content into 'element_value' - what we're looking for + * and loads its value content into 'element_value' - what we're looking for ***************************************************************************/ -int jsonApi_array_value ( char * json_str_ptr, +int jsonApi_array_value ( char * json_str_ptr, string array_label, string search_key, string search_value, @@ -123,18 +164,18 @@ int jsonApi_array_value ( char * json_str_ptr, * This utility updates the reference key_list with all the * values for the specified label. ***********************************************************************/ -int jsonUtil_get_list ( char * json_str_ptr, +int jsonUtil_get_list ( char * json_str_ptr, string label, list & key_list ); /*********************************************************************** * This utility updates the reference element with the number of array - * elements for the specified label in the provided string + * elements for the specified label in the provided string ***********************************************************************/ int jsonUtil_array_elements ( char * json_str_ptr, string label, int & elements ); /*********************************************************************** * This utility updates the reference string 'element' with the - * contents of the specified labeled array element index. + * contents of the specified labeled array element index. ***********************************************************************/ int jsonUtil_get_array_idx ( char * json_str_ptr, string label, int idx, string & element ); diff --git a/mtce-common/src/common/logMacros.h b/mtce-common/src/common/logMacros.h index f8720c97..b0412088 100644 --- a/mtce-common/src/common/logMacros.h +++ b/mtce-common/src/common/logMacros.h @@ -67,7 +67,7 @@ typedef struct char* keystone_auth_project ; /**< =services */ char* keystone_user_domain; /**< = Default */ char* keystone_project_domain; /**< = Default */ - char* keyring_directory ; /**< =/opt/platform/.keyring/ */ + char* sysinv_mtc_inv_label ; /**< =/v1/hosts/ */ int sysinv_api_port ; /**< =6385 */ char* sysinv_api_bind_ip ; /**< = */ @@ -75,6 +75,9 @@ typedef struct char* ceilometer_url ; /**< ceilometer sensor sample database url */ int ceilometer_port ; /**< ceilometer REST API port number */ + char* barbican_api_host ; /**< Barbican REST API host IP address */ + int barbican_api_port ; /**< Barbican REST API port number */ + int mtc_rx_mgmnt_port ; /**< mtcClient listens mgmnt nwk cmd reqs */ int mtc_rx_infra_port ; /**< mtcClient listens infra nwk cmd reqs */ int mtc_tx_mgmnt_port ; /**< mtcClient sends mgmnt nwk cmds/resp's */ diff --git a/mtce-common/src/common/nodeBase.h b/mtce-common/src/common/nodeBase.h index 162dace3..c154653b 100755 --- a/mtce-common/src/common/nodeBase.h +++ b/mtce-common/src/common/nodeBase.h @@ -114,7 +114,7 @@ void daemon_exit ( void ); #define NFVI_PLUGIN_CFG_FILE ((const char *)"/etc/nfv/nfv_plugins/nfvi_plugins/config.ini") #define SYSINV_CFG_FILE ((const char *)"/etc/sysinv/sysinv.conf") #define HWMON_CONF_FILE ((const char *)"/etc/mtc/hwmond.conf") - +#define SECRET_CFG_FILE ((const char *)"/etc/barbican/barbican.conf") #define GOENABLED_DIR ((const char *)"/etc/goenabled.d") /* generic */ #define GOENABLED_WORKER_DIR ((const char *)"/etc/goenabled.d/worker") diff --git a/mtce-common/src/common/nodeUtil.cpp b/mtce-common/src/common/nodeUtil.cpp index 9aa30dc9..a7aaed24 100755 --- a/mtce-common/src/common/nodeUtil.cpp +++ b/mtce-common/src/common/nodeUtil.cpp @@ -1188,73 +1188,6 @@ bool string_contains ( string buffer, string sequence ) } -extern char *program_invocation_short_name; - - -string get_bm_password ( const char * uuid ) -{ - #define STR_LEN 128 - int rc = RETRY ; - string value = "" ; - - daemon_signal_hdlr (); - - if ( uuid == NULL ) - { - slog ("failed ; Null uuid\n" ); - return (value); - } - - string temp_file = "/tmp/." ; - temp_file.append(program_invocation_short_name); - temp_file.append("_bmc.tmp"); - - /* If the keyring dir is not present then set the password to unknown */ - DIR *d = opendir(daemon_get_cfg_ptr()->keyring_directory); - if (d) - { - char str [STR_LEN] ; - memset (&str[0],0,STR_LEN); - sprintf(&str[0], "/usr/bin/keyring get BM %s > %s", uuid, temp_file.data() ); - /* This system call can take 1 sec */ - rc = system(str) ; - { - int parms ; - usleep(10); - FILE *fp = fopen(temp_file.c_str(), "r"); - if (fp) - { - memset (&str[0],0,STR_LEN); - if ( (parms = fscanf(fp, "%128s", &str[0])) == 1 ) - { - value = str ; /* get the value we are looking for */ - rc = PASS ; - } - fclose(fp); - } - else - { - wlog ("Failed to open %s\n", temp_file.c_str() ); - } - } - closedir(d); - } - else - { - wlog ("Failed to open credentials directory '%s'\n", daemon_get_cfg_ptr()->keyring_directory ); - } - - if ( rc != PASS ) - { - wlog ("password for uuid '%s' not found\n", uuid); - } - - /* Don't leave the temp file containing the password around */ - daemon_remove_file ( temp_file.data() ); - - return (value); -} - static int health = NODE_HEALTH_UNKNOWN ; int get_node_health ( string hostname ) { diff --git a/mtce-common/src/common/nodeUtil.h b/mtce-common/src/common/nodeUtil.h index 712a7251..f8765af3 100755 --- a/mtce-common/src/common/nodeUtil.h +++ b/mtce-common/src/common/nodeUtil.h @@ -41,10 +41,10 @@ typedef struct } msgSock_type ; int send_log_message ( msgSock_type * sock_ptr, - const char * hostname, + const char * hostname, const char * filename, const char * log_str ); - + msgSock_type * get_mtclogd_sockPtr ( void ) ; void mem_log_list_init ( void ); @@ -70,14 +70,13 @@ const char * get_iface_name_str ( int iface ); unsigned int get_host_function_mask ( string & nodeType_str ); bool is_combo_system (unsigned int nodetype_mask ); -int set_host_functions ( string nodetype_str, - unsigned int * nodetype_bits_ptr, - unsigned int * nodetype_function_ptr, +int set_host_functions ( string nodetype_str, + unsigned int * nodetype_bits_ptr, + unsigned int * nodetype_function_ptr, unsigned int * nodetype_subfunction_ptr ); bool is_goenabled ( int nodeType, bool pass ); -string get_bm_password ( const char * username ); string get_strings_in_string_list ( std::list & l ); bool is_string_in_string_list ( std::list & l , string & str ); bool is_int_in_int_list ( std::list & l , int & val ); diff --git a/mtce-common/src/common/secretUtil.cpp b/mtce-common/src/common/secretUtil.cpp new file mode 100755 index 00000000..c92251cb --- /dev/null +++ b/mtce-common/src/common/secretUtil.cpp @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + + /** + * @file + * Wind River CGTS Platform Controller Maintenance + * Access to Openstack Barbican via REST API Interface. + * + * This file implements the a set of secret utilities that maintenance + * calls upon to get/read Barbican secrets from the Barbican Secret storage. + * + * The APIs exposed from this file are + * + * secretUtil_get_secret - gets the Barbican secret, filtered by name + * secretUtil_read_secret - reads the payload for a specified secret uuid + * + * Each utility is paired with a private handler. + * + * secretUtil_handler - handles response for Barbican requests + * + * Warning: These calls cannot be nested. + * + **/ + +#ifdef __AREA__ +#undef __AREA__ +#endif +#define __AREA__ "pwd" + +#include +#include "nodeBase.h" /* for ... Base Service Header */ +#include "nodeUtil.h" /* for ... Utility Service Header */ +#include "hostUtil.h" /* for ... Host Service Header */ +#include "jsonUtil.h" /* for ... Json utilities */ +#include "secretUtil.h" /* this .. module header */ + +std::map secretList; + +barbicanSecret_type * secretUtil_find_secret ( string & host_uuid ) +{ + std::map::iterator it; + it = secretList.find( host_uuid ); + if ( it != secretList.end() ) + { + return &it->second; + } + return NULL; +} + + +barbicanSecret_type * secretUtil_manage_secret ( libEvent & event, + string & host_uuid, + struct mtc_timer & secret_timer, + void (*handler)(int, siginfo_t*, void*)) +{ + int rc = PASS; + std::map::iterator it; + it = secretList.find( host_uuid ); + if ( it == secretList.end() ) + { + barbicanSecret_type secret; + secret.stage = MTC_SECRET__START; + it = secretList.insert( std::pair( host_uuid, secret ) ).first; + } + + if ( it->second.stage == MTC_SECRET__START ) + { + it->second.reference.clear(); + it->second.payload.clear(); + } + + if ( it->second.stage == MTC_SECRET__START || + it->second.stage == MTC_SECRET__GET_REF_FAIL ) + { + if ( secret_timer.ring == true ) + { + rc = secretUtil_get_secret ( event, host_uuid ); + if (rc) + { + wlog ( "%s getting secret reference failed \n", host_uuid.c_str() ); + it->second.stage = MTC_SECRET__GET_REF_FAIL; + mtcTimer_start( secret_timer, handler, SECRET_RETRY_DELAY ); + } + else + { + mtcTimer_start( secret_timer, handler, SECRET_REPLY_DELAY ); + } + } + else if ( event.base ) + { + httpUtil_free_conn ( event ); + httpUtil_free_base ( event ); + } + } + else if ( it->second.stage == MTC_SECRET__GET_REF_RECV || + it->second.stage == MTC_SECRET__GET_PWD_FAIL ) + { + if ( secret_timer.ring == true ) + { + rc = secretUtil_read_secret ( event, host_uuid ); + if (rc) + { + wlog ( "%s getting secret payload failed \n", host_uuid.c_str() ); + it->second.stage = MTC_SECRET__GET_PWD_FAIL; + mtcTimer_start( secret_timer, handler, SECRET_RETRY_DELAY ); + } + else + { + mtcTimer_start( secret_timer, handler, SECRET_REPLY_DELAY ); + } + } + else if ( event.base ) + { + httpUtil_free_conn ( event ); + httpUtil_free_base ( event ); + } + } + else if ( it->second.stage == MTC_SECRET__GET_REF || + it->second.stage == MTC_SECRET__GET_PWD ) + { + if ( event.active == true ) + { + /* Look for the response */ + if ( event.base ) + { + event_base_loop( event.base, EVLOOP_NONBLOCK ); + } + else + { + /* should not get here. event active while base is null + * try and recover from this error case. */ + event.active = false ; + } + } + else if ( event.base ) + { + if ( it->second.stage == MTC_SECRET__GET_REF ) + { + wlog ( "%s getting secret reference timeout \n", host_uuid.c_str() ); + it->second.stage = MTC_SECRET__GET_REF_FAIL ; + mtcTimer_start( secret_timer, handler, SECRET_RETRY_DELAY ); + } + if ( it->second.stage == MTC_SECRET__GET_PWD ) + { + wlog ( "%s getting secret payload timeout \n", host_uuid.c_str() ); + it->second.stage = MTC_SECRET__GET_PWD_FAIL ; + mtcTimer_start( secret_timer, handler, SECRET_RETRY_DELAY ); + } + httpUtil_free_conn ( event ); + httpUtil_free_base ( event ); + } + } + return & it->second ; +} + +/*********************************************************************** + * + * Name : secretUtil_get_secret + * + * Purpose : Issue an Barbican GET request for a specified secret name + * to manage secret's reference. + * + */ + +int secretUtil_get_secret ( libEvent & event, string & host_uuid ) +{ + httpUtil_event_init ( &event, + host_uuid, + "secretUtil_get_secret", + hostUtil_getServiceIp (SERVICE_SECRET), + hostUtil_getServicePort(SERVICE_SECRET)); + + std::map::iterator it; + it = secretList.find( host_uuid ); + if ( it != secretList.end() ) + { + it->second.stage = MTC_SECRET__GET_REF; + } + else + { + elog ("%s failed to find secret record\n", host_uuid.c_str()); + return FAIL; + } + + event.hostname = _hn(); + event.uuid = host_uuid; + + event.token.url = MTC_SECRET_LABEL; + event.token.url.append(MTC_SECRET_NAME); + event.token.url.append(host_uuid); + event.token.url.append(MTC_SECRET_BATCH); + event.token.url.append(MTC_SECRET_BATCH_MAX); + event.address = event.token.url; + + event.blocking = false; + event.request = BARBICAN_GET_SECRET; + event.operation = "get secret reference"; + event.type = EVHTTP_REQ_GET ; + event.timeout = HTTP_SECRET_TIMEOUT ; + event.handler = &secretUtil_handler ; + + dlog ("Path:%s\n", event.token.url.c_str() ); + + return ( httpUtil_api_request ( event ) ) ; +} + +/* ****************************************************************** + * + * Name: secretUtil_read_secret + * + * Purpose: Issue an Barbican GET request for a specified secret uuid + * to read secret's payload, ie password itself. + * + *********************************************************************/ + +int secretUtil_read_secret ( libEvent & event, string & host_uuid ) +{ + httpUtil_event_init ( &event, + host_uuid, + "secretUtil_get_secret", + hostUtil_getServiceIp (SERVICE_SECRET), + hostUtil_getServicePort(SERVICE_SECRET)); + + string bm_pw_reference; + std::map::iterator it; + it = secretList.find( host_uuid ); + if ( it != secretList.end() ) + { + bm_pw_reference = it->second.reference; + it->second.stage = MTC_SECRET__GET_PWD; + } + else + { + elog ("%s failed to find secret record\n", host_uuid.c_str()); + return FAIL; + } + + event.hostname = _hn(); + event.uuid = host_uuid; + + event.token.url = MTC_SECRET_LABEL; + event.token.url.append("/"); + event.token.url.append(bm_pw_reference); + event.token.url.append("/"); + event.token.url.append(MTC_SECRET_PAYLOAD); + event.address = event.token.url; + + event.blocking = false; + event.request = BARBICAN_READ_SECRET ; + event.operation = "get secret payload"; + event.type = EVHTTP_REQ_GET ; + event.timeout = HTTP_SECRET_TIMEOUT ; + event.handler = &secretUtil_handler ; + + dlog ("Path:%s\n", event.token.url.c_str() ); + + return ( httpUtil_api_request ( event ) ) ; +} + + +/******************************************************************* + * + * Name : secretUtil_handler + * + * Description: The handles the barbican get request + * responses for the following messages + * + * BARBICAN_GET_SECRET, + * BARBICAN_READ_SECRET + * + *******************************************************************/ + +int secretUtil_handler ( libEvent & event ) +{ + /* Declare and clean the json info object string containers */ + jsonUtil_secret_type json_info ; + + string hn = event.hostname ; + int rc = event.status ; + + std::map::iterator it; + it = secretList.find( event.uuid ); + if ( it == secretList.end() ) + { + elog ("%s failed to find secret record\n", hn.c_str()); + return ( rc ) ; + } + + if ( event.request == BARBICAN_GET_SECRET ) + { + if ( event.status ) + { + elog ("%s failed to get secret - error code (%d) \n", hn.c_str(), event.status ); + it->second.stage = MTC_SECRET__GET_REF_FAIL; + return ( rc ) ; + } + rc = jsonUtil_secret_load ( event.uuid, + (char*)event.response.data(), + json_info ); + if ( rc != PASS ) + { + elog ( "%s failed to parse secret response (%s)\n", + event.hostname.c_str(), + event.response.c_str() ); + event.status = FAIL_JSON_PARSE ; + it->second.stage = MTC_SECRET__GET_REF_FAIL; + } + else + { + size_t pos = json_info.secret_ref.find_last_of( '/' ); + it->second.reference = json_info.secret_ref.substr( pos+1 ); + if ( it->second.reference.empty() ) + { + ilog ("%s no barbican secret reference found \n", hn.c_str() ); + it->second.stage = MTC_SECRET__GET_PWD_RECV; + } + else + { + it->second.stage = MTC_SECRET__GET_REF_RECV; + } + } + } + else if ( event.request == BARBICAN_READ_SECRET ) + { + if ( event.status == HTTP_NOTFOUND ) + { + ilog ("%s no barbican secret payload found \n", hn.c_str() ); + } + else if ( event.status != PASS ) + { + elog ("%s failed to read secret - error code (%d) \n", hn.c_str(), event.status ); + it->second.stage = MTC_SECRET__GET_REF_FAIL; + return ( rc ) ; + } + + it->second.payload = event.response; + it->second.stage = MTC_SECRET__GET_PWD_RECV; + } + else + { + elog ("%s unsupported secret request (%d)\n", hn.c_str(), event.request ); + } + return ( rc ) ; +} diff --git a/mtce-common/src/common/secretUtil.h b/mtce-common/src/common/secretUtil.h new file mode 100755 index 00000000..c222da66 --- /dev/null +++ b/mtce-common/src/common/secretUtil.h @@ -0,0 +1,63 @@ +#ifndef __INCLUDE_MTCSECRETUTIL_H__ +#define __INCLUDE_MTCSECRETUTIL_H__ + +/* + * Copyright (c) 2019 Wind River Systems, Inc. +* +* SPDX-License-Identifier: Apache-2.0 +* + */ + + /** + * @file + * Wind River CGCS Platform - Maintenance - Openstack Barbican UTIL Header + */ + +/** + * @addtogroup secretUtil + * @{ + * + * This file implements the a set of secretUtil utilities that maintenance + * calls upon to get/read Barbican secrets from the Barbican Secret storage. + * + * The UTILs exposed from this file are + * + * secretUtil_get_secret - gets all the Barbican secrets, filtered by name + * secretUtil_read_secret - reads the payload for a specified secret + * + * See nodeClass.h for these prototypes + * + * Each utility is paired with a private handler. + * + * secretUtil_handler - handles response for secretUtil_get/read_secret + * + * Warning: These calls cannot be nested. + * + **/ + +using namespace std; + +#include "logMacros.h" +#include "httpUtil.h" + +#define MTC_SECRET_LABEL "/v1/secrets" /**< barbican secrets url label */ +#define MTC_SECRET_NAME "?name=" /**< name of barbican secret prefix */ +#define MTC_SECRET_BATCH "&limit=" /**< batch read limit specified prefix */ +#define MTC_SECRET_BATCH_MAX "1" /**< maximum allowed batched read */ +#define MTC_SECRET_PAYLOAD "payload" /**< barbican secret payload label */ + +#define SECRET_START_DELAY (1) +#define SECRET_REPLY_DELAY (1) +#define SECRET_RETRY_DELAY (8) + +barbicanSecret_type * secretUtil_find_secret ( string & host_uuid ); +barbicanSecret_type * secretUtil_manage_secret ( libEvent & event, + string & host_uuid, + struct mtc_timer & secret_timer, + void (*handler)(int, siginfo_t*, void*) ); + +int secretUtil_handler ( libEvent & event ); +int secretUtil_get_secret ( libEvent & event, string & host_uuid ); +int secretUtil_read_secret ( libEvent & event, string & host_uuid ); + +#endif /* __INCLUDE_MTCSECRETUTIL_H__ */ diff --git a/mtce-common/src/common/tokenUtil.cpp b/mtce-common/src/common/tokenUtil.cpp index 251ecf56..c4cfa723 100644 --- a/mtce-common/src/common/tokenUtil.cpp +++ b/mtce-common/src/common/tokenUtil.cpp @@ -7,7 +7,7 @@ /** * @file - * Wind River Titanium Cloud + * Wind River Titanium Cloud * Common Keystone Token Authentication Utility API * * tokenUtil_handler - handle response @@ -410,18 +410,18 @@ string _get_keystone_prefix_path ( ) return (prefix_path); } -/* http://localhost:5000/v2.0/tokens -X POST -H "Content-Type: application/json" - * -H "Accept: application/json" +/* http://localhost:5000/v2.0/tokens -X POST -H "Content-Type: application/json" + * -H "Accept: application/json" * -H "User-Agent: python-keyclient" * -H "Connection: close" * - * { - * "auth": + * { + * "auth": * { - * "tenantName": "admin", - * "passwordCredentials": + * "tenantName": "admin", + * "passwordCredentials": * { - * "username": "admin", + * "username": "admin", * "password": "password" * } * } @@ -433,12 +433,12 @@ string _get_keystone_prefix_path ( ) * * Name : tokenUtil_handler * - * Description: The handles the keystone get request + * Description: The handles the keystone get request * responses for the following messages * - * KEYSTONE_GET_TOKEN, + * KEYSTONE_GET_TOKEN, * KEYSTONE_GET_SERVICE_LIST - * KEYSTONE_GET_ENDPOINT_LIST + * KEYSTONE_GET_ENDPOINT_LIST * *******************************************************************/ int tokenUtil_handler ( libEvent & event ) @@ -486,12 +486,12 @@ int tokenUtil_handler ( libEvent & event ) } else if ( event.request == KEYSTONE_GET_ENDPOINT_LIST ) { - /* Response: {"endpoints": + /* Response: {"endpoints": * [{ - * "service_id": "067...b60", + * "service_id": "067...b60", * "region": "RegionOne", - * "enabled": true, - * "id": "410ab64a37114a418d188f450300aa48", + * "enabled": true, + * "id": "410ab64a37114a418d188f450300aa48", * "interface": "internal", * ""links": { * "self": "http://192.168.204.2:5000/v3/endpoints/410ab64a37114a418d188f450300aa48" @@ -592,28 +592,28 @@ int tokenUtil_handler ( libEvent & event ) { /* Response: {"services": [ - {"id": "49fc93c32d734c78a9d9f975c22f1703", "type": "network", "name": "neutron", "description": "Neutron Networking Service"}, + {"id": "49fc93c32d734c78a9d9f975c22f1703", "type": "network", "name": "neutron", "description": "Neutron Networking Service"}, {"id": "0900a982ff114e7ba62c317443b43362", "type": "metering", "name": "ceilometer", "description": "Openstack Metering Service"}, - {"id": "97940d057bec47cc989cc190b4293aad", "type": "ec2", "name": "nova_ec2", "description": "EC2 Service"}, - {"id": "7ce51d481d024b1f8b80bb1127b80752", "type": "volumev2", "name": "cinderv2", "description": "Cinder Service v2"}, + {"id": "97940d057bec47cc989cc190b4293aad", "type": "ec2", "name": "nova_ec2", "description": "EC2 Service"}, + {"id": "7ce51d481d024b1f8b80bb1127b80752", "type": "volumev2", "name": "cinderv2", "description": "Cinder Service v2"}, {"id": "3ed8ae6ccf85445ebdf2e93bbce9f5fb", "type": "computev3", "name": "novav3", "description": "Openstack Compute Service v3"}, - {"id": "564bf663693c49cf9fee24e2fdbdba3a", "type": "identity", "name": "keystone", "description": "OpenStack Identity Service"}, + {"id": "564bf663693c49cf9fee24e2fdbdba3a", "type": "identity", "name": "keystone", "description": "OpenStack Identity Service"}, {"id": "7e0cadd9db444342b7fddb0005c4ce5f", "type": "platform", "name": "sysinv", "description": "SysInv Service"}, - {"id": "be7afccda91c4ba19ac2e53f613c6b63", "type": "volume", "name": "cinder", "description": "Cinder Service"}, - {"id": "edf60a37f4f84b9baba215d8346b814f", "type": "image", "name": "glance", "description": "Openstack Image Service"}, - {"id": "0673921c7b094178989455a5b157fb60", "type": "patching", "name": "patching", "description": "Patching Service"}, + {"id": "be7afccda91c4ba19ac2e53f613c6b63", "type": "volume", "name": "cinder", "description": "Cinder Service"}, + {"id": "edf60a37f4f84b9baba215d8346b814f", "type": "image", "name": "glance", "description": "Openstack Image Service"}, + {"id": "0673921c7b094178989455a5b157fb60", "type": "patching", "name": "patching", "description": "Patching Service"}, {"id": "d7621026166f43c0a1c74e0e9784cce6", "type": "compute", "name": "nova", "description": "Openstack Compute Service"}, {"id": "aef585311e3144e0b1267ea25dc40b70", "type": "orchestration", "name": "heat", "description": "Openstack Orchestration Service"}, {"id": "0a67bc174fa0469e9b837daf23d83aaf", "type": "cloudformation", "name": "heat-cfn", "description": "Openstack Cloudformation Service"} ]} */ - + bool found = false ; list service_list ; service_list.clear() ; rc = jsonUtil_get_list ( (char*)event.response.data(), (char*)event.label.data(), service_list ); if ( rc == PASS ) { std::list::iterator iter_ptr ; - + for ( iter_ptr = service_list.begin() ; iter_ptr != service_list.end() ; iter_ptr++ ) @@ -625,16 +625,16 @@ int tokenUtil_handler ( libEvent & event ) if ( jsonUtil_get_key_val ( (char*)iter_ptr->data(), "id", event.result ) == PASS ) { found = true ; - ilog ("%s '%s' service uuid is '%s'\n", - event.hostname.c_str(), + ilog ("%s '%s' service uuid is '%s'\n", + event.hostname.c_str(), event.information.c_str(), event.result.c_str()); break ; } else { - wlog ("%s '%s' service uuid not found\n", - event.hostname.c_str(), + wlog ("%s '%s' service uuid not found\n", + event.hostname.c_str(), event.information.c_str()); event.status = FAIL_KEY_VALUE_PARSE ; } @@ -642,8 +642,8 @@ int tokenUtil_handler ( libEvent & event ) } else { - wlog ("%s '%s' service not found\n", - event.hostname.c_str(), + wlog ("%s '%s' service not found\n", + event.hostname.c_str(), event.information.c_str()); } } @@ -707,13 +707,13 @@ int tokenUtil_new_token ( libEvent & event, string hostname, bool blocking ) ilog ("%s Requesting Authentication Token\n", hostname.c_str()); httpUtil_event_init ( &event, - hostname, - "tokenUtil_new_token", + hostname, + "tokenUtil_new_token", _get_ip(), daemon_get_cfg_ptr()->keystone_port); event.hostname = _hn (); - + dlog ("%s fetching new token\n", event.hostname.c_str()); event.prefix_path = _get_keystone_prefix_path(); @@ -724,7 +724,7 @@ int tokenUtil_new_token ( libEvent & event, string hostname, bool blocking ) event.type = EVHTTP_REQ_POST ; event.timeout = HTTP_TOKEN_TIMEOUT ; event.handler = &tokenUtil_handler ; - + return ( httpUtil_api_request ( event )); } @@ -732,11 +732,11 @@ int tokenUtil_new_token ( libEvent & event, string hostname, bool blocking ) string tokenUtil_get_svc_uuid ( libEvent & event, string service_name ) { httpUtil_event_init ( &event, - service_name, - "tokenUtil_get_svc_uuid", + service_name, + "tokenUtil_get_svc_uuid", _get_ip(), 5000 ) ; // get_keystone_admin_port() ; - + event.hostname = _hn() ; /* The type of HTTP request */ @@ -766,8 +766,8 @@ string tokenUtil_get_svc_uuid ( libEvent & event, string service_name ) int tokenUtil_get_endpoints ( libEvent & event, string service_uuid ) { httpUtil_event_init ( &event, - service_uuid, - "tokenUtil_get_endpoints", + service_uuid, + "tokenUtil_get_endpoints", _get_ip(), 5000 ); // get_keystone_admin_port(); @@ -799,7 +799,7 @@ int tokenUtil_get_endpoints ( libEvent & event, string service_uuid ) return ( event.status ); } -int keystone_config_handler ( void * user, +int keystone_config_handler ( void * user, const char * section, const char * name, const char * value) @@ -833,33 +833,28 @@ int keystone_config_handler ( void * user, } } } - else if (MATCH("agent", "keyring_directory")) - { - config_ptr->keyring_directory = strdup(value); - ilog("Keyring Directory : %s\n", config_ptr->keyring_directory ); - } else if (MATCH("agent", "keystone_auth_username")) { config_ptr->keystone_auth_username = strdup(value); - ilog("Mtce Keystone username : %s\n", + ilog("Mtce Keystone username : %s\n", config_ptr->keystone_auth_username ); } else if (MATCH("agent", "keystone_auth_pw")) { config_ptr->keystone_auth_pw = strdup(value); - dlog("Mtce Keystone pw : %s\n", + dlog("Mtce Keystone pw : %s\n", config_ptr->keystone_auth_pw ); } else if (MATCH("agent", "keystone_auth_project")) { config_ptr->keystone_auth_project = strdup(value); - ilog("Mtce Keystone project : %s\n", + ilog("Mtce Keystone project : %s\n", config_ptr->keystone_auth_project ); } else if (MATCH("agent", "keystone_user_domain")) { config_ptr->keystone_user_domain = strdup(value); - ilog("Mtce Keystone user domain : %s\n", + ilog("Mtce Keystone user domain : %s\n", config_ptr->keystone_user_domain ); } else if (MATCH("agent", "keystone_project_domain")) diff --git a/mtce-common/src/common/tokenUtil.h b/mtce-common/src/common/tokenUtil.h index 7e269561..b0f54377 100644 --- a/mtce-common/src/common/tokenUtil.h +++ b/mtce-common/src/common/tokenUtil.h @@ -26,13 +26,11 @@ using namespace std; -#include "logMacros.h" +#include "logMacros.h" #include "httpUtil.h" /* for ... libEvent */ #define MTC_POST_KEY_LABEL "/v3/auth/tokens" -#define KEYSTONE_SIG "token" - /* The invalidation window is 5 minutes according * to the testing of token expiration time */ #define STALE_TOKEN_DURATION 300 //5 minutes diff --git a/mtce-common/src/daemon/daemon_common.h b/mtce-common/src/daemon/daemon_common.h index 6215dcb1..efd48d3f 100755 --- a/mtce-common/src/daemon/daemon_common.h +++ b/mtce-common/src/daemon/daemon_common.h @@ -169,6 +169,11 @@ int sysinv_config_handler ( void * user, const char * name, const char * value); +int barbican_config_handler ( void * user, + const char * section, + const char * name, + const char * value); + int client_timeout_handler ( void * user, const char * section, const char * name, @@ -225,6 +230,7 @@ int daemon_run_testhead ( void ); #define CONFIG_MTC_TO_HBS_CMD_PORT 0x04000000 /**< Mtce to Hbs Command Port */ #define CONFIG_HBS_TO_MTC_EVENT_PORT 0x08000000 /**< Hbs to Mtc Event Port */ #define CONFIG_CLIENT_PULSE_PORT 0x10000000 /**< Pmon pulse port */ +#define CONFIG_AGENT_SECRET_PORT 0x20000000 /**< Barbican HTTP port */ #define CONFIG_AGENT_VIM_EVENT_PORT 0x40000000 /**< VIM Event Port Mask */ #define CONFIG_CLIENT_RMON_PORT 0x80000000 /**< Rmon client port */ diff --git a/mtce-common/src/daemon/daemon_config.cpp b/mtce-common/src/daemon/daemon_config.cpp index e11212c1..0fb71094 100644 --- a/mtce-common/src/daemon/daemon_config.cpp +++ b/mtce-common/src/daemon/daemon_config.cpp @@ -40,7 +40,6 @@ void daemon_config_default ( daemon_config_type* config_ptr ) config_ptr->keystone_auth_uri = strdup(""); config_ptr->keystone_auth_host = strdup(""); config_ptr->keystone_region_name = strdup("none"); - config_ptr->keyring_directory = strdup(""); config_ptr->sysinv_mtc_inv_label = strdup("none"); config_ptr->mgmnt_iface = strdup("none"); config_ptr->infra_iface = strdup("none"); @@ -48,6 +47,7 @@ void daemon_config_default ( daemon_config_type* config_ptr ) config_ptr->mode = strdup("none"); config_ptr->fit_host = strdup("none"); config_ptr->multicast = strdup("none"); + config_ptr->barbican_api_host = strdup("none"); config_ptr->debug_all = 0 ; config_ptr->debug_json = 0 ; @@ -264,6 +264,27 @@ int sysinv_config_handler ( void * user, return (PASS); } +/* Openstack Barbican Config Reader */ +int barbican_config_handler ( void * user, + const char * section, + const char * name, + const char * value) +{ + daemon_config_type* config_ptr = (daemon_config_type*)user; + + if (MATCH("DEFAULT", "bind_port")) // bind_port=9311 + { + config_ptr->barbican_api_port = atoi(value); + ilog("Barbican Port : %d\n", config_ptr->barbican_api_port ); + } + else if (MATCH("DEFAULT", "bind_host")) // bind_host=192.168.204.2 + { + config_ptr->barbican_api_host = strdup(value); + ilog("Barbican Host : %s\n", config_ptr->barbican_api_host ); + } + return (PASS); +} + #define EMPTY "----" void daemon_dump_cfg ( void ) @@ -306,7 +327,8 @@ void daemon_dump_cfg ( void ) if ( ptr->keystone_user_domain ) { ilog ("keystone_user_domain = %s\n", ptr->keystone_user_domain );} if ( ptr->keystone_project_domain ) { ilog ("keystone_project_domain = %s\n", ptr->keystone_project_domain );} if ( ptr->keystone_region_name ) { ilog ("keystone_region_name = %s\n", ptr->keystone_region_name );} - if ( ptr->keyring_directory ) { ilog ("keyring_directory = %s\n", ptr->keyring_directory );} + if ( ptr->barbican_api_port ) { ilog ("barbican_api_port = %d\n", ptr->barbican_api_port );} + if ( ptr->barbican_api_host ) { ilog ("barbican_api_host = %s\n", ptr->barbican_api_host );} if ( ptr->mtc_rx_mgmnt_port ) { ilog ("mtc_rx_mgmnt_port = %d\n", ptr->mtc_rx_mgmnt_port );} if ( ptr->mtc_rx_infra_port ) { ilog ("mtc_rx_infra_port = %d\n", ptr->mtc_rx_infra_port );} diff --git a/mtce/src/common/nodeClass.cpp b/mtce/src/common/nodeClass.cpp index 2069cdc2..49c73d21 100755 --- a/mtce/src/common/nodeClass.cpp +++ b/mtce/src/common/nodeClass.cpp @@ -28,6 +28,7 @@ using namespace std; #include "threadUtil.h" #include "nodeClass.h" #include "nodeUtil.h" +#include "secretUtil.h" #include "mtcNodeMsg.h" /* for ... send_mtc_cmd */ #include "nlEvent.h" /* for ... get_netlink_events */ #include "daemon_common.h" @@ -649,6 +650,7 @@ nodeLinkClass::node* nodeLinkClass::addNode( string hostname ) ptr->cfgEvent.base = NULL ; ptr->sysinvEvent.base= NULL ; ptr->vimEvent.base = NULL ; + ptr->secretEvent.base= NULL ; ptr->httpReq.base = NULL ; ptr->libEvent_done_fifo.clear(); @@ -664,17 +666,19 @@ nodeLinkClass::node* nodeLinkClass::addNode( string hostname ) ptr->sysinvEvent.conn= NULL ; ptr->vimEvent.conn = NULL ; ptr->httpReq.conn = NULL ; + ptr->secretEvent.conn= NULL ; ptr->cfgEvent.req = NULL ; ptr->sysinvEvent.req = NULL ; ptr->vimEvent.req = NULL ; ptr->httpReq.req = NULL ; - + ptr->secretEvent.req = NULL ; ptr->cfgEvent.buf = NULL ; ptr->sysinvEvent.buf = NULL ; ptr->vimEvent.buf = NULL ; ptr->httpReq.buf = NULL ; + ptr->secretEvent.buf = NULL ; /* log throttles */ ptr->stall_recovery_log_throttle = 0 ; @@ -838,10 +842,21 @@ struct nodeLinkClass::node* nodeLinkClass::getEventBaseNode ( libEvent_enum requ return ptr ; } } + case BARBICAN_GET_SECRET: + case BARBICAN_READ_SECRET: + { + if ( ptr->secretEvent.base == base_ptr ) + { + hlog1 ("%s Found secretEvent Base Pointer (%p) \n", + ptr->hostname.c_str(), ptr->secretEvent.base); + + return ptr ; + } + } default: ; } /* End Switch */ - + if (( ptr->next == NULL ) || ( ptr == tail )) break ; } @@ -2428,9 +2443,10 @@ int nodeLinkClass::mod_host ( node_inv_type & inv ) /* BM is already provisioned but is now deprovisioned */ else if (( bm_type_was_valid == true ) && ( bm_type_now_valid == false )) { - node_ptr->bm_type = NONE ; - node_ptr->bm_ip = NONE ; - node_ptr->bm_un = NONE ; + node_ptr->bm_type = NONE ; + node_ptr->bm_ip = NONE ; + node_ptr->bm_un = NONE ; + node_ptr->bm_pw = NONE ; mtcAlarm_log ( node_ptr->hostname, MTC_LOG_ID__COMMAND_BM_DEPROVISIONED ); set_bm_prov ( node_ptr, false ); } @@ -3953,10 +3969,16 @@ int nodeLinkClass::set_bm_prov ( struct nodeLinkClass::node * node_ptr, bool sta bmc_access_data_init ( node_ptr ); node_ptr->bm_ping_info.timer_handler = &mtcTimer_handler ; - node_ptr->thread_extra_info.bm_pw = - node_ptr->bm_pw = - get_bm_password (node_ptr->uuid.data()); + barbicanSecret_type * secret = secretUtil_find_secret( node_ptr->uuid ); + if ( secret ) + { + secret->reference.clear() ; + secret->payload.clear() ; + secret->stage = MTC_SECRET__START ; + } + mtcTimer_start( node_ptr->bm_timer, mtcTimer_handler, SECRET_START_DELAY ); + node_ptr->thread_extra_info.bm_pw.clear() ; node_ptr->thread_extra_info.bm_ip = node_ptr->bm_ip ; node_ptr->thread_extra_info.bm_un = node_ptr->bm_un ; diff --git a/mtce/src/common/nodeClass.h b/mtce/src/common/nodeClass.h index f879351f..bd38d78c 100755 --- a/mtce/src/common/nodeClass.h +++ b/mtce/src/common/nodeClass.h @@ -35,7 +35,7 @@ using namespace std; #include "httpUtil.h" /* for ... libevent stuff */ #include "ipmiUtil.h" /* for ... mc_info_type */ #include "mtcHttpUtil.h" /* for ... libevent stuff */ -#include "mtcSmgrApi.h" /* */ +#include "mtcSmgrApi.h" /* for ... mtcSmgrApi_request/handler */ #include "alarmUtil.h" /* for ... SFmAlarmDataT */ #include "mtcAlarm.h" /* for ... MTC_ALARM_ID__xx and utils */ #include "mtcThreads.h" /* for ... mtcThread_ipmitool */ @@ -455,8 +455,9 @@ private: * based on each service */ libEvent sysinvEvent; /**< Sysinv REST API Handling for host */ - libEvent cfgEvent; /**< Sysinv REST API Handling for config changes */ + libEvent cfgEvent ; /**< Sysinv REST API Handling for config changes */ libEvent vimEvent ; /**< VIM Event REST API Handling */ + libEvent secretEvent; libEvent httpReq ; /**< Http libEvent Request Handling */ libEvent thisReq ; /**< Http libEvent Request Handling */ @@ -1110,7 +1111,7 @@ private: int mtcSmgrApi_request ( struct nodeLinkClass::node * node_ptr, mtc_cmd_enum operation, int retries ); /* Private VIM API */ - int mtcVimApi_state_change ( struct nodeLinkClass::node * node_ptr, libEvent_enum operation, int retries ); + int mtcVimApi_state_change ( struct nodeLinkClass::node * node_ptr, libEvent_enum operation, int retries ); int set_bm_prov ( struct nodeLinkClass::node * node_ptr, bool state ); @@ -1926,12 +1927,6 @@ public: void mtcHttpUtil_handler ( struct evhttp_request *req, void *arg ); - /* Update the authentication token as a work queue'd command */ - int mtcKeyApi_refresh_token ( string hostname ); - - /* Update the authentication token now ; as a blocking request */ - int mtcKeyApi_get_token ( string hostname ); - /*********************** Public Heartbeat Interfaces *********************/ /** Creates a linked list of nodes to heartbeat for the specified port diff --git a/mtce/src/heartbeat/Makefile b/mtce/src/heartbeat/Makefile index 549f0e04..e36de539 100755 --- a/mtce/src/heartbeat/Makefile +++ b/mtce/src/heartbeat/Makefile @@ -9,7 +9,7 @@ SHELL = /bin/bash SRCS = hbsAlarm.cpp hbsClient.cpp hbsAgent.cpp hbsPmon.cpp hbsUtil.cpp hbsCluster.cpp hbsStubs.cpp OBJS = $(SRCS:.cpp=.o) -LDLIBS = -lstdc++ -ldaemon -lcommon -lthreadUtil -lpthread -lfmcommon -lalarm -lrt -lamon -lcrypto -luuid -ljson-c +LDLIBS = -lstdc++ -ldaemon -lcommon -lthreadUtil -lpthread -lfmcommon -lalarm -lrt -lamon -lcrypto -luuid -ljson-c -levent INCLUDES = -I. -I/usr/include/mtce-daemon -I/usr/include/mtce-common INCLUDES += -I../common -I../alarm -I../maintenance -I../public diff --git a/mtce/src/heartbeat/hbsStubs.cpp b/mtce/src/heartbeat/hbsStubs.cpp index fbd68067..d0675d88 100644 --- a/mtce/src/heartbeat/hbsStubs.cpp +++ b/mtce/src/heartbeat/hbsStubs.cpp @@ -226,7 +226,6 @@ int nodeLinkClass::mtcSmgrApi_request ( struct nodeLinkClass::node * node_ptr, m return(PASS); } - void mtcTimer_handler ( int sig, siginfo_t *si, void *uc) { UNUSED(sig); diff --git a/mtce/src/hwmon/hwmonClass.cpp b/mtce/src/hwmon/hwmonClass.cpp index f7587094..b897ab1e 100644 --- a/mtce/src/hwmon/hwmonClass.cpp +++ b/mtce/src/hwmon/hwmonClass.cpp @@ -7,6 +7,7 @@ #include "nodeBase.h" #include "tokenUtil.h" +#include "secretUtil.h" #include "hwmonClass.h" #include "hwmonUtil.h" #include "hwmonIpmi.h" @@ -128,6 +129,7 @@ struct hwmonHostClass::hwmon_host* hwmonHostClass::addHost( string hostname ) ptr->ping_info.timer_handler = &hwmonTimer_handler ; mtcTimer_init ( ptr->hostTimer, ptr->hostname, "host timer" ); mtcTimer_init ( ptr->addTimer, ptr->hostname, "add timer" ); + mtcTimer_init ( ptr->secretTimer, ptr->hostname, "secret timer" ); mtcTimer_init ( ptr->relearnTimer, ptr->hostname, "relearn timer" ); mtcTimer_init ( ptr->ping_info.timer, ptr->hostname, "ping monitor timer" ); @@ -144,6 +146,11 @@ struct hwmonHostClass::hwmon_host* hwmonHostClass::addHost( string hostname ) ptr->event.req = NULL ; ptr->event.buf = NULL ; + ptr->secretEvent.base= NULL ; + ptr->secretEvent.conn= NULL ; + ptr->secretEvent.req = NULL ; + ptr->secretEvent.buf = NULL ; + /* If the host list is empty add it to the head */ if( hwmon_head == NULL ) { @@ -180,6 +187,7 @@ void hwmonHostClass::free_host_timers ( struct hwmon_host * ptr ) { mtcTimer_fini ( ptr->hostTimer ); mtcTimer_fini ( ptr->addTimer ); + mtcTimer_fini ( ptr->secretTimer ); mtcTimer_fini ( ptr->relearnTimer ); mtcTimer_fini ( ptr->ping_info.timer ); @@ -195,7 +203,7 @@ int hwmonHostClass::remHost( string hostname ) if ( hwmon_head == NULL ) return -ENXIO ; - + struct hwmon_host * ptr = hwmonHostClass::getHost ( hostname ); if ( ptr == NULL ) @@ -263,15 +271,15 @@ struct hwmonHostClass::hwmon_host* hwmonHostClass::getHost ( string hostname ) } /* - * Allocates memory for a new host and stores its the address in host_ptrs + * Allocates memory for a new host and stores its the address in host_ptrs * * @param void * @return pointer to the newly allocted host memory - */ + */ struct hwmonHostClass::hwmon_host * hwmonHostClass::newHost ( void ) { struct hwmonHostClass::hwmon_host * temp_host_ptr = NULL ; - + if ( memory_allocs == 0 ) { memset ( host_ptrs, 0 , sizeof(struct hwmon_host *)*MAX_HOSTS); @@ -428,7 +436,7 @@ void hwmonHostClass::degrade_state_audit ( struct hwmonHostClass::hwmon_host * h } /* Frees the memory of a pre-allocated host and removes - * it from the host_ptrs list + * it from the host_ptrs list * @param host * pointer to the host memory address to be freed * @return int return code { PASS or -EINVAL } */ @@ -451,14 +459,14 @@ int hwmonHostClass::delHost ( struct hwmonHostClass::hwmon_host * host_ptr ) } else elog ( "Error: Free memory called when there is no memory to free\n" ); - + return -EINVAL ; } void hwmonHostClass::clear_bm_assertions ( struct hwmonHostClass::hwmon_host * host_ptr ) { /* Loop over all sensors and groups - * - clear any outstanding alarms + * - clear any outstanding alarms * - clear degrade of host * ... while we deprovision the BMC */ for ( int i = 0 ; i < host_ptr->sensors ; i++ ) @@ -475,9 +483,9 @@ void hwmonHostClass::clear_bm_assertions ( struct hwmonHostClass::hwmon_host * h { hwmonAlarm_clear ( host_ptr->hostname, HWMON_ALARM_ID__SENSORGROUP, host_ptr->group[g].group_name, REASON_DEPROVISIONED ); } - + /* send the degrade anyway , just to be safe */ - hwmon_send_event ( host_ptr->hostname, MTC_DEGRADE_CLEAR , "sensors" ); + hwmon_send_event ( host_ptr->hostname, MTC_DEGRADE_CLEAR , "sensors" ); /* Bug Fix: This was outside the if bm_provisioned clause causing it * to be called even if the bmc was not already provisioned @@ -485,9 +493,6 @@ void hwmonHostClass::clear_bm_assertions ( struct hwmonHostClass::hwmon_host * h hwmonAlarm_clear ( host_ptr->hostname, HWMON_ALARM_ID__SENSORCFG, "sensors", REASON_DEPROVISIONED ); } - - - int hwmonHostClass::set_bm_prov ( struct hwmonHostClass::hwmon_host * host_ptr, bool state ) { int rc = FAIL_HOSTNAME_LOOKUP ; @@ -510,7 +515,18 @@ int hwmonHostClass::set_bm_prov ( struct hwmonHostClass::hwmon_host * host_ptr, host_ptr->ping_info.ip = host_ptr->bm_ip ; host_ptr->ping_info.hostname = host_ptr->hostname ; ipmi_bmc_data_init ( host_ptr ); - host_ptr->thread_extra_info.bm_pw = host_ptr->bm_pw = get_bm_password (hostBase.get_uuid(host_ptr->hostname).data()); + + string host_uuid = hostBase.get_uuid( host_ptr->hostname ); + barbicanSecret_type * secret = secretUtil_find_secret( host_uuid ); + if ( secret ) + { + secret->reference.clear() ; + secret->payload.clear() ; + secret->stage = MTC_SECRET__START ; + } + mtcTimer_start( host_ptr->secretTimer, hwmonTimer_handler, SECRET_START_DELAY ); + + host_ptr->thread_extra_info.bm_pw.clear() ; host_ptr->thread_extra_info.bm_ip = host_ptr->bm_ip ; host_ptr->thread_extra_info.bm_un = host_ptr->bm_un ; } @@ -709,6 +725,7 @@ int hwmonHostClass::add_host ( node_inv_type & inv ) host_ptr->sensor_query_count = 0 ; /* Sensor Monitoring Thread 'Extra Request Information' */ + host_ptr->empty_secret_log_throttle = 0 ; host_ptr->thread_extra_info.bm_ip = host_ptr->bm_ip ; host_ptr->thread_extra_info.bm_un = host_ptr->bm_un ; host_ptr->thread_extra_info.bm_pw.clear() ; @@ -779,7 +796,7 @@ int hwmonHostClass::rem_host ( string hostname ) hwmonHostClass::remHost ( hostname ); slog ("potential memory leak !\n"); } - + /* Now remove the service specific component */ hostlist.remove ( hostname ); } @@ -814,7 +831,7 @@ int hwmonHostClass::del_host ( string hostname ) { int rc = FAIL_DEL_UNKNOWN ; hwmonHostClass::hwmon_host * hwmon_host_ptr = hwmonHostClass::getHost( hostname ); - if ( hwmon_host_ptr ) + if ( hwmon_host_ptr ) { rc = rem_host ( hostname ); if ( rc == PASS ) @@ -838,7 +855,7 @@ int hwmonHostClass::mon_host ( string hostname, bool monitor ) { int rc = FAIL_UNKNOWN_HOSTNAME ; hwmonHostClass::hwmon_host * hwmon_host_ptr = hwmonHostClass::getHost( hostname ); - if ( hwmon_host_ptr ) + if ( hwmon_host_ptr ) { bool change = false ; string want_state = "" ; @@ -1013,6 +1030,10 @@ struct hwmonHostClass::hwmon_host * hwmonHostClass::getHost_timer ( timer_t tid { return host_ptr ; } + if ( host_ptr->secretTimer.tid == tid ) + { + return host_ptr ; + } if ( host_ptr->ping_info.timer.tid == tid ) { return host_ptr ; @@ -1166,7 +1187,7 @@ int hwmonHostClass::add_sensor ( string hostname, sensor_type & sensor ) if ( rc ) { - elog ("%s '%s' sensor add failed\n", hostname.c_str() , + elog ("%s '%s' sensor add failed\n", hostname.c_str(), sensor.sensorname.c_str()); } return (rc); @@ -1197,8 +1218,8 @@ struct sensor_group_type * hwmonHostClass::hwmon_get_sensorgroup ( string hostna { if ( !host_ptr->group[g].sensor_ptr[s]->sensorname.compare(entity_path) ) { - blog ("%s '%s' sensor found in '%s' group\n", - hostname.c_str(), + blog ("%s '%s' sensor found in '%s' group\n", + hostname.c_str(), host_ptr->group[g].sensor_ptr[s]->sensorname.c_str(), host_ptr->group[g].group_name.c_str()); @@ -1229,7 +1250,7 @@ struct sensor_group_type * hwmonHostClass::hwmon_get_sensorgroup ( string hostna * * Name : hwmon_get_group * - * Description : Returns a pointer to the sensor group that matches the supplied + * Description : Returns a pointer to the sensor group that matches the supplied * group name. * **********************************************************************************/ @@ -1247,8 +1268,8 @@ struct sensor_group_type * hwmonHostClass::hwmon_get_group ( string hostname, st { if ( !group_name.compare(host_ptr->group[i].group_name)) { - blog ("%s '%s' sensor group found\n", - hostname.c_str(), + blog ("%s '%s' sensor group found\n", + hostname.c_str(), host_ptr->group[i].group_name.c_str()); return (&host_ptr->group[i]) ; @@ -1306,7 +1327,7 @@ int hwmonHostClass::hwmon_add_group ( string hostname, struct sensor_group_type host_ptr->group[i].hostname = hostname ; host_ptr->interval_changed = true ; - + host_ptr->group[i].group_interval = group.group_interval ; host_ptr->group[i].sensortype = group.sensortype ; @@ -1349,7 +1370,7 @@ int hwmonHostClass::hwmon_add_group ( string hostname, struct sensor_group_type if ( rc ) { - elog ("%s '%s' sensor group add failed\n", hostname.c_str() , + elog ("%s '%s' sensor group add failed\n", hostname.c_str(), group.group_name.c_str()); } return (rc); @@ -1377,8 +1398,8 @@ int hwmonHostClass::add_group_uuid ( string & hostname, string & group_name, st { if ( !group_name.compare(host_ptr->group[i].group_name)) { - blog1 ("%s '%s' sensor group found\n", - hostname.c_str(), + blog1 ("%s '%s' sensor group found\n", + hostname.c_str(), host_ptr->group[i].group_name.c_str()); host_ptr->group[i].group_uuid = uuid ; @@ -1418,8 +1439,8 @@ int hwmonHostClass::add_sensor_uuid ( string & hostname, string & sensorname, s { if ( !sensorname.compare(host_ptr->sensor[i].sensorname)) { - blog1 ("%s '%s' sensor found\n", - hostname.c_str(), + blog1 ("%s '%s' sensor found\n", + hostname.c_str(), host_ptr->sensor[i].sensorname.c_str()); host_ptr->sensor[i].uuid = uuid ; @@ -2352,7 +2373,6 @@ void hwmonHostClass::mem_log_groups ( struct hwmonHostClass::hwmon_host * host_p done = true ; } if ((( x % 8 == 0 ) & ( x != 0 )) || ( done == true )) - // if ( done == true ) { if ( first == true ) { diff --git a/mtce/src/hwmon/hwmonClass.h b/mtce/src/hwmon/hwmonClass.h index 7cb7b6cb..b1afd730 100644 --- a/mtce/src/hwmon/hwmonClass.h +++ b/mtce/src/hwmon/hwmonClass.h @@ -49,6 +49,10 @@ class hwmonHostClass bool bm_provisioned ; + int empty_secret_log_throttle ; + + libEvent secretEvent ; + /** set true once a connection is estabished and * set false when error recovery is performed on the connection **/ @@ -91,12 +95,13 @@ class hwmonHostClass /** Pointer to the previous host in the list */ struct hwmon_host * prev; - + /** Pointer to the next host in the list */ struct hwmon_host * next; struct mtc_timer hostTimer ; struct mtc_timer addTimer ; + struct mtc_timer secretTimer ; bool monitor ; /* true if host's sensors are to be monitored */ @@ -232,9 +237,9 @@ class hwmonHostClass int memory_allocs ; /** A memory used counter - * + * * A variable storing the accumulated host memory - */ + */ int memory_used ; struct hwmon_host * hwmon_head ; /**< Host Linked List Head pointer */ @@ -458,7 +463,7 @@ class hwmonHostClass void timer_handler ( int sig, siginfo_t *si, void *uc); - /** This is a list of host names. */ + /** This is a list of host names. */ std::list hostlist ; std::list::iterator hostlist_iter_ptr ; @@ -476,7 +481,7 @@ class hwmonHostClass int hosts ; /* This bool is set in the daemon_configure case to inform the - * FSM that there has been a configuration reload. + * FSM that there has been a configuration reload. * The initial purpose if this bool is to trigger a full sensor * dump of all hosts on demand */ bool config_reload ; @@ -506,7 +511,7 @@ class hwmonHostClass * Name: get_sensor * * Description: Returns a pointer to the host sensor - * that matches the supplied sensor name. + * that matches the supplied sensor name. * ****************************************************************************/ sensor_type * get_sensor ( string hostname, string sensorname ); @@ -515,7 +520,7 @@ class hwmonHostClass * * Name: add_sensor * - * Description: If the return code is PASS then the supplied sensor is + * Description: If the return code is PASS then the supplied sensor is * provisioned against this host. If the sensor already exists * then it is updated with all the new information. Otherwise * (normally) a new sensor is added. @@ -532,13 +537,13 @@ class hwmonHostClass * ****************************************************************************/ int add_sensor_uuid ( string & hostname, string & name, string & uuid ); - + /**************************************************************************** * * Name: hwmon_get_group * * Description: Returns a pointer to the host sensor group - * that matches the supplied sensor group name. + * that matches the supplied sensor group name. ****************************************************************************/ struct sensor_group_type * hwmon_get_group ( string hostname, string group_name ); @@ -547,7 +552,7 @@ class hwmonHostClass * Name: hwmon_get_sensorgroup * * Description: Returns a pointer to the host sensor group - * that matches the supplied sensor name. + * that matches the supplied sensor name. ****************************************************************************/ struct sensor_group_type * hwmon_get_sensorgroup ( string hostname, string sensorname ); @@ -555,7 +560,7 @@ class hwmonHostClass * * Name: hwmon_add_group * - * Description: If the return code is PASS then the supplied sensor group is + * Description: If the return code is PASS then the supplied sensor group is * provisioned against this host. If the group already exists * then it is updated with all the new information. Otherwise * (normally) a new group is added to the hwmon class struct. diff --git a/mtce/src/hwmon/hwmonFsm.cpp b/mtce/src/hwmon/hwmonFsm.cpp index 6faa216b..789a298d 100644 --- a/mtce/src/hwmon/hwmonFsm.cpp +++ b/mtce/src/hwmon/hwmonFsm.cpp @@ -16,7 +16,7 @@ #include "hwmonHttp.h" #include "hwmonSensor.h" #include "hwmonThreads.h" /* for ... ipmitool_thread */ - +#include "secretUtil.h" /************************************************************************** @@ -155,9 +155,19 @@ void hwmonHostClass::hwmon_fsm ( void ) #endif if (( host_ptr->thread_extra_info.bm_pw.empty ()) && ( host_ptr->ping_info.ok == true )) { - wlog ( "%s bm password is empty ; learning and forcing reconnect\n", host_ptr->hostname.c_str()); - host_ptr->ping_info.ok = false ; - host_ptr->thread_extra_info.bm_pw = host_ptr->bm_pw = get_bm_password (hostBase.get_uuid(host_ptr->hostname).data()); + string host_uuid = hostBase.get_uuid(host_ptr->hostname); + wlog_throttled ( host_ptr->empty_secret_log_throttle, 20, + "%s bm password is empty ; learning and forcing reconnect\n", + host_ptr->hostname.c_str()); + barbicanSecret_type * secret = secretUtil_manage_secret( host_ptr->secretEvent, + host_uuid, + host_ptr->secretTimer, + hwmonTimer_handler ); + if ( secret->stage == MTC_SECRET__GET_PWD_RECV ) + { + host_ptr->ping_info.ok = false ; + host_ptr->thread_extra_info.bm_pw = host_ptr->bm_pw = secret->payload ; + } } else if ( host_ptr->accessible ) { diff --git a/mtce/src/hwmon/hwmonHdlr.cpp b/mtce/src/hwmon/hwmonHdlr.cpp index 95200451..304fb554 100644 --- a/mtce/src/hwmon/hwmonHdlr.cpp +++ b/mtce/src/hwmon/hwmonHdlr.cpp @@ -236,6 +236,12 @@ void hwmonHostClass::timer_handler ( int sig, siginfo_t *si, void *uc) hwmon_host_ptr->relearn = false ; return ; } + else if (( *tid_ptr == hwmon_host_ptr->secretTimer.tid ) ) + { + mtcTimer_stop_int_safe ( hwmon_host_ptr->secretTimer ); + hwmon_host_ptr->secretTimer.ring = true ; + return ; + } } } mtcTimer_stop_tid_int_safe (tid_ptr); diff --git a/mtce/src/hwmon/hwmonInit.cpp b/mtce/src/hwmon/hwmonInit.cpp index 92174004..70f76ffb 100644 --- a/mtce/src/hwmon/hwmonInit.cpp +++ b/mtce/src/hwmon/hwmonInit.cpp @@ -151,6 +151,12 @@ int daemon_configure ( void ) return (FAIL_LOAD_INI); } + if (ini_parse(SECRET_CFG_FILE, barbican_config_handler, &hwmon_config) < 0) + { + elog ("Can't load '%s'\n", SECRET_CFG_FILE ); + return (FAIL_LOAD_INI); + } + /* tell the host service that there has been a config reload */ obj_ptr->config_reload = true ; diff --git a/mtce/src/maintenance/Makefile b/mtce/src/maintenance/Makefile index 875178fe..d2a13484 100755 --- a/mtce/src/maintenance/Makefile +++ b/mtce/src/maintenance/Makefile @@ -21,7 +21,6 @@ SRCS += mtcHttpSvr.cpp SRCS += mtcWorkQueue.cpp SRCS += mtcInvApi.cpp SRCS += mtcSmgrApi.cpp -SRCS += mtcKeyApi.cpp SRCS += mtcCmdHdlr.cpp SRCS += mtcNodeMnfa.cpp SRCS += mtcVimApi.cpp @@ -42,7 +41,6 @@ CONTROL_OBJS += mtcCtrlMsg.o CONTROL_OBJS += mtcWorkQueue.o CONTROL_OBJS += mtcInvApi.o CONTROL_OBJS += mtcSmgrApi.o -CONTROL_OBJS += mtcKeyApi.o CONTROL_OBJS += mtcHttpUtil.o CONTROL_OBJS += mtcHttpSvr.o CONTROL_OBJS += mtcCmdHdlr.o diff --git a/mtce/src/maintenance/mtcHttpUtil.cpp b/mtce/src/maintenance/mtcHttpUtil.cpp index 73cce49f..71c30f7d 100755 --- a/mtce/src/maintenance/mtcHttpUtil.cpp +++ b/mtce/src/maintenance/mtcHttpUtil.cpp @@ -680,6 +680,7 @@ int mtcHttpUtil_api_request ( libEvent & event ) event.type = EVHTTP_REQ_PATCH ; } } + else { slog ("%s Unsupported Request (%d)\n", event.hostname.c_str(), event.request); @@ -826,6 +827,7 @@ int mtcHttpUtil_api_request ( libEvent & event ) } else { + jlog ("%s API Address : %s\n", event.hostname.c_str(), event.token.url.c_str()); event.status = evhttp_make_request ( event.conn, event.req, event.type, event.token.url.data()); } if ( event.status == PASS ) diff --git a/mtce/src/maintenance/mtcInvApi.cpp b/mtce/src/maintenance/mtcInvApi.cpp index b90c6521..242626dc 100755 --- a/mtce/src/maintenance/mtcInvApi.cpp +++ b/mtce/src/maintenance/mtcInvApi.cpp @@ -49,7 +49,6 @@ #include "nodeUtil.h" /* for ... Utility Service Header */ #include "jsonUtil.h" /* for ... Json utilities */ #include "mtcInvApi.h" /* this .. module header */ -#include "mtcKeyApi.h" /* for ... keystone service utilities */ #include "mtcNodeHdlrs.h" /* for ... mtcTimer_handler ( .. ) */ @@ -70,11 +69,6 @@ int mtcInvApi_read_inventory ( int batch ) nodeLinkClass * obj_ptr = get_mtcInv_ptr (); string hostname = obj_ptr->get_my_hostname(); - if ( rc != PASS ) - { - wlog ("Failed to get an authentication token ... requesting retry\n"); - return (RETRY); - } rc = mtcHttpUtil_event_init ( &obj_ptr->sysinvEvent, obj_ptr->my_hostname, diff --git a/mtce/src/maintenance/mtcKeyApi.cpp b/mtce/src/maintenance/mtcKeyApi.cpp deleted file mode 100755 index e1f99edd..00000000 --- a/mtce/src/maintenance/mtcKeyApi.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2013, 2015 Wind River Systems, Inc. -* -* SPDX-License-Identifier: Apache-2.0 -* - */ - - /** - * @file - * Wind River CGTS Platform Controller Maintenance - * Authentication Utility API - * - * mtcKeyApi_get_token - * _key_POST_request - Request a authentication token - * jsonApi_auth_request - * mtcHttpUtil_connect_new - * mtcHttpUtil_request_new - * mtcHttpUtil_header_add - * mtcHttpUtil_request_make - * evhttp_connection_set_timeout - * event_base_dispatch - * - * _key_POST_handler - called by libevent like an interrupt handler - * evbuffer_remove - reads the response data out of da resp buffer - * jsonApi_auth_load - extract the data we want from resp json string - * tokenid - load data: the 3604 byte authentication token - * adminURL - load data: the key address - * issued - load data: can use this later so that we - * expiry - load data: don't have to keep requesting tokens - * event_base_loopbreak - end the interrupt handler -*/ - -#ifdef __AREA__ -#undef __AREA__ -#endif -#define __AREA__ "key" - -#include "nodeClass.h" /* for ... maintenance class nodeLinkClass */ -#include "nodeUtil.h" -#include "httpUtil.h" /* for ... libEvent */ -#include "mtcKeyApi.h" /* for ... this module header */ -#include "jsonUtil.h" /* for ... Json utilities */ - -/* Token info is stored in the common public - * area of the maintenance nodelinkClass structure */ - -/* http://localhost:5000/v2.0/tokens -X POST -H "Content-Type: application/json" - * -H "Accept: application/json" - * -H "User-Agent: python-keyclient" - * -H "Connection: close" - * - * { - * "auth": - * { - * "tenantName": "services", - * "passwordCredentials": - * { - * "username": "mtce", - * "password": "password" - * } - * } - * } - * - */ -int throttle = 0 ; - -/* The handles the keystone POST request's response message */ -int mtcKeyApi_handler ( libEvent & event ) -{ - jsonUtil_auth_type info ; - string hn = event.hostname ; - int rc = PASS ; - - nodeLinkClass * obj_ptr = get_mtcInv_ptr () ; - - /* Copy the token info into the static libEvent tokenEvent struct */ - obj_ptr->tokenEvent = event ; - - if ( event.status ) - { - rc = obj_ptr->tokenEvent.status ; - elog ( "%s Token Request Failed (%d) \n", hn.c_str(), rc ); - } - else if ( jsonApi_auth_load ( hn, (char*)obj_ptr->tokenEvent.response.data(), info ) ) - { - rc = obj_ptr->tokenEvent.status = FAIL_JSON_PARSE ; - elog ( "%s Token Request Failed - Json Parse Error\n", hn.c_str()); - } - else - { - jlog ("%s Token Exp: %s\n", hn.c_str(), info.expiry.c_str() ); - jlog ("%s Admin URL: %s\n" ,hn.c_str(), info.adminURL.c_str() ); - jlog ("%s Token Len: %ld\n",hn.c_str(), info.tokenid.length() ); - obj_ptr->tokenEvent.token.issued = info.issued ; - obj_ptr->tokenEvent.token.expiry = info.expiry ; - obj_ptr->tokenEvent.token.token = info.tokenid ; - obj_ptr->tokenEvent.token.url = info.adminURL ; - obj_ptr->tokenEvent.status = PASS ; - if ( obj_ptr->token_refresh_rate ) - { - ilog ( "Token Refresh: [%s] [Expiry: %s %s]\n", - md5sum_string ( obj_ptr->tokenEvent.token.token).c_str(), - obj_ptr->tokenEvent.token.expiry.substr(0,10).c_str(), - obj_ptr->tokenEvent.token.expiry.substr(11,8).c_str()); - } - } - - /* Check for a response string */ - if ( obj_ptr->tokenEvent.token.token.empty() ) - { - elog ("%s Failed to get token\n", - obj_ptr->tokenEvent.hostname.c_str()); - rc = FAIL_TOKEN_GET; - } - - /* Check for Key URL */ - else if ( obj_ptr->tokenEvent.token.url.empty() ) - { - elog ("%s Failed to get token URL\n", - obj_ptr->tokenEvent.hostname.c_str()); - rc = FAIL_TOKEN_URL; - } - else - { - dlog ("%s Token Refresh O.K.\n", obj_ptr->tokenEvent.hostname.c_str()); - } - return (rc); -} - -void corrupt_token ( keyToken_type & key ) -{ - key.token.replace ( 800, 50, "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" ); -} - -/* fetches an authorization token as a blocking request */ -int nodeLinkClass::mtcKeyApi_get_token ( string hostname ) -{ - mtcHttpUtil_event_init ( &this->tokenEvent, - hostname, - "mtcKeyApi_get_token", - hostUtil_getServiceIp ( SERVICE_TOKEN ), - hostUtil_getServicePort ( SERVICE_TOKEN )); - - this->tokenEvent.prefix_path = hostUtil_getPrefixPath(); - this->tokenEvent.blocking = true ; - this->tokenEvent.request = KEYSTONE_TOKEN ; - this->tokenEvent.operation = KEYSTONE_SIG ; - - this->tokenEvent.token.token.clear() ; - this->tokenEvent.token.url.clear(); - this->tokenEvent.token.issued.clear(); - this->tokenEvent.token.expiry.clear(); - - ilog ("%s Prefix path: %s\n", hostname.c_str(), this->tokenEvent.prefix_path.c_str() ); - return ( mtcHttpUtil_api_request ( this->tokenEvent )); -} - -/* fetches an authorization token and key URL and UUID info */ -int nodeLinkClass::mtcKeyApi_refresh_token ( string hostname ) -{ - GET_NODE_PTR(hostname); - mtcHttpUtil_event_init ( &node_ptr->httpReq, - hostname, - "mtcKeyApi_refresh_token", - hostUtil_getServiceIp ( SERVICE_TOKEN ), - hostUtil_getServicePort ( SERVICE_TOKEN )); - - node_ptr->httpReq.prefix_path = hostUtil_getPrefixPath(); - node_ptr->httpReq.hostname = hostname ; - node_ptr->httpReq.uuid = node_ptr->uuid ; - node_ptr->httpReq.request = KEYSTONE_TOKEN ; - node_ptr->httpReq.operation = KEYSTONE_SIG ; - node_ptr->httpReq.max_retries = 3 ; - node_ptr->httpReq.cur_retries = 0 ; - - node_ptr->httpReq.token.token.clear() ; - node_ptr->httpReq.token.url.clear(); - node_ptr->httpReq.token.issued.clear(); - node_ptr->httpReq.token.expiry.clear(); - - ilog ("%s Prefix path: %s\n", hostname.c_str(), this->tokenEvent.prefix_path.c_str() ); - return(this->workQueue_enqueue ( node_ptr->httpReq)); -} diff --git a/mtce/src/maintenance/mtcKeyApi.h b/mtce/src/maintenance/mtcKeyApi.h deleted file mode 100755 index 6e53aad4..00000000 --- a/mtce/src/maintenance/mtcKeyApi.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __INCLUDE_MTCKEYAPI_H__ -#define __INCLUDE_MTCKEYAPI_H__ -/* - * Copyright (c) 2013, 2016 Wind River Systems, Inc. -* -* SPDX-License-Identifier: Apache-2.0 -* - */ - -#include -#include - -#include "mtcHttpUtil.h" - -//#define MTC_POST_KEY_ADDR "localhost" -//#define MTC_POST_KEY_PORT 5000 -#define MTC_POST_KEY_LABEL "/v3/auth/tokens" - -int mtcKeyApi_init ( string ip, int port ); - -int mtcKeyApi_handler ( libEvent & event ); - -void corrupt_token ( keyToken_type & key ); - -#endif /* __INCLUDE_MTCKEYAPI_H__ */ diff --git a/mtce/src/maintenance/mtcNodeCtrl.cpp b/mtce/src/maintenance/mtcNodeCtrl.cpp index 75c26853..12c35fae 100644 --- a/mtce/src/maintenance/mtcNodeCtrl.cpp +++ b/mtce/src/maintenance/mtcNodeCtrl.cpp @@ -53,7 +53,7 @@ using namespace std; #include "mtcHttpSvr.h" /* for ... mtcHttpSvr_init/_fini/_look */ #include "mtcInvApi.h" /* */ #include "mtcSmgrApi.h" /* */ -#include "nlEvent.h" /* for ... open_netlink_socket */ +#include "nlEvent.h" /* for ... open_netlink_socket */ /************************************************************** * Implementation Structure @@ -237,19 +237,16 @@ static int mtc_config_handler ( void * user, config_ptr->ha_port = atoi(value); config_ptr->mask |= CONFIG_AGENT_HA_PORT ; } - else if (MATCH("agent", "inv_event_port")) { config_ptr->inv_event_port = atoi(value); config_ptr->mask |= CONFIG_AGENT_INV_EVENT_PORT ; } - else if (MATCH("agent", "keystone_port")) { config_ptr->keystone_port = atoi(value); config_ptr->mask |= CONFIG_AGENT_KEY_PORT ; } - else if (MATCH("agent", "mtc_agent_port")) { config_ptr->mtc_agent_port = atoi(value); @@ -482,6 +479,12 @@ int daemon_configure ( void ) return (FAIL_LOAD_INI); } + if (ini_parse(SECRET_CFG_FILE, barbican_config_handler, &mtc_config) < 0) + { + elog ("Can't load '%s'\n", SECRET_CFG_FILE ); + return (FAIL_LOAD_INI); + } + /* Loads key Mtce debug values that can override the defaults */ if (ini_parse(MTCE_CONF_FILE, debug_config_handler, &mtc_config) < 0) { @@ -653,6 +656,8 @@ int daemon_configure ( void ) ilog("guestAgent : %d (port)\n", mtc_config.mtc_to_guest_cmd_port ); ilog("hwmond : %d (port)\n", mtc_config.hwmon_cmd_port ); ilog("auth_host : %s \n", mtc_config.keystone_auth_host ); + ilog("Barbican Port: %d (rx)\n", mtc_config.barbican_api_port ); + ilog("Barbican Address : %s (tx)\n", mtc_config.barbican_api_host ); /* log system wide service based auto recovery control values */ ilog("AR Config : %d (threshold) %d sec (retry interval)", diff --git a/mtce/src/maintenance/mtcNodeHdlrs.cpp b/mtce/src/maintenance/mtcNodeHdlrs.cpp index 5ac7f72e..35343c3d 100755 --- a/mtce/src/maintenance/mtcNodeHdlrs.cpp +++ b/mtce/src/maintenance/mtcNodeHdlrs.cpp @@ -37,6 +37,7 @@ using namespace std; #include "jsonUtil.h" /* for ... jsonApi_array_value */ #include "tokenUtil.h" +#include "secretUtil.h" #include "regexUtil.h" /* for ... regexUtil_pattern_match */ #include "nodeClass.h" /* All base stuff */ @@ -5833,6 +5834,18 @@ int nodeLinkClass::bm_handler ( struct nodeLinkClass::node * node_ptr ) mtcTimer_start ( node_ptr->bmc_access_timer, mtcTimer_handler, MTC_MINS_2 ); } + if (( node_ptr->thread_extra_info.bm_pw.empty ()) && ( node_ptr->bm_ping_info.ok == true )) + { + barbicanSecret_type * secret = secretUtil_manage_secret( node_ptr->secretEvent, + node_ptr->uuid, + node_ptr->bm_timer, + mtcTimer_handler ); + if ( secret->stage == MTC_SECRET__GET_PWD_RECV ) + { + node_ptr->thread_extra_info.bm_pw = node_ptr->bm_pw = secret->payload ; + } + } + /* This block queries and logs BMC Info and last Reset Cause */ if (( node_ptr->bm_accessible == false ) && ( node_ptr->bm_ping_info.ok == true ) && @@ -5968,8 +5981,8 @@ int nodeLinkClass::bm_handler ( struct nodeLinkClass::node * node_ptr ) node_ptr->power_status_query_done = true ; node_ptr->ipmitool_thread_ctrl.done = true ; node_ptr->ipmitool_thread_info.command = 0 ; - node_ptr->bm_accessible = true ; node_ptr->bm_accessible = true ; + node_ptr->bm_ping_info.ok = true; mtcTimer_reset ( node_ptr->bmc_access_timer ); ilog ("%s %s\n", node_ptr->hostname.c_str(), diff --git a/mtce/src/scripts/mtc.conf b/mtce/src/scripts/mtc.conf index 898e8a3b..0060df60 100644 --- a/mtce/src/scripts/mtc.conf +++ b/mtce/src/scripts/mtc.conf @@ -25,6 +25,7 @@ mtc_to_hbs_cmd_port = 2104 ; Mtc to Hbs Command Port Number mtc_to_guest_cmd_port = 2108 ; Mtc to guestAgent Command port hbs_to_mtc_event_port = 2107 ; Hbs to Mtc Event Port Number inv_event_port = 2112 ; The Inventory Event Port Number +barbican_port = 9311 ; The Barbican Port Number token_refresh_rate = 1200 ; Authentication token refresh rate in seconds. ; A value of zero means no refresh.