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 <alex.kozyrev@windriver.com>
This commit is contained in:
Alex Kozyrev 2019-01-21 11:52:51 -05:00
parent b01f8ea964
commit 506ef3fd7f
36 changed files with 899 additions and 493 deletions

View File

@ -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" \

View File

@ -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

View File

@ -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)

View File

@ -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 );

View File

@ -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 );

View File

@ -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];
@ -375,7 +375,7 @@ int httpUtil_header_add ( libEvent * ptr, http_headers_type * hdrs_ptr )
{
/* Add the header */
rc = evhttp_add_header( ptr->req->output_headers,
hdrs_ptr->entry[i].key.c_str() ,
hdrs_ptr->entry[i].key.c_str(),
hdrs_ptr->entry[i].value.c_str());
if ( rc )
{
@ -554,7 +554,6 @@ void httpUtil_handler ( struct evhttp_request *req, void *arg )
event_ptr->status);
if ( event_ptr->type != EVHTTP_REQ_POST )
event_ptr->status = PASS ;
goto httpUtil_handler_done ;
}
@ -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);
@ -864,9 +868,18 @@ int httpUtil_api_request ( libEvent & event )
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
{

View File

@ -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,
@ -160,13 +183,16 @@ typedef enum {
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

View File

@ -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 )

View File

@ -56,6 +56,46 @@ typedef struct
string adminURL; /**< path to the nova server. */
} jsonUtil_auth_type ;
#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 );
@ -78,8 +118,9 @@ int jsonApi_auth_request ( string & hostname, string & payload );
/** 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 );

View File

@ -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/<release> */
char* sysinv_mtc_inv_label ; /**< =/v1/hosts/ */
int sysinv_api_port ; /**< =6385 */
char* sysinv_api_bind_ip ; /**< =<local floating 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 */

View File

@ -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")

View File

@ -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 )
{

View File

@ -77,7 +77,6 @@ int set_host_functions ( string nodetype_str,
bool is_goenabled ( int nodeType, bool pass );
string get_bm_password ( const char * username );
string get_strings_in_string_list ( std::list<string> & l );
bool is_string_in_string_list ( std::list<string> & l , string & str );
bool is_int_in_int_list ( std::list<int> & l , int & val );

View File

@ -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 <map>
#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<string, barbicanSecret_type> secretList;
barbicanSecret_type * secretUtil_find_secret ( string & host_uuid )
{
std::map<string, barbicanSecret_type>::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<string, barbicanSecret_type>::iterator it;
it = secretList.find( host_uuid );
if ( it == secretList.end() )
{
barbicanSecret_type secret;
secret.stage = MTC_SECRET__START;
it = secretList.insert( std::pair<string, barbicanSecret_type>( 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<string, barbicanSecret_type>::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<string, barbicanSecret_type>::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<string, barbicanSecret_type>::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 ) ;
}

View File

@ -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__ */

View File

@ -833,11 +833,6 @@ 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);

View File

@ -31,8 +31,6 @@ using namespace std;
#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

View File

@ -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 */

View File

@ -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 );}

View File

@ -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,6 +842,17 @@ 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 */
@ -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 ;

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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 );
@ -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() ;
@ -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);
@ -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);
@ -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 )
{

View File

@ -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
**/
@ -97,6 +101,7 @@ class hwmonHostClass
struct mtc_timer hostTimer ;
struct mtc_timer addTimer ;
struct mtc_timer secretTimer ;
bool monitor ; /* true if host's sensors are to be monitored */

View File

@ -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 )
{

View File

@ -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);

View File

@ -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 ;

View File

@ -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

View File

@ -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 )

View File

@ -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,

View File

@ -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));
}

View File

@ -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 <iostream>
#include <string>
#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__ */

View File

@ -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)",

View File

@ -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(),

View File

@ -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.