//============================================================================= // Entry Point //============================================================================= RU32 RPAL_THREAD_FUNC RpHcpI_mainThread ( rEvent isTimeToStop ) { RU32 ret = 0; RU64 nextBeaconTime = 0; rList cloudMessages = NULL; rSequence msg = NULL; rList newConfigurations = NULL; rList newNotifications = NULL; RPU8 newConfigurationHash = NULL; RU32 newHashSize = 0; rSequence staticConfig = NULL; RU8* tmpBuffer = NULL; RU32 tmpSize = 0; FORCE_LINK_THAT( HCP_IFACE ); CryptoLib_init(); getPrivileges(); // This is the event for the collectors, it is different than the // hbs proper event so that we can restart the collectors without // signaling hbs as a whole. if( NULL == ( g_hbs_state.isTimeToStop = rEvent_create( TRUE ) ) ) { return (RU32)-1; } // By default, no collectors are running rEvent_set( g_hbs_state.isTimeToStop ); // We attempt to load some initial config from the serialized // rSequence that can be patched in this binary. if( NULL != ( staticConfig = getStaticConfig() ) ) { if( rSequence_getBUFFER( staticConfig, RP_TAGS_HBS_ROOT_PUBLIC_KEY, &tmpBuffer, &tmpSize ) ) { hbs_cloud_pub_key = rpal_memory_duplicate( tmpBuffer, tmpSize ); if( NULL == hbs_cloud_pub_key ) { hbs_cloud_pub_key = hbs_cloud_default_pub_key; } rpal_debug_info( "loading hbs root public key from static config" ); } if( rSequence_getRU32( staticConfig, RP_TAGS_MAX_QUEUE_SIZE, &g_hbs_state.maxQueueNum ) ) { rpal_debug_info( "loading max queue size from static config" ); } else { g_hbs_state.maxQueueNum = HBS_EXFIL_QUEUE_MAX_NUM; } if( rSequence_getRU32( staticConfig, RP_TAGS_MAX_SIZE, &g_hbs_state.maxQueueSize ) ) { rpal_debug_info( "loading max queue num from static config" ); } else { g_hbs_state.maxQueueSize = HBS_EXFIL_QUEUE_MAX_SIZE; } rSequence_free( staticConfig ); } else { hbs_cloud_pub_key = hbs_cloud_default_pub_key; g_hbs_state.maxQueueNum = HBS_EXFIL_QUEUE_MAX_NUM; g_hbs_state.maxQueueSize = HBS_EXFIL_QUEUE_MAX_SIZE; } if( !rQueue_create( &g_hbs_state.outQueue, freeExfilEvent, g_hbs_state.maxQueueNum ) ) { rEvent_free( g_hbs_state.isTimeToStop ); return (RU32)-1; } // We simply enqueue a message to let the cloud know we're starting sendStartupEvent(); while( !rEvent_wait( isTimeToStop, (RU32)nextBeaconTime ) ) { nextBeaconTime = MSEC_FROM_SEC( HBS_DEFAULT_BEACON_TIMEOUT + ( rpal_rand() % HBS_DEFAULT_BEACON_TIMEOUT_FUZZ ) ); if( NULL != ( cloudMessages = beaconHome() ) ) { while( rList_getSEQUENCE( cloudMessages, RP_TAGS_MESSAGE, &msg ) ) { // Cloud message indicating next requested beacon time, as a Seconds delta if( rSequence_getTIMEDELTA( msg, RP_TAGS_TIMEDELTA, &nextBeaconTime ) ) { nextBeaconTime = MSEC_FROM_SEC( nextBeaconTime ); rpal_debug_info( "received set_next_beacon" ); } if( NULL == newConfigurations && rSequence_getLIST( msg, RP_TAGS_HBS_CONFIGURATIONS, &newConfigurations ) ) { rpal_debug_info( "received a new profile" ); if( rSequence_getBUFFER( msg, RP_TAGS_HASH, &newConfigurationHash, &newHashSize ) && newHashSize == CRYPTOLIB_HASH_SIZE ) { newConfigurations = rList_duplicate( newConfigurations ); rpal_memory_memcpy( &( g_hbs_state.currentConfigHash ), newConfigurationHash, CRYPTOLIB_HASH_SIZE ); g_hbs_state.isProfilePresent = TRUE; } else { newConfigurations = NULL; rpal_debug_error( "profile hash received is invalid" ); } } if( NULL == newNotifications && rSequence_getLIST( msg, RP_TAGS_HBS_CLOUD_NOTIFICATIONS, &newNotifications ) ) { rpal_debug_info( "received cloud events" ); newNotifications = rList_duplicate( newNotifications ); } } rList_free( cloudMessages ); } // If this is the initial boot and we have no profile yet, we'll load a dummy // blank profile and use our defaults. if( NULL == newConfigurations && !g_hbs_state.isProfilePresent && !rEvent_wait( isTimeToStop, 0 ) ) { newConfigurations = rList_new( RP_TAGS_HCP_MODULES, RPCM_SEQUENCE ); rpal_debug_info( "setting empty profile" ); } if( NULL != newConfigurations ) { // We try to be as responsive as possible when asked to quit // so if we happen to have received the signal during a beacon // we will action the quit instead of the config change. if( !rEvent_wait( isTimeToStop, 0 ) ) { rpal_debug_info( "begining sensor update on new profile" ); shutdownCollectors(); updateCollectorConfigs( newConfigurations ); rList_free( newConfigurations ); newConfigurations = NULL; startCollectors(); } else { rList_free( newConfigurations ); } newConfigurations = NULL; } if( NULL != newNotifications ) { if( !rEvent_wait( isTimeToStop, 0 ) ) { publishCloudNotifications( newNotifications ); } rList_free( newNotifications ); newNotifications = NULL; } } // We issue one last beacon indicating we are stopping sendShutdownEvent(); // Shutdown everything shutdownCollectors(); // Cleanup the last few resources rEvent_free( g_hbs_state.isTimeToStop ); rQueue_free( g_hbs_state.outQueue ); CryptoLib_deinit(); if( hbs_cloud_default_pub_key != hbs_cloud_pub_key && NULL != hbs_cloud_pub_key ) { rpal_memory_free( hbs_cloud_pub_key ); hbs_cloud_pub_key = NULL; } return ret; }
RBOOL rpHostCommonPlatformLib_launch ( RU8 configHint, RPNCHAR primaryHomeUrl, RPNCHAR secondaryHomeUrl ) { RBOOL isInitSuccessful = FALSE; rSequence staticConfig = NULL; RPCHAR tmpStr = NULL; rSequence tmpSeq = NULL; RPU8 tmpBuffer = NULL; RU32 tmpSize = 0; RU16 tmpPort = 0; rpal_debug_info( "launching hcp" ); #ifdef RPAL_PLATFORM_WINDOWS if( setGlobalCrashHandler() && SetConsoleCtrlHandler( (PHANDLER_ROUTINE)ctrlHandler, TRUE ) ) { rpal_debug_info( "global crash handler set" ); } else { rpal_debug_warning( "error setting global crash handler" ); } #endif if( 1 == rInterlocked_increment32( &g_hcpContext.isRunning ) ) { if( rpal_initialize( NULL, RPAL_COMPONENT_HCP ) ) { CryptoLib_init(); if( NULL == ( g_hcpContext.cloudConnectionMutex = rMutex_create() ) || NULL == ( g_hcpContext.isCloudOnline = rEvent_create( TRUE ) ) ) { rMutex_free( g_hcpContext.cloudConnectionMutex ); rpal_debug_error( "could not create cloud connection mutex or event" ); return FALSE; } g_hcpContext.currentId.raw = g_idTemplate.raw; // We attempt to load some initial config from the serialized // rSequence that can be patched in this binary. if( NULL != ( staticConfig = getStaticConfig() ) ) { if( rSequence_getSTRINGA( staticConfig, RP_TAGS_HCP_PRIMARY_URL, &tmpStr ) && rSequence_getRU16( staticConfig, RP_TAGS_HCP_PRIMARY_PORT, &tmpPort ) ) { g_hcpContext.primaryUrl = rpal_string_strdupA( tmpStr ); g_hcpContext.primaryPort = tmpPort; rpal_debug_info( "loading primary url from static config" ); } if( rSequence_getSTRINGA( staticConfig, RP_TAGS_HCP_SECONDARY_URL, &tmpStr ) && rSequence_getRU16( staticConfig, RP_TAGS_HCP_SECONDARY_PORT, &tmpPort ) ) { g_hcpContext.secondaryUrl = rpal_string_strdupA( tmpStr ); g_hcpContext.secondaryPort = tmpPort; rpal_debug_info( "loading secondary url from static config" ); } if( rSequence_getSEQUENCE( staticConfig, RP_TAGS_HCP_ID, &tmpSeq ) ) { g_hcpContext.currentId = seqToHcpId( tmpSeq ); rpal_debug_info( "loading default id from static config" ); } if( rSequence_getBUFFER( staticConfig, RP_TAGS_HCP_C2_PUBLIC_KEY, &tmpBuffer, &tmpSize ) ) { setC2PublicKey( rpal_memory_duplicate( tmpBuffer, tmpSize ) ); rpal_debug_info( "loading c2 public key from static config" ); } if( rSequence_getBUFFER( staticConfig, RP_TAGS_HCP_ROOT_PUBLIC_KEY, &tmpBuffer, &tmpSize ) ) { setRootPublicKey( rpal_memory_duplicate( tmpBuffer, tmpSize ) ); rpal_debug_info( "loading root public key from static config" ); } if( rSequence_getSTRINGA( staticConfig, RP_TAGS_HCP_DEPLOYMENT_KEY, &tmpStr ) ) { g_hcpContext.deploymentKey = rpal_string_strdupA( tmpStr ); rpal_debug_info( "loading deployment key from static config" ); } rSequence_free( staticConfig ); } // Now we will override the defaults (if present) with command // line parameters. if( NULL != primaryHomeUrl && 0 != rpal_string_strlen( primaryHomeUrl ) ) { if( NULL != g_hcpContext.primaryUrl ) { rpal_memory_free( g_hcpContext.primaryUrl ); g_hcpContext.primaryUrl = NULL; } g_hcpContext.primaryUrl = rpal_string_ntoa( primaryHomeUrl ); } if( NULL != secondaryHomeUrl && 0 != rpal_string_strlen( secondaryHomeUrl ) ) { if( NULL != g_hcpContext.secondaryUrl ) { rpal_memory_free( g_hcpContext.secondaryUrl ); g_hcpContext.secondaryUrl = NULL; } g_hcpContext.secondaryUrl = rpal_string_ntoa( secondaryHomeUrl ); } g_hcpContext.enrollmentToken = NULL; g_hcpContext.enrollmentTokenSize = 0; getStoreConf(); /* Sets the agent ID platform. */ // Set the current configId g_hcpContext.currentId.id.configId = configHint; if( startBeacons() ) { isInitSuccessful = TRUE; } else { rpal_debug_warning( "error starting beacons" ); } CryptoLib_deinit(); } else { rpal_debug_warning( "hcp platform could not init rpal" ); } } else { rInterlocked_decrement32( &g_hcpContext.isRunning ); rpal_debug_info( "hcp already launched" ); } return isInitSuccessful; }