static RVOID processGenericSnapshot ( rpcm_tag notifType, rSequence event ) { rList entityList = NULL; rSequence entity = NULL; UNREFERENCED_PARAMETER( notifType ); if( rpal_memory_isValid( event ) ) { if( rSequence_getLIST( event, RP_TAGS_AUTORUNS, &entityList ) || rSequence_getLIST( event, RP_TAGS_SVCS, &entityList ) || rSequence_getLIST( event, RP_TAGS_PROCESSES, &entityList ) ) { // Go through the elements, whatever tag while( rList_getSEQUENCE( entityList, RPCM_INVALID_TAG, &entity ) ) { processHashedEvent( notifType, entity ); } } } }
// Receives a task to start denying a tree at a given root. // Can be a single atom or a list of atoms. RPRIVATE RVOID denyNewTree ( rpcm_tag notifType, rSequence event ) { RPU8 atomId = NULL; RU32 size = 0; rList atomList = NULL; UNREFERENCED_PARAMETER( notifType ); // We accept a single atom, or a list of atoms if( rSequence_getBUFFER( event, RP_TAGS_HBS_THIS_ATOM, &atomId, &size ) && HBS_ATOM_ID_SIZE == size ) { denyExistingTree( atomId ); } else if( rSequence_getLIST( event, RP_TAGS_HBS_THIS_ATOM, &atomList ) ) { while( rList_getBUFFER( atomList, RP_TAGS_HBS_THIS_ATOM, &atomId, &size ) && HBS_ATOM_ID_SIZE == size ) { denyExistingTree( atomId ); } } }
RBOOL collector_18_init ( HbsState* hbsState, rSequence config ) { RBOOL isSuccess = FALSE; rList extensions = NULL; rList patterns = NULL; RPCHAR strA = NULL; RPCHAR tmpA = NULL; RPWCHAR strW = NULL; RPWCHAR tmpW = NULL; RU32 maxSize = 0; RBOOL isCaseInsensitive = FALSE; if( NULL != hbsState ) { #ifdef RPAL_PLATFORM_WINDOWS // On Windows files and paths are not case sensitive. isCaseInsensitive = TRUE; #endif if( NULL == config || rSequence_getLIST( config, RP_TAGS_EXTENSIONS, &extensions ) || rSequence_getLIST( config, RP_TAGS_PATTERNS, &patterns ) ) { if( NULL != ( cacheMutex = rMutex_create() ) && NULL != ( matcherA = obsLib_new( 0, 0 ) ) && NULL != ( matcherW = obsLib_new( 0, 0 ) ) ) { cacheSize = 0; if( NULL != config && rSequence_getRU32( config, RP_TAGS_MAX_SIZE, &maxSize ) ) { cacheMaxSize = maxSize; } else { cacheMaxSize = MAX_CACHE_SIZE; } if( NULL != ( documentCache = HbsRingBuffer_new( 0, cacheMaxSize ) ) ) { if( NULL == config ) { // As a default we'll cache all new files obsLib_addPattern( matcherA, (RPU8)"", sizeof( RCHAR ), NULL ); obsLib_addPattern( matcherW, (RPU8)_WCH(""), sizeof( RWCHAR ), NULL ); } else { // If a config was provided we'll cache only certain extensions // specified. while( rList_getSTRINGA( extensions, RP_TAGS_EXTENSION, &strA ) ) { if( rpal_string_expand( strA, &tmpA ) ) { obsLib_addStringPatternA( matcherA, tmpA, TRUE, isCaseInsensitive, NULL ); rpal_memory_free( tmpA ); } if( NULL != ( strW = rpal_string_atow( strA ) ) ) { if( rpal_string_expandw( strW, &tmpW ) ) { obsLib_addStringPatternW( matcherW, tmpW, TRUE, isCaseInsensitive, NULL ); rpal_memory_free( tmpW ); } rpal_memory_free( strW ); } } while( rList_getSTRINGW( extensions, RP_TAGS_EXTENSION, &strW ) ) { if( rpal_string_expandw( strW, &tmpW ) ) { obsLib_addStringPatternW( matcherW, tmpW, TRUE, isCaseInsensitive, NULL ); rpal_memory_free( tmpW ); } if( NULL != ( strA = rpal_string_wtoa( strW ) ) ) { if( rpal_string_expand( strA, &tmpA ) ) { obsLib_addStringPatternA( matcherA, tmpA, TRUE, isCaseInsensitive, NULL ); rpal_memory_free( tmpA ); } rpal_memory_free( strA ); } } while( rList_getSTRINGA( patterns, RP_TAGS_STRING_PATTERN, &strA ) ) { if( rpal_string_expand( strA, &tmpA ) ) { obsLib_addStringPatternA( matcherA, tmpA, FALSE, isCaseInsensitive, NULL ); rpal_memory_free( tmpA ); } if( NULL != ( strW = rpal_string_atow( strA ) ) ) { if( rpal_string_expandw( strW, &tmpW ) ) { obsLib_addStringPatternW( matcherW, tmpW, FALSE, isCaseInsensitive, NULL ); rpal_memory_free( tmpW ); } rpal_memory_free( strW ); } } while( rList_getSTRINGW( patterns, RP_TAGS_STRING_PATTERN, &strW ) ) { if( rpal_string_expandw( strW, &tmpW ) ) { obsLib_addStringPatternW( matcherW, tmpW, FALSE, isCaseInsensitive, NULL ); rpal_memory_free( tmpW ); } if( NULL != ( strA = rpal_string_wtoa( strW ) ) ) { if( rpal_string_expand( strA, &tmpA ) ) { obsLib_addStringPatternA( matcherA, tmpA, FALSE, isCaseInsensitive, NULL ); rpal_memory_free( tmpA ); } rpal_memory_free( strA ); } } } if( rQueue_create( &createQueue, _freeEvt, 200 ) && notifications_subscribe( RP_TAGS_NOTIFICATION_FILE_CREATE, NULL, 0, createQueue, NULL ) && notifications_subscribe( RP_TAGS_NOTIFICATION_GET_DOCUMENT_REQ, NULL, 0, NULL, getDocument ) && rThreadPool_task( hbsState->hThreadPool, parseDocuments, NULL ) ) { isSuccess = TRUE; } } } if( !isSuccess ) { notifications_unsubscribe( RP_TAGS_NOTIFICATION_FILE_CREATE, createQueue, NULL ); notifications_unsubscribe( RP_TAGS_NOTIFICATION_GET_DOCUMENT_REQ, NULL, getDocument ); rQueue_free( createQueue ); createQueue = NULL; obsLib_free( matcherA ); obsLib_free( matcherW ); HbsRingBuffer_free( documentCache ); matcherA = NULL; matcherW = NULL; documentCache = NULL; rMutex_free( cacheMutex ); cacheMutex = NULL; } } } return isSuccess; }
RBOOL collector_22_init ( HbsState* hbsState, rSequence config ) { RBOOL isSuccess = FALSE; rList patterns = NULL; rSequence pattern = NULL; RPCHAR strA = NULL; RPWCHAR strW = NULL; RPNCHAR tmpN = NULL; RU8 patternId = 0; RU32 i = 0; if( NULL != hbsState && NULL != ( g_extensions = obsLib_new( 0, 0 ) ) ) { if( rSequence_getLIST( config, RP_TAGS_PATTERNS, &patterns ) ) { while( rList_getSEQUENCE( patterns, RP_TAGS_RULE, &pattern ) ) { if( rSequence_getRU8( pattern, RP_TAGS_RULE_NAME, &patternId ) ) { if( 64 < patternId || 0 == patternId ) { rpal_debug_critical( "rule id must be below 64 and 1-based." ); continue; } // Base the pattern id to 0 patternId--; if( rSequence_getSTRINGA( pattern, RP_TAGS_EXTENSION, &strA ) && NULL != ( tmpN = rpal_string_aton( strA ) ) ) { _addPattern( g_extensions, tmpN, TRUE, NUMBER_TO_PTR( patternId ) ); rpal_memory_free( tmpN ); } if( rSequence_getSTRINGW( pattern, RP_TAGS_EXTENSION, &strW ) && NULL != ( tmpN = rpal_string_wton( strW ) ) ) { _addPattern( g_extensions, tmpN, TRUE, NUMBER_TO_PTR( patternId ) ); rpal_memory_free( tmpN ); } if( rSequence_getSTRINGA( pattern, RP_TAGS_STRING_PATTERN, &strA ) && NULL != ( tmpN = rpal_string_aton( strA ) ) ) { _addPattern( g_extensions, tmpN, FALSE, NUMBER_TO_PTR( patternId ) ); rpal_memory_free( tmpN ); } if( rSequence_getSTRINGW( pattern, RP_TAGS_STRING_PATTERN, &strW ) && NULL != ( tmpN = rpal_string_wton( strW ) ) ) { _addPattern( g_extensions, tmpN, FALSE, NUMBER_TO_PTR( patternId ) ); rpal_memory_free( tmpN ); } } } if( NULL != ( g_mutex = rMutex_create() ) && NULL != ( g_procContexts = rpal_vector_new() ) && notifications_subscribe( RP_TAGS_NOTIFICATION_FILE_CREATE, NULL, 0, NULL, processFileIo ) && notifications_subscribe( RP_TAGS_NOTIFICATION_FILE_DELETE, NULL, 0, NULL, processFileIo ) && notifications_subscribe( RP_TAGS_NOTIFICATION_FILE_MODIFIED, NULL, 0, NULL, processFileIo ) && notifications_subscribe( RP_TAGS_NOTIFICATION_FILE_READ, NULL, 0, NULL, processFileIo ) && notifications_subscribe( RP_TAGS_NOTIFICATION_NEW_PROCESS, NULL, 0, NULL, processNewProcesses ) && notifications_subscribe( RP_TAGS_NOTIFICATION_EXISTING_PROCESS, NULL, 0, NULL, processNewProcesses ) && notifications_subscribe( RP_TAGS_NOTIFICATION_TERMINATE_PROCESS, NULL, 0, NULL, processTerminateProcesses ) ) { isSuccess = TRUE; } } } if( !isSuccess ) { notifications_unsubscribe( RP_TAGS_NOTIFICATION_FILE_CREATE, NULL, processFileIo ); notifications_unsubscribe( RP_TAGS_NOTIFICATION_FILE_DELETE, NULL, processFileIo ); notifications_unsubscribe( RP_TAGS_NOTIFICATION_FILE_MODIFIED, NULL, processFileIo ); notifications_unsubscribe( RP_TAGS_NOTIFICATION_FILE_READ, NULL, processFileIo ); notifications_unsubscribe( RP_TAGS_NOTIFICATION_NEW_PROCESS, NULL, processNewProcesses ); notifications_unsubscribe( RP_TAGS_NOTIFICATION_EXISTING_PROCESS, NULL, processNewProcesses ); notifications_unsubscribe( RP_TAGS_NOTIFICATION_TERMINATE_PROCESS, NULL, processTerminateProcesses ); obsLib_free( g_extensions ); g_extensions = NULL; if( NULL != g_procContexts ) { for( i = 0; i < g_procContexts->nElements; i++ ) { rpal_memory_free( ( (ProcExtInfo*)g_procContexts->elements[ i ] )->processPath ); rpal_memory_free( g_procContexts->elements[ i ] ); } } rpal_vector_free( g_procContexts ); g_procContexts = NULL; rMutex_free( g_mutex ); g_mutex = NULL; } return isSuccess; }
//============================================================================= // 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; }
RPRIVATE RVOID mem_find_string ( rpcm_tag eventType, rSequence event ) { RU32 pid = 0; RU32 currentPid = 0; rList searchStrings = NULL; rList processes = NULL; rSequence process = NULL; processLibProcEntry* pids = NULL; RU32 nCurrent = 0; RU32 minLength = 5; RU32 maxLength = 128; RPU8 atom = NULL; RU32 atomSize = 0; UNREFERENCED_PARAMETER( eventType ); if( rpal_memory_isValid( event ) ) { if( ( rSequence_getRU32( event, RP_TAGS_PROCESS_ID, &pid ) || ( rSequence_getBUFFER( event, RP_TAGS_HBS_THIS_ATOM, &atom, &atomSize ) && HBS_ATOM_ID_SIZE == atomSize && 0 != ( pid = atoms_getPid( atom ) ) ) ) && rSequence_getLIST( event, RP_TAGS_STRINGSW, &searchStrings ) ) { currentPid = processLib_getCurrentPid(); if( NULL != ( processes = rList_new( RP_TAGS_PROCESS, RPCM_SEQUENCE ) ) ) { if( 0 != pid ) { if( NULL != ( process = _findStringsInProcess( pid, searchStrings, minLength, maxLength ) ) ) { if( !rList_addSEQUENCE( processes, process ) ) { rSequence_free( process ); } } } else { if( NULL != ( pids = processLib_getProcessEntries( TRUE ) ) ) { while( 0 != pids[ nCurrent ].pid ) { if( currentPid != pids[ nCurrent ].pid ) { if( NULL != ( process = _findStringsInProcess( pids[ nCurrent ].pid, searchStrings, minLength, maxLength ) ) ) { if( !rList_addSEQUENCE( processes, process ) ) { rSequence_free( process ); } } } nCurrent++; } rpal_memory_free( pids ); } } if( !rSequence_addLIST( event, RP_TAGS_PROCESSES, processes ) ) { rList_free( processes ); } } } hbs_timestampEvent( event, 0 ); hbs_publish( RP_TAGS_NOTIFICATION_MEM_FIND_STRING_REP, event ); } }