Пример #1
0
static RVOID
    sendStartupEvent
    (

    )
{
    rSequence wrapper = NULL;
    rSequence startupEvent = NULL;

    if( NULL != ( wrapper = rSequence_new() ) )
    {
        if( NULL != ( startupEvent = rSequence_new() ) )
        {
            if( rSequence_addSEQUENCE( wrapper, RP_TAGS_NOTIFICATION_STARTING_UP, startupEvent ) )
            {
                if( !rSequence_addTIMESTAMP( startupEvent, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() ) ||
                    !rQueue_add( g_hbs_state.outQueue, wrapper, 0 ) )
                {
                    rSequence_free( wrapper );
                }
            }
            else
            {
                rSequence_free( wrapper );
                rSequence_free( startupEvent );
            }
        }
        else
        {
            rSequence_free( wrapper );
        }
    }
}
static RBOOL
    notifyOfProcess
    (
        RU32 pid,
        RU32 ppid,
        RBOOL isStarting
    )
{
    RBOOL isSuccess = FALSE;
    rSequence info = NULL;
    rSequence parentInfo = NULL;

    if( !isStarting ||
        NULL == ( info = processLib_getProcessInfo( pid ) ) )
    {
        info = rSequence_new();
    }

    if( rpal_memory_isValid( info ) )
    {
        rSequence_addRU32( info, RP_TAGS_PROCESS_ID, pid );
        rSequence_addRU32( info, RP_TAGS_PARENT_PROCESS_ID, ppid );
        rSequence_addTIMESTAMP( info, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() );

        if( isStarting )
        {
            if( NULL != ( parentInfo = processLib_getProcessInfo( ppid ) ) &&
                !rSequence_addSEQUENCE( info, RP_TAGS_PARENT, parentInfo ) )
            {
                rSequence_free( parentInfo );
            }
        }

        if( isStarting )
        {
            if( notifications_publish( RP_TAGS_NOTIFICATION_NEW_PROCESS, info ) )
            {
                isSuccess = TRUE;
                rpal_debug_info( "new process starting: %d", pid );
            }
        }
        else
        {
            if( notifications_publish( RP_TAGS_NOTIFICATION_TERMINATE_PROCESS, info ) )
            {
                isSuccess = TRUE;
                rpal_debug_info( "new process terminating: %d", pid );
            }
        }

        rSequence_free( info );
    }

    return isSuccess;
}
Пример #3
0
static RVOID
    shutdownCollectors
    (

    )
{
    RU32 i = 0;

    if( !rEvent_wait( g_hbs_state.isTimeToStop, 0 ) )
    {
        rpal_debug_info( "signaling to collectors to stop." );
        rEvent_set( g_hbs_state.isTimeToStop );

        if( NULL != g_hbs_state.hThreadPool )
        {
            rpal_debug_info( "destroying collector thread pool." );
            rThreadPool_destroy( g_hbs_state.hThreadPool, TRUE );
            g_hbs_state.hThreadPool = NULL;

            for( i = 0; i < ARRAY_N_ELEM( g_collectors ); i++ )
            {
                if( g_collectors[ i ].isEnabled )
                {
                    rpal_debug_info( "cleaning up collector %d.", i );
                    g_collectors[ i ].cleanup( &g_hbs_state, g_collectors[ i ].conf );
                    rSequence_free( g_collectors[ i ].conf );
                    g_collectors[ i ].conf = NULL;
                }
            }
        }
    }
}
Пример #4
0
static
int
    _yaraFileMatchCallback
    (
        int message,
        void* message_data,
        void* user_data
    )
{
    YR_RULE* rule = (YR_RULE*)message_data;
    YaraMatchContext* context = (YaraMatchContext*)user_data;
    rSequence event = NULL;
    
    if( CALLBACK_MSG_RULE_MATCHING == message &&
        NULL != message_data &&
        NULL != user_data )
    {
        if( NULL != ( event = rSequence_duplicate( context->fileInfo ) ) )
        {
            rSequence_addSTRINGA( event, RP_TAGS_RULE_NAME, (char*)rule->identifier );

            notifications_publish( RP_TAGS_NOTIFICATION_YARA_DETECTION, event );

            rSequence_free( event );
        }
        else
        {
            rpal_debug_warning( "error creating event from Yara match" );
        }
    }

    return CALLBACK_CONTINUE;
}
Пример #5
0
void 
    test_modules
    (
        void
    )
{
    processLibProcEntry* entries = NULL;
    RU32 entryIndex = 0;
    rList mods = NULL;
    rSequence mod = NULL;
    RPWCHAR path = NULL;

    entries = processLib_getProcessEntries( TRUE );

    CU_ASSERT_PTR_NOT_EQUAL_FATAL( entries, NULL );

    CU_ASSERT_NOT_EQUAL_FATAL( entries[ entryIndex ].pid, 0 );

    mods = processLib_getProcessModules( entries[ entryIndex ].pid );

    CU_ASSERT_PTR_NOT_EQUAL( mods, NULL );

    CU_ASSERT_TRUE( rList_getSEQUENCE( mods, RP_TAGS_DLL, &mod ) );

    CU_ASSERT_TRUE( rSequence_getSTRINGW( mod, RP_TAGS_FILE_PATH, &path ) );

    CU_ASSERT_PTR_NOT_EQUAL( path, NULL );
    CU_ASSERT_NOT_EQUAL( rpal_string_strlenw( path ), 0 );

    rSequence_free( mods );

    rpal_memory_free( entries );
}
Пример #6
0
void 
    test_processInfo
    (
        void
    )
{
    processLibProcEntry* entries = NULL;
    RU32 entryIndex = 0;
    rSequence proc = NULL;
    RPWCHAR path = NULL;

    entries = processLib_getProcessEntries( TRUE );

    CU_ASSERT_PTR_NOT_EQUAL_FATAL( entries, NULL );

    CU_ASSERT_NOT_EQUAL_FATAL( entries[ entryIndex ].pid, 0 );

    proc = processLib_getProcessInfo( entries[ entryIndex ].pid );

    CU_ASSERT_PTR_NOT_EQUAL( proc, NULL );

    CU_ASSERT_TRUE( rSequence_getSTRINGW( proc, RP_TAGS_FILE_PATH, &path ) );

    CU_ASSERT_PTR_NOT_EQUAL( path, NULL );
    CU_ASSERT_NOT_EQUAL( rpal_string_strlenw( path ), 0 );

    rSequence_free( proc );

    rpal_memory_free( entries );
}
StatefulEvent*
    SMEvent_new
    (
        rpcm_tag eventType,
        rSequence data
    )
{
    StatefulEvent* event = NULL;

    rSequence wrapper = NULL;

    if( NULL != data )
    {
        if( NULL != ( wrapper = rSequence_new() ) )
        {
            if( NULL != ( event = rpal_memory_alloc( sizeof( *event ) ) ) )
            {
                if( NULL != ( event->ref = rRefCount_create( (rRefCount_freeFunc)_freeEvent, event, sizeof( *event ) ) ) )
                {
                    if( rSequence_addSEQUENCE( wrapper, eventType, data ) )
                    {
                        event->data = wrapper;
                        event->eventType = eventType;
                        rSequence_getTIMESTAMP( data, RP_TAGS_TIMESTAMP, &event->ts );
                    }
                    else
                    {
                        rSequence_free( wrapper );
                    }
                }
                else
                {
                    rpal_memory_free( event );
                    event = NULL;
                    rSequence_free( wrapper );
                }
            }
            else
            {
                rSequence_free( wrapper );
            }
        }
    }

    return event;
}
Пример #8
0
static RVOID
    freeExfilEvent
    (
        rSequence seq,
        RU32 unused
    )
{
    UNREFERENCED_PARAMETER( unused );
    rSequence_free( seq );
}
Пример #9
0
static
RVOID
    _freeEvt
    (
        rSequence evt,
        RU32 unused
    )
{
    UNREFERENCED_PARAMETER( unused );
    rSequence_free( evt );
}
Пример #10
0
static
int 
    _yaraMemMatchCallback
    (
        int message,
        void* message_data,
        void* user_data
    )
{
    YR_RULE* rule = (YR_RULE*)message_data;
    YaraMatchContext* context = (YaraMatchContext*)user_data;
    rSequence event = NULL;

    if( CALLBACK_MSG_RULE_MATCHING == message &&
        NULL != message_data &&
        NULL != user_data )
    {
        if( NULL != ( event = rSequence_new() ) )
        {
            rSequence_addRU32( event, RP_TAGS_PROCESS_ID, context->pid );
            rSequence_addPOINTER64( event, RP_TAGS_BASE_ADDRESS, context->regionBase );
            rSequence_addRU64( event, RP_TAGS_MEMORY_SIZE, context->regionSize );

            hbs_markAsRelated( context->fileInfo, event );

            if( NULL == context->processInfo )
            {
                context->processInfo = processLib_getProcessInfo( context->pid, NULL );
            }

            if( NULL != context->processInfo )
            {
                rSequence_addSEQUENCE( event, RP_TAGS_PROCESS, rSequence_duplicate( context->processInfo ) );
            }

            if( NULL != context->moduleInfo )
            {
                rSequence_addSEQUENCE( event, RP_TAGS_DLL, rSequence_duplicate( context->moduleInfo ) );
            }

            rSequence_addSTRINGA( event, RP_TAGS_RULE_NAME, (char*)rule->identifier );

            notifications_publish( RP_TAGS_NOTIFICATION_YARA_DETECTION, event );

            rSequence_free( event );
        }
        else
        {
            rpal_debug_warning( "error creating event from Yara match" );
        }
    }

    return CALLBACK_CONTINUE;
}
Пример #11
0
static RVOID
    sendShutdownEvent
    (

    )
{
    rList cloudMessages = NULL;
    rSequence wrapper = NULL;
    rSequence shutdownEvent = NULL;

    if( NULL != ( wrapper = rSequence_new() ) )
    {
        if( NULL != ( shutdownEvent = rSequence_new() ) )
        {
            if( rSequence_addSEQUENCE( wrapper, RP_TAGS_NOTIFICATION_SHUTTING_DOWN, shutdownEvent ) )
            {
                if( rSequence_addTIMESTAMP( shutdownEvent, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() ) &&
                    rQueue_add( g_hbs_state.outQueue, wrapper, 0 ) )
                {
                    if( NULL != ( cloudMessages = beaconHome() ) )
                    {
                        rList_free( cloudMessages );
                    }
                }
                else
                {
                    rSequence_free( wrapper );
                }
            }
            else
            {
                rSequence_free( wrapper );
                rSequence_free( shutdownEvent );
            }
        }
        else
        {
            rSequence_free( wrapper );
        }
    }
}
Пример #12
0
static RBOOL
    updateCollectorConfigs
    (
        rList newConfigs
    )
{
    RBOOL isSuccess = FALSE;
    RU8 unused = 0;
    RU32 i = 0;
    rSequence tmpConf = NULL;
    RU32 confId = 0;

    if( rpal_memory_isValid( newConfigs ) )
    {
        rpal_debug_info( "updating collector configurations." );
        
        for( i = 0; i < ARRAY_N_ELEM( g_collectors ); i++ )
        {
            if( NULL != g_collectors[ i ].conf )
            {
                rpal_debug_info( "freeing collector %d config.", i );
                rSequence_free( g_collectors[ i ].conf );
                g_collectors[ i ].conf = NULL;
            }
        }

        while( rList_getSEQUENCE( newConfigs, RP_TAGS_HBS_CONFIGURATION, &tmpConf ) )
        {
            if( rSequence_getRU32( tmpConf, RP_TAGS_HBS_CONFIGURATION_ID, &confId ) &&
                confId < ARRAY_N_ELEM( g_collectors ) )
            {
                if( rSequence_getRU8( tmpConf, RP_TAGS_IS_DISABLED, &unused ) )
                {
                    g_collectors[ confId ].isEnabled = FALSE;
                }
                else
                {
                    g_collectors[ confId ].isEnabled = TRUE;
                    g_collectors[ confId ].conf = rSequence_duplicate( tmpConf );
                    rpal_debug_info( "set new collector %d config.", confId );
                }
            }
        }
                
        isSuccess = TRUE;
    }

    return isSuccess;
}
Пример #13
0
static
RVOID
    _freeSeq
    (
        rSequence seq,
        RU32 dummySize
    )
{
    UNREFERENCED_PARAMETER( dummySize );

    if( rpal_memory_isValid( seq ) )
    {
        rSequence_free( seq );
    }
}
//=============================================================================
//  BOILERPLATE
//=============================================================================
static
RVOID
    _freeEvent
    (
        StatefulEvent* event,
        RU32 unused
    )
{
    UNREFERENCED_PARAMETER( unused );
    if( rpal_memory_isValid( event ) )
    {
        rSequence_free( event->data );
        event->data = NULL;
        rpal_memory_free( event );
    }
}
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;
}
Пример #16
0
void 
    test_memmap
    (
        void
    )
{
    processLibProcEntry* entries = NULL;
    RU32 entryIndex = 0;
    rList regions = NULL;
    rSequence region = NULL;
    RU32 nRegions = 0;
    
    RU8 type = 0;
    RU8 protect = 0;
    RU64 ptr = 0;
    RU64 size = 0;

    entries = processLib_getProcessEntries( TRUE );

    CU_ASSERT_PTR_NOT_EQUAL_FATAL( entries, NULL );

    CU_ASSERT_NOT_EQUAL_FATAL( entries[ entryIndex ].pid, 0 );

    regions = processLib_getProcessMemoryMap( entries[ entryIndex ].pid );

    CU_ASSERT_PTR_NOT_EQUAL( regions, NULL );

    while( rList_getSEQUENCE( regions, RP_TAGS_MEMORY_REGION, &region ) )
    {
        CU_ASSERT_TRUE( rSequence_getRU8( region, RP_TAGS_MEMORY_TYPE, &type ) );
        CU_ASSERT_TRUE( rSequence_getRU8( region, RP_TAGS_MEMORY_ACCESS, &protect ) );
        CU_ASSERT_TRUE( rSequence_getPOINTER64( region, RP_TAGS_BASE_ADDRESS, &ptr ) );
        CU_ASSERT_TRUE( rSequence_getRU64( region, RP_TAGS_MEMORY_SIZE, &size ) );
        nRegions++;
    }

    CU_ASSERT_TRUE( 2 < nRegions ); 

    rSequence_free( regions );

    rpal_memory_free( entries );
}
Пример #17
0
static
RVOID
    processCodeIdentA
    (
        RPCHAR name,
        RPU8 pFileHash,
        RU64 codeSize,
        rSequence originalEvent
    )
{
    CodeIdent ident = { 0 };
    rSequence notif = NULL;

    ident.codeSize = codeSize;

    if( NULL != name )
    {
        CryptoLib_hash( name, rpal_string_strlen( name ) * sizeof( RCHAR ), ident.nameHash );
    }

    if( NULL != pFileHash )
    {
        rpal_memory_memcpy( ident.fileHash, pFileHash, CRYPTOLIB_HASH_SIZE );
    }

    if( rpal_bloom_addIfNew( knownCode, &ident, sizeof( ident ) ) )
    {
        if( NULL != ( notif = rSequence_new() ) )
        {
            hbs_markAsRelated( originalEvent, notif );

            if( rSequence_addSTRINGA( notif, RP_TAGS_FILE_NAME, name ) &&
                rSequence_addBUFFER( notif, RP_TAGS_HASH, pFileHash, CRYPTOLIB_HASH_SIZE ) &&
                rSequence_addRU32( notif, RP_TAGS_MEMORY_SIZE, (RU32)codeSize ) &&
                rSequence_addTIMESTAMP( notif, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() ) )
            {
                notifications_publish( RP_TAGS_NOTIFICATION_CODE_IDENTITY, notif );
            }
            rSequence_free( notif );
        }
    }
}
Пример #18
0
//=============================================================================
// YARA Required Shims
//=============================================================================
static
RVOID
    reportError
    (
        rSequence originalRequest,
        RU32 errorCode,
        RPCHAR errorStr
    )
{
    rSequence event = NULL;

    if( NULL != ( event = rSequence_new() ) )
    {
        hbs_markAsRelated( originalRequest, event );
        rSequence_addRU32( event, RP_TAGS_ERROR, errorCode );
        rSequence_addSTRINGA( event, RP_TAGS_ERROR_MESSAGE, errorStr ? errorStr : "" );
        rSequence_addTIMESTAMP( event, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() );
        notifications_publish( RP_TAGS_NOTIFICATION_YARA_DETECTION, event );
        rSequence_free( event );
    }
}
Пример #19
0
void 
    test_servicesList
    (
        void
    )
{
    rList svcs = NULL;
    rSequence svc = NULL;
    RU32 type = PROCESSLIB_SVCS;
#if defined( RPAL_PLATFORM_WINDOWS ) || defined( RPAL_PLATFORM_LINUX )
    RPWCHAR svcName = NULL;
#elif defined( RPAL_PLATFORM_MACOSX )
    RPCHAR svcName = NULL;
#endif

    svcs = processLib_getServicesList( type );

    CU_ASSERT_PTR_NOT_EQUAL_FATAL( svcs, NULL );

    CU_ASSERT_TRUE( rList_getSEQUENCE( svcs, RP_TAGS_SVC, &svc ) );

#if defined( RPAL_PLATFORM_WINDOWS ) || defined( RPAL_PLATFORM_LINUX )
    CU_ASSERT_TRUE( rSequence_getSTRINGW( svc, RP_TAGS_SVC_NAME, &svcName ) );

    CU_ASSERT_PTR_NOT_EQUAL( svcName, NULL );

    CU_ASSERT_NOT_EQUAL( rpal_string_strlenw( svcName ), 0 );
#elif defined( RPAL_PLATFORM_MACOSX )
    CU_ASSERT_TRUE( rSequence_getSTRINGA( svc, RP_TAGS_SVC_NAME, &svcName ) );

    CU_ASSERT_PTR_NOT_EQUAL( svcName, NULL );

    CU_ASSERT_NOT_EQUAL( rpal_string_strlen( svcName ), 0 );
#endif

    rSequence_free( svcs );
}
Пример #20
0
static
RVOID
    doScan
    (
        rpcm_tag eventType,
        rSequence event
    )
{
    RU32 pid = 0;
    RPWCHAR fileW = NULL;
    RPCHAR fileA = NULL;
    RPWCHAR procW = NULL;
    RPCHAR procA = NULL;
    RPU8 rulesBuffer = NULL;
    RU32 rulesBufferSize = 0;
    YR_RULES* rules = NULL;
    YaraMatchContext matchContext = { 0 };
    processLibProcEntry* processes = NULL;
    processLibProcEntry* curProc = NULL;
    RU32 scanError = 0;
    rSequence processInfo = NULL;
    RPWCHAR tmpW = NULL;
    RPCHAR tmpA = NULL;

    UNREFERENCED_PARAMETER( eventType );

    if( rpal_memory_isValid( event ) )
    {
        rSequence_getRU32( event, RP_TAGS_PROCESS_ID, &pid );
        rSequence_getSTRINGW( event, RP_TAGS_FILE_PATH, &fileW );
        rSequence_getSTRINGA( event, RP_TAGS_FILE_PATH, &fileA );
        rSequence_getSTRINGW( event, RP_TAGS_PROCESS, &procW );
        rSequence_getSTRINGA( event, RP_TAGS_PROCESS, &procA );

        if( rSequence_getBUFFER( event, RP_TAGS_RULES, &rulesBuffer, &rulesBufferSize ) )
        {
            rules = loadYaraRules( rulesBuffer, rulesBufferSize );
        }

        if( NULL != rules )
        {
            if( NULL != fileW )
            {
                fileA = rpal_string_wtoa( fileW );
            }

            if( NULL != procW )
            {
                procA = rpal_string_wtoa( procW );
            }

            if( NULL != fileA )
            {
                rpal_debug_info( "scanning file with yara" );
                matchContext.fileInfo = event;

                // Scan this file
                if( ERROR_SUCCESS != ( scanError = yr_rules_scan_file( rules,
                                                                       fileA,
                                                                       SCAN_FLAGS_FAST_MODE,
                                                                       _yaraFileMatchCallback,
                                                                       &matchContext,
                                                                       60 ) ) )
                {
                    rpal_debug_warning( "Yara file scan error: %d", scanError );
                }
            }
            else if( NULL != procA )
            {
                // Scan processes matching
                if( NULL != ( processes = processLib_getProcessEntries( TRUE ) ) )
                {
                    curProc = processes;
                    while( 0 != curProc->pid )
                    {
                        if( NULL != ( processInfo = processLib_getProcessInfo( curProc->pid, NULL ) ) )
                        {
                            if( rSequence_getSTRINGW( processInfo, RP_TAGS_FILE_PATH, &tmpW ) ||
                                rSequence_getSTRINGA( processInfo, RP_TAGS_FILE_PATH, &tmpA ) )
                            {
                                if( NULL != tmpW )
                                {
                                    tmpA = rpal_string_wtoa( tmpW );
                                }

                                if( NULL != tmpA )
                                {
                                    if( rpal_string_match( procA, tmpA, RPAL_PLATFORM_FS_CASE_SENSITIVITY ) )
                                    {
                                        matchContext.pid = curProc->pid;
                                        matchContext.processInfo = processInfo;

                                        scanError = _scanProcessWith( curProc->pid,
                                                                      &matchContext,
                                                                      rules,
                                                                      NULL );
                                    }
                                }

                                if( NULL != tmpW && NULL != tmpA )
                                {
                                    // If both are allocated it means we got a strW and converted to A
                                    // so we must free the strA version.
                                    rpal_memory_free( tmpA );
                                }
                            }

                            rSequence_free( processInfo );
                        }

                        curProc++;
                    }

                    rpal_memory_free( processes );
                }
            }
            else if( 0 != pid )
            {
                // Scan this process
                matchContext.pid = pid;
                scanError = _scanProcessWith( pid, &matchContext, rules, NULL );
                rSequence_free( matchContext.processInfo );
            }
            else
            {
                // Scan all processes
                if( NULL != ( processes = processLib_getProcessEntries( TRUE ) ) )
                {
                    curProc = processes;
                    while( 0 != curProc->pid )
                    {
                        matchContext.pid = curProc->pid;

                        scanError = _scanProcessWith( curProc->pid, &matchContext, rules, NULL );
                        rSequence_free( matchContext.processInfo );

                        curProc++;
                    }
                        
                    rpal_memory_free( processes );
                }
            }


            if( NULL != fileW && NULL != fileA )
            {
                // If both are allocated it means we got a strW and converted to A
                // so we must free the strA version.
                rpal_memory_free( fileA );
            }

            if( NULL != procW && NULL != procA )
            {
                // If both are allocated it means we got a strW and converted to A
                // so we must free the strA version.
                rpal_memory_free( procA );
            }

            yr_rules_destroy( rules );
        }
        else
        {
            rpal_debug_warning( "no rules in yara scan request" );
            reportError( event, RPAL_ERROR_NOT_SUPPORTED, "yara rules do not parse" );
        }
    }

    rpal_debug_info( "finished on demand yara scan" );
    reportError( event, scanError, "done" );

    yr_finalize_thread();
}
Пример #21
0
static
RPVOID
    continuousFileScan
    (
        rEvent isTimeToStop,
        RPVOID ctx
    )
{
    rSequence event = NULL;
    RU32 timeout = 0;
    RPWCHAR strW = NULL;
    RPCHAR strA = NULL;
    YaraMatchContext matchContext = { 0 };
    RU32 scanError = 0;
    rBloom knownFiles = NULL;

    UNREFERENCED_PARAMETER( ctx );

    if( NULL == ( knownFiles = rpal_bloom_create( 100000, 0.00001 ) ) )
    {
        return NULL;
    }

    while( !rEvent_wait( isTimeToStop, timeout ) )
    {
        if( rQueue_remove( g_async_files_to_scan, (RPVOID*)&event, NULL, MSEC_FROM_SEC( 2 ) ) )
        {
            if( rSequence_getSTRINGW( event, RP_TAGS_FILE_PATH, &strW ) )
            {
                strA = rpal_string_wtoa( strW );
            }
            else
            {
                rSequence_getSTRINGA( event, RP_TAGS_FILE_PATH, &strA );
            }

            if( NULL != strA &&
                rpal_bloom_addIfNew( knownFiles, strA, rpal_string_strlen( strA ) ) )
            {
                rpal_debug_info( "yara scanning %s", strA );
                matchContext.fileInfo = event;

                if( rMutex_lock( g_global_rules_mutex ) )
                {
                    if( NULL != g_global_rules )
                    {
                        rpal_debug_info( "scanning continuous file with yara" );
                        if( ERROR_SUCCESS != ( scanError = yr_rules_scan_file( g_global_rules,
                                                                               strA,
                                                                               SCAN_FLAGS_FAST_MODE,
                                                                               _yaraFileMatchCallback,
                                                                               &matchContext,
                                                                               60 ) ) )
                        {
                            rpal_debug_warning( "Yara file scan error: %d", scanError );
                        }
                    }

                    rMutex_unlock( g_global_rules_mutex );
                }
            }

            if( NULL != strA && NULL != strW )
            {
                // If both are allocated it means we got a strW and converted to A
                // so we must free the strA version.
                rpal_memory_free( strA );
            }

            strA = NULL;
            strW = NULL;
            rSequence_free( event );

            timeout = _TIMEOUT_BETWEEN_FILE_SCANS;
        }
        else
        {
            timeout = 0;
        }
    }

    rpal_bloom_destroy( knownFiles );

    yr_finalize_thread();

    return NULL;
}
static
RPVOID
    spotCheckNewProcesses
    (
        rEvent isTimeToStop,
        RPVOID ctx
    )
{
    RU32 pid = 0;
    RTIME timestamp = 0;
    RTIME timeToWait = 0;
    RTIME now = 0;
    rSequence newProcess = NULL;
    rList hollowedModules = NULL;
    LibOsPerformanceProfile perfProfile = { 0 };

    UNREFERENCED_PARAMETER( ctx );

    perfProfile.sanityCeiling = _SANITY_CEILING;
    perfProfile.lastTimeoutValue = _INITIAL_PROFILED_TIMEOUT;
    perfProfile.targetCpuPerformance = 0;
    perfProfile.globalTargetCpuPerformance = GLOBAL_CPU_USAGE_TARGET;
    perfProfile.enforceOnceIn = 7;
    perfProfile.timeoutIncrementPerSec = _PROFILE_INCREMENT;

    while( !rEvent_wait( isTimeToStop, 0 ) )
    {
        if( rQueue_remove( g_newProcessNotifications, &newProcess, NULL, MSEC_FROM_SEC( 5 ) ) )
        {
            if( rSequence_getRU32( newProcess, RP_TAGS_PROCESS_ID, &pid ) &&
                rSequence_getTIMESTAMP( newProcess, RP_TAGS_TIMESTAMP, &timestamp ) )
            {
                timeToWait = timestamp + _CHECK_SEC_AFTER_PROCESS_CREATION;
                now = rpal_time_getGlobalPreciseTime();
                if( now < timeToWait )
                {
                    timeToWait = timeToWait - now;
                    if( _CHECK_SEC_AFTER_PROCESS_CREATION < timeToWait )
                    {
                        // Sanity check
                        timeToWait = _CHECK_SEC_AFTER_PROCESS_CREATION;
                    }
                    rpal_thread_sleep( (RU32)timeToWait );
                }

                if( NULL != ( hollowedModules = _spotCheckProcess( isTimeToStop, pid, &perfProfile ) ) )
                {
                    if( !rSequence_addLIST( newProcess, RP_TAGS_MODULES, hollowedModules ) )
                    {
                        rList_free( hollowedModules );
                    }
                    else
                    {
                        hbs_publish( RP_TAGS_NOTIFICATION_MODULE_MEM_DISK_MISMATCH, 
                                     newProcess );
                    }
                }
            }

            rSequence_free( newProcess );
        }
    }

    return NULL;
}
Пример #23
0
static
RPVOID
    continuousMemScan
    (
        rEvent isTimeToStop,
        RPVOID ctx
    )
{
    processLibProcEntry* processes = NULL;
    processLibProcEntry* curProc = NULL;
    RU32 thisProcId = 0;
    YaraMatchContext matchContext = { 0 };
    RU32 scanError = 0;

    UNREFERENCED_PARAMETER( ctx );

    thisProcId = processLib_getCurrentPid();

    while( !rEvent_wait( isTimeToStop, 0 ) )
    {
        // Wait until we have global rules to look for.
        if( rMutex_lock( g_global_rules_mutex ) )
        {
            if( NULL == g_global_rules )
            {
                rMutex_unlock( g_global_rules_mutex );
                rEvent_wait( isTimeToStop, MSEC_FROM_SEC( 30 ) );
                continue;
            }
            rMutex_unlock( g_global_rules_mutex );
        }

        if( NULL != ( processes = processLib_getProcessEntries( TRUE ) ) )
        {
            curProc = processes;
            while( 0 != curProc->pid )
            {
                // We can't examine our own memory for the risk of tripping on the sigs themselves.
                if( curProc->pid == thisProcId ) continue;

                rpal_debug_info( "yara scanning pid %d", curProc->pid );

                matchContext.pid = curProc->pid;
                matchContext.processInfo = NULL;
                matchContext.moduleInfo = NULL;

                scanError = _scanProcessWith( curProc->pid, &matchContext, NULL, isTimeToStop );

                rSequence_free( matchContext.processInfo );

                if( rEvent_wait( isTimeToStop, MSEC_FROM_SEC( 30 ) ) ) { break; }

                curProc++;
            }

            rpal_memory_free( processes );
        }
    }

    yr_finalize_thread();

    return NULL;
}
static
RVOID
    scan_for_hollowing
    (
        rpcm_tag eventType,
        rSequence event
    )
{
    RU32 pid = (RU32)( -1 );
    rEvent dummy = NULL;
    rList hollowedModules = NULL;
    rSequence process = NULL;
    LibOsPerformanceProfile perfProfile = { 0 };
    Atom parentAtom = { 0 };

    UNREFERENCED_PARAMETER( eventType );

    if( NULL != ( dummy = rEvent_create( TRUE ) ) )
    {
        perfProfile.targetCpuPerformance = 10;
        perfProfile.globalTargetCpuPerformance = GLOBAL_CPU_USAGE_TARGET_WHEN_TASKED;
        perfProfile.timeoutIncrementPerSec = _PROFILE_INCREMENT;
        perfProfile.enforceOnceIn = 7;
        perfProfile.lastTimeoutValue = _INITIAL_PROFILED_TIMEOUT;
        perfProfile.sanityCeiling = _SANITY_CEILING;

        if( rSequence_getRU32( event, RP_TAGS_PROCESS_ID, &pid ) )
        {
            if( NULL != ( process = processLib_getProcessInfo( pid, NULL ) ) ||
                ( NULL != ( process = rSequence_new() ) &&
                  rSequence_addRU32( process, RP_TAGS_PROCESS_ID, pid ) ) )
            {
                if( NULL != ( hollowedModules = _spotCheckProcess( dummy, pid, &perfProfile ) ) )
                {
                    if( !rSequence_addLIST( process, RP_TAGS_MODULES, hollowedModules ) )
                    {
                        rList_free( hollowedModules );
                    }
                    else
                    {
                        parentAtom.key.category = RP_TAGS_NOTIFICATION_NEW_PROCESS;
                        parentAtom.key.process.pid = pid;
                        if( atoms_query( &parentAtom, 0 ) )
                        {
                            HbsSetParentAtom( process, parentAtom.id );
                        }

                        hbs_publish( RP_TAGS_NOTIFICATION_MODULE_MEM_DISK_MISMATCH,
                                     process );
                    }
                }
            }

            if( rpal_memory_isValid( process ) )
            {
                rSequence_free( process );
            }
        }

        rEvent_free( dummy );
    }
}
Пример #25
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;
}
Пример #26
0
static
RVOID
    processFile
    (
        rSequence notif
    )
{
    RPCHAR fileA = NULL;
    RPWCHAR fileW = NULL;
    RPU8 fileContent = NULL;
    RU32 fileSize = 0;
    CryptoLib_Hash hash = { 0 };

    if( NULL != notif )
    {
        obsLib_resetSearchState( matcherA );
        obsLib_resetSearchState( matcherW );

        if( ( rSequence_getSTRINGA( notif, RP_TAGS_FILE_PATH, &fileA ) &&
              obsLib_setTargetBuffer( matcherA, 
                                      fileA, 
                                      ( rpal_string_strlen( fileA ) + 1 ) * sizeof( RCHAR ) ) &&
              obsLib_nextHit( matcherA, NULL, NULL ) ) ||
            ( rSequence_getSTRINGW( notif, RP_TAGS_FILE_PATH, &fileW ) &&
              obsLib_setTargetBuffer( matcherW, 
                                      fileW, 
                                      ( rpal_string_strlenw( fileW ) + 1 ) * sizeof( RWCHAR ) ) &&
              obsLib_nextHit( matcherW, NULL, NULL ) ) )
        {
            // This means it's a file of interest.
            if( ( NULL != fileA &&
                  ( ( DOCUMENT_MAX_SIZE >= rpal_file_getSize( fileA, TRUE ) &&
                      rpal_file_read( fileA, (RPVOID*)&fileContent, &fileSize, TRUE ) &&
                      CryptoLib_hash( fileContent, fileSize, &hash ) ) ||
                    CryptoLib_hashFileA( fileA, &hash, TRUE ) ) ) ||
                ( NULL != fileW &&
                  ( ( DOCUMENT_MAX_SIZE >= rpal_file_getSizew( fileW, TRUE ) &&
                      rpal_file_readw( fileW, (RPVOID*)&fileContent, &fileSize, TRUE ) &&
                      CryptoLib_hash( fileContent, fileSize, &hash ) ) ||
                    CryptoLib_hashFileW( fileW, &hash, TRUE ) ) ) )
            {
                // We acquired the hash, either by reading the entire file in memory
                // which we will use for caching, or if it was too big by hashing it
                // sequentially on disk.
                rSequence_unTaintRead( notif );
                rSequence_addBUFFER( notif, RP_TAGS_HASH, (RPU8)&hash, sizeof( hash ) );
                notifications_publish( RP_TAGS_NOTIFICATION_NEW_DOCUMENT, notif );
            }

            if( rMutex_lock( cacheMutex ) )
            {
                if( NULL == fileContent ||
                    !rSequence_addBUFFER( notif, RP_TAGS_FILE_CONTENT, fileContent, fileSize ) ||
                    !HbsRingBuffer_add( documentCache, notif ) )
                {
                    rSequence_free( notif );
                }

                rMutex_unlock( cacheMutex );
            }
            else
            {
                rSequence_free( notif );
            }

            if( NULL != fileContent )
            {
                rpal_memory_free( fileContent );
            }
        }
        else
        {
            rSequence_free( notif );
        }
    }
}
Пример #27
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 );
    }
}
static
RVOID
    processFileIo
    (
        rpcm_tag notifType,
        rSequence event
    )
{
    ProcExtInfo* ctx = NULL;
    RPNCHAR path = NULL;
    RPVOID patternCtx = 0;
    RU8 patternId = 0;
    RPU8 atomId = NULL;
    RU32 pid = 0;
    rSequence newEvent = NULL;

    UNREFERENCED_PARAMETER( notifType );

    if( rSequence_getSTRINGN( event, RP_TAGS_FILE_PATH, &path ) &&
        HbsGetParentAtom( event, &atomId ) &&
        rSequence_getRU32( event, RP_TAGS_PROCESS_ID, &pid ) )
    {
        if( rMutex_lock( g_mutex ) )
        {
            obsLib_resetSearchState( g_extensions );
            if( obsLib_setTargetBuffer( g_extensions,
                                        path,
                                        rpal_string_strsize( path ) ) )
            {
                while( obsLib_nextHit( g_extensions, &patternCtx, NULL ) )
                {
                    if( NULL != ctx ||
                        NULL != ( ctx = getProcContext( atomId ) ) )
                    {
                        patternId = (RU8)PTR_TO_NUMBER( patternCtx );

                        if( !IS_FLAG_ENABLED( ctx->extBitMask, (RU64)1 << patternId ) )
                        {
                            rpal_debug_info( "process " RF_U32 " observed file io " RF_U64, 
                                             pid, patternId + 1 );
                            ENABLE_FLAG( ctx->extBitMask, (RU64)1 << patternId );
                            
                            if( NULL != ( newEvent = rSequence_new() ) )
                            {
                                HbsSetParentAtom( newEvent, atomId );
                                rSequence_addRU32( newEvent, RP_TAGS_PROCESS_ID, pid );
                                rSequence_addRU8( newEvent, RP_TAGS_RULE_NAME, patternId + 1 );
                                rSequence_addSTRINGN( newEvent, RP_TAGS_FILE_PATH, ctx->processPath );

                                hbs_publish( RP_TAGS_NOTIFICATION_FILE_TYPE_ACCESSED, newEvent );
                                rSequence_free( newEvent );
                            }
                        }
                    }
                    else
                    {
                        rpal_debug_error( "error getting process context" );
                        break;
                    }
                }
            }

            rMutex_unlock( g_mutex );
        }
    }
}
Пример #29
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;
}
Пример #30
0
static RVOID
    publishCloudNotifications
    (
        rList notifications
    )
{
    rSequence notif = NULL;
    RPU8 buff = NULL;
    RU32 buffSize = 0;
    RPU8 sig = NULL;
    RU32 sigSize = 0;
    rpHCPId curId = { 0 };
    rSequence cloudEvent = NULL;
    rSequence targetId = { 0 };
    RU32 eventId = 0;
    rSequence localEvent = NULL;
    RU64 expiry = 0;
    rpHCPId tmpId = { 0 };
    rSequence receipt = NULL;

    while( rList_getSEQUENCE( notifications, RP_TAGS_HBS_CLOUD_NOTIFICATION, &notif ) )
    {
        cloudEvent = NULL;

        if( rSequence_getBUFFER( notif, RP_TAGS_BINARY, &buff, &buffSize ) &&
            rSequence_getBUFFER( notif, RP_TAGS_SIGNATURE, &sig, &sigSize ) )
        {
            if( CryptoLib_verify( buff, buffSize, hbs_cloud_pub_key, sig ) )
            {
                if( !rpHcpI_getId( &curId ) )
                {
                    rpal_debug_error( "error getting current id for cloud notifications." );
                }
                else
                {
                    if( !rSequence_deserialise( &cloudEvent, buff, buffSize, NULL ) )
                    {
                        cloudEvent = NULL;
                        rpal_debug_warning( "error deserializing cloud event." );
                    }
                }
            }
            else
            {
                rpal_debug_warning( "cloud event signature invalid." );
            }
        }

        if( rpal_memory_isValid( cloudEvent ) )
        {
            if( rSequence_getSEQUENCE( cloudEvent, RP_TAGS_HCP_ID, &targetId ) &&
                rSequence_getRU32( cloudEvent, RP_TAGS_HBS_NOTIFICATION_ID, &eventId ) &&
                rSequence_getSEQUENCE( cloudEvent, RP_TAGS_HBS_NOTIFICATION, &localEvent ) )
            {
                rSequence_getTIMESTAMP( cloudEvent, RP_TAGS_EXPIRY, &expiry );

                tmpId = rpHcpI_seqToHcpId( targetId );

                curId.id.configId = 0;
                tmpId.id.configId = 0;
                
                if( NULL != ( receipt = rSequence_new() ) )
                {
                    if( rSequence_addSEQUENCE( receipt, 
                                               RP_TAGS_HBS_CLOUD_NOTIFICATION, 
                                               rSequence_duplicate( cloudEvent ) ) )
                    {
                        if( !rQueue_add( g_hbs_state.outQueue, receipt, 0 ) )
                        {
                            rSequence_free( receipt );
                            receipt = NULL;
                        }
                    }
                    else
                    {
                        rSequence_free( receipt );
                        receipt = NULL;
                    }
                }

                if( curId.raw == tmpId.raw &&
                    rpal_time_getGlobal() <= expiry )
                {
                    if( !notifications_publish( eventId, localEvent ) )
                    {
                        rpal_debug_error( "error publishing event from cloud." );
                    }
                }
                else
                {
                    rpal_debug_warning( "event expired or for wrong id." );
                }
            }

            if( rpal_memory_isValid( cloudEvent ) )
            {
                rSequence_free( cloudEvent );
                cloudEvent = NULL;
            }
        }
    }
}