static
RBOOL
    _reportEvents
    (
        StatefulMachine* machine
    )
{
    RBOOL isSuccess = FALSE;

    rSequence wrapper = NULL;
    rList events = NULL;
    rSequence event = NULL;
    RU32 i = 0;

    if( NULL != machine )
    {
        if( NULL != ( wrapper = rSequence_new() ) )
        {
            if( NULL != ( events = rList_new( RP_TAGS_EVENT, RPCM_SEQUENCE ) ) )
            {
                for( i = 0; i < machine->history->nElements; i++ )
                {
                    event = ( (StatefulEvent*)machine->history->elements[ i ] )->data;
                    rList_addSEQUENCE( events, rSequence_duplicate( event ) );
                }

                if( !rSequence_addLIST( wrapper, RP_TAGS_EVENTS, events ) )
                {
                    rList_free( events );
                }
                else
                {
                    hbs_timestampEvent( wrapper, 0 );
                    isSuccess = hbs_publish( machine->desc->reportEventType, wrapper );
                }
            }

            rSequence_free( wrapper );
        }
    }

    return isSuccess;
}
Ejemplo n.º 2
0
static
RVOID
    getDocument
    (
        rpcm_tag notifId,
        rSequence notif
    )
{
    rSequence tmp = NULL;
    DocSearchContext ctx = { 0 };
    RU32 hashSize = 0;
    rList foundDocs = NULL;
    RBOOL isAAlloced = FALSE;
    RBOOL isWAlloced = FALSE;
    UNREFERENCED_PARAMETER( notifId );

    if( NULL != notif )
    {
        if( !rSequence_getSTRINGA( notif, RP_TAGS_STRING_PATTERN, &ctx.exprA ) )
        {
            ctx.exprA = NULL;
        }
        if( !rSequence_getSTRINGW( notif, RP_TAGS_STRING_PATTERN, &ctx.exprW ) )
        {
            ctx.exprW = NULL;
        }
        if( NULL != ctx.exprA && NULL == ctx.exprW )
        {
            ctx.exprW = rpal_string_atow( ctx.exprA );
            isWAlloced = TRUE;
        }
        if( NULL != ctx.exprW && NULL == ctx.exprA )
        {
            ctx.exprA = rpal_string_wtoa( ctx.exprW );
            isAAlloced = TRUE;
        }
        if( !rSequence_getBUFFER( notif, RP_TAGS_HASH, (RPU8*)&ctx.pHash, &hashSize ) ||
            sizeof( *ctx.pHash ) != hashSize )
        {
            // Unexpected hash size, let's not gamble 
            ctx.pHash = NULL;
        }
    }

    if( rMutex_lock( cacheMutex ) )
    {
        if( NULL != ( foundDocs = rList_new( RP_TAGS_FILE_INFO, RPCM_SEQUENCE ) ) )
        {
            while( HbsRingBuffer_find( documentCache, (HbsRingBufferCompareFunc)findDoc, &ctx, &tmp ) )
            {
                // TODO: optimize this since if we're dealing with large files
                // we will be temporarily using large amounts of duplicate memory.
                // We just need to do some shallow free of the datastructures
                // somehow.
                if( NULL != ( tmp = rSequence_duplicate( tmp ) ) )
                {
                    if( !rList_addSEQUENCE( foundDocs, tmp ) )
                    {
                        rSequence_free( tmp );
                    }
                }
            }

            if( !rSequence_addLIST( notif, RP_TAGS_FILES, foundDocs ) )
            {
                rList_free( foundDocs );
            }
        }

        rMutex_unlock( cacheMutex );

        notifications_publish( RP_TAGS_NOTIFICATION_GET_DOCUMENT_REP, notif );
    }

    if( isAAlloced )
    {
        rpal_memory_free( ctx.exprA );
    }
    if( isWAlloced )
    {
        rpal_memory_free( ctx.exprW );
    }
}
Ejemplo n.º 3
0
//=============================================================================
//  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;
}
Ejemplo n.º 4
0
static rList
    beaconHome
    (
        
    )
{
    rList response = NULL;
    rList exfil = NULL;
    rSequence msg = NULL;
    RU32 nExfilMsg = 0;
    rSequence tmpMessage = NULL;

    if( NULL != ( exfil = rList_new( RP_TAGS_MESSAGE, RPCM_SEQUENCE ) ) )
    {
        if( NULL != ( msg = rSequence_new() ) )
        {
            if( rSequence_addBUFFER( msg, RP_TAGS_HASH, g_hbs_state.currentConfigHash, CRYPTOLIB_HASH_SIZE ) )
            {
                if( !rList_addSEQUENCE( exfil, msg ) )
                {
                    rSequence_free( msg );
                    msg = NULL;
                }

                tmpMessage = msg;
            }
            else
            {
                rSequence_free( msg );
                msg = NULL;
            }
        }

        while( rQueue_remove( g_hbs_state.outQueue, &msg, NULL, 0 ) )
        {
            nExfilMsg++;

            if( !rList_addSEQUENCE( exfil, msg ) )
            {
                rSequence_free( msg );
            }
        }

        rpal_debug_info( "%d messages ready for exfil.", nExfilMsg );


        if( rpHcpI_beaconHome( exfil, &response ) )
        {
            rpal_debug_info( "%d messages received from cloud.", rList_getNumElements( response ) );
        }
        else if( g_hbs_state.maxQueueSize > rList_getEstimateSize( exfil ) )
        {
            rpal_debug_info( "beacon failed, re-adding %d messages.", rList_getNumElements( exfil ) );

            // We will attempt to re-add the existing messages back in the queue since this failed
            rList_resetIterator( exfil );
            while( rList_getSEQUENCE( exfil, RP_TAGS_MESSAGE, &msg ) )
            {
                // Ignore message we generate temporarily for the beacon
                if( tmpMessage == msg )
                {
                    rSequence_free( msg );
                    continue;
                }

                if( !rQueue_add( g_hbs_state.outQueue, msg, 0 ) )
                {
                    rSequence_free( msg );
                }
            }
            rList_shallowFree( exfil );
            exfil = NULL;
        }
        else
        {
            rpal_debug_warning( "beacon failed but discarded exfil because of its size." );
        }

        if( NULL != exfil )
        {
            rList_free( exfil );
        }
    }

    return response;
}
Ejemplo n.º 5
0
static
rList
    assembleRequest
    (
        RPU8 optCrashCtx,
        RU32 optCrashCtxSize
    )
{
    rSequence req = NULL;
    RU32 moduleIndex = 0;
    rList msgList = NULL;
    rList modList = NULL;
    rSequence modEntry = NULL;

    if( NULL != ( req = rSequence_new() ) )
    {
        // Add some basic info
        rSequence_addRU32( req, RP_TAGS_MEMORY_USAGE, rpal_memory_totalUsed() );
        rSequence_addTIMESTAMP( req, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() );

        // If we have a crash context to report
        if( NULL != optCrashCtx )
        {
            if( !rSequence_addBUFFER( req, RP_TAGS_HCP_CRASH_CONTEXT, optCrashCtx, optCrashCtxSize ) )
            {
                rpal_debug_error( "error adding crash context of size %d to hcp beacon", optCrashCtxSize );
            }
            else
            {
                rpal_debug_info( "crash context is being bundled in hcp beacon" );
            }
        }

        // List of loaded modules
        if( NULL != ( modList = rList_new( RP_TAGS_HCP_MODULE, RPCM_SEQUENCE ) ) )
        {
            for( moduleIndex = 0; moduleIndex < RP_HCP_CONTEXT_MAX_MODULES; moduleIndex++ )
            {
                if( NULL != g_hcpContext.modules[ moduleIndex ].hModule )
                {
                    if( NULL != ( modEntry = rSequence_new() ) )
                    {
                        if( !rSequence_addBUFFER( modEntry, 
                                                    RP_TAGS_HASH, 
                                                    g_hcpContext.modules[ moduleIndex ].hash, 
                                                    sizeof( g_hcpContext.modules[ moduleIndex ].hash ) ) ||
                            !rSequence_addRU8( modEntry, 
                                                RP_TAGS_HCP_MODULE_ID, 
                                                g_hcpContext.modules[ moduleIndex ].id ) ||
                            !rList_addSEQUENCE( modList, modEntry ) )
                        {
                            break;
                        }

                        // We take the opportunity to cleanup the list of modules...
                        if( rpal_thread_wait( g_hcpContext.modules[ moduleIndex ].hThread, 0 ) )
                        {
                            // This thread has exited, which is our signal that the module
                            // has stopped executing...
                            rEvent_free( g_hcpContext.modules[ moduleIndex ].isTimeToStop );
                            rpal_thread_free( g_hcpContext.modules[ moduleIndex ].hThread );
                            rpal_memory_zero( &(g_hcpContext.modules[ moduleIndex ]),
                                              sizeof( g_hcpContext.modules[ moduleIndex ] ) );

                            if( !rSequence_addRU8( modEntry, RP_TAGS_HCP_MODULE_TERMINATED, 1 ) )
                            {
                                break;
                            }
                        }
                    }
                }
            }

            if( !rSequence_addLIST( req, RP_TAGS_HCP_MODULES, modList ) )
            {
                rList_free( modList );
            }
        }

        if( NULL != ( msgList = rList_new( RP_TAGS_MESSAGE, RPCM_SEQUENCE ) ) )
        {
            if( !rList_addSEQUENCE( msgList, req ) )
            {
                rList_free( msgList );
                rSequence_free( req );
                msgList = NULL;
            }
        }
        else
        {
            rSequence_free( req );
        }
    }

    return msgList;
}
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 );
    }
}
RPRIVATE
RVOID
    mem_strings
    (
        rpcm_tag eventType,
        rSequence event
    )
{
    RU32 pid = 0;
    rList memMapList = NULL;
    rSequence region = NULL;
    RU64 memBase = 0;
    RU64 memSize = 0;
    RPU8 pRegion = NULL;
    rList stringsAList = NULL;
    rList stringsWList = NULL;
    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 ) ) ) )
        {
            if( NULL != ( memMapList = processLib_getProcessMemoryMap( pid ) ) &&
                ( NULL != ( stringsAList = rList_new( RP_TAGS_STRINGSA, RPCM_STRINGA ) ) ) &&
                ( NULL != ( stringsWList = rList_new( RP_TAGS_STRINGSW, RPCM_STRINGW ) ) ) )
            {
                while( rList_getSEQUENCE( memMapList, RP_TAGS_MEMORY_REGION, &region ) )
                {
                    if( rSequence_getPOINTER64( region, RP_TAGS_BASE_ADDRESS, &memBase ) &&
                        rSequence_getRU64( region, RP_TAGS_MEMORY_SIZE, &memSize ) )
                    {
                        if( processLib_getProcessMemory( pid, 
                                                         (RPVOID)rpal_ULongToPtr( memBase ), 
                                                         memSize, 
                                                         (RPVOID*)&pRegion,
                                                         TRUE ) )
                        {
                            // now search for strings inside this region
                            _getStringsList( stringsAList, stringsWList, pRegion, memSize, minLength, maxLength );

                            rpal_memory_free( pRegion );
                        }
                    }
                }

                if( !rSequence_addLIST( event, RP_TAGS_STRINGSA, stringsAList ) )
                {
                    rList_free( stringsAList );
                }
                if( !rSequence_addLIST( event, RP_TAGS_STRINGSW, stringsWList ) )
                {
                    rList_free( stringsWList );
                }
            }
            else
            {
                rSequence_addRU32( event, RP_TAGS_ERROR, rpal_error_getLast() );
            }

            if( NULL != memMapList )
            {
                rList_free( memMapList );
            }
        }

        hbs_timestampEvent( event, 0 );
        hbs_publish( RP_TAGS_NOTIFICATION_MEM_STRINGS_REP, event );
    }
}
        RPRIVATE
rSequence
    _findStringsInProcess
    (
        RU32 pid,
        rList searchStrings,
        RU32 minLength,
        RU32 maxLength
    )
{
    rSequence info = NULL;

    rList memMapList = NULL;
    rSequence region = NULL;
    RU64 memBase = 0;
    RU64 memSize = 0;
    RPU8 pRegion = NULL;
    rList stringsFound = NULL;

    if( NULL != searchStrings )
    {
        if( NULL != ( info = rSequence_new() ) )
        {
            rSequence_addRU32( info, RP_TAGS_PROCESS_ID, pid );

            if( NULL != ( memMapList = processLib_getProcessMemoryMap( pid ) ) &&
                ( NULL != ( stringsFound = rList_new( RP_TAGS_STRINGSW, RPCM_SEQUENCE ) ) ) )
            {
                while( rList_getSEQUENCE( memMapList, RP_TAGS_MEMORY_REGION, &region ) )
                {
                    if( rSequence_getPOINTER64( region, RP_TAGS_BASE_ADDRESS, &memBase ) &&
                        rSequence_getRU64( region, RP_TAGS_MEMORY_SIZE, &memSize ) )
                    {
                        if( processLib_getProcessMemory( pid, 
                                                         (RPVOID)rpal_ULongToPtr( memBase ), 
                                                         memSize, 
                                                         (RPVOID*)&pRegion, 
                                                         TRUE ) )
                        {
                            // now search for strings inside this region
                            _searchForStrings( stringsFound, 
                                               searchStrings, 
                                               pRegion, 
                                               memSize, 
                                               memBase, 
                                               minLength, 
                                               maxLength);

                            rpal_memory_free( pRegion );
                        }
                    }
                }

                if( !rSequence_addLIST( info, RP_TAGS_STRINGS_FOUND, stringsFound ) )
                {
                    rList_free( stringsFound );
                }
            }
            else
            {
                rSequence_addRU32( info, RP_TAGS_ERROR, rpal_error_getLast() );
            }

            if( NULL != memMapList )
            {
                rList_free( memMapList );
            }
        }
    }

    return info;
}