Exemplo n.º 1
0
RBOOL
    rpal_blob_remove
    (
        rBlob blob,
        RU32 startOffset,
        RU32 size
    )
{
    RBOOL isSuccess = FALSE;
    _prBlob pBlob = (_prBlob)blob;
    
    if( NULL != pBlob &&
        IS_WITHIN_BOUNDS( pBlob->pData + startOffset, size, pBlob->pData, pBlob->sizeUsed ) &&
        rpal_memory_isValid( pBlob->pData ) )
    {
        rpal_memory_memcpy( pBlob->pData + startOffset, pBlob->pData + startOffset + size, pBlob->sizeUsed - size - startOffset );
        pBlob->sizeUsed -= size;

        if( rpal_memory_isValid( pBlob->pData ) )
        {
            pBlob->pData = rpal_memory_realloc_from( pBlob->pData, pBlob->sizeUsed + sizeof( RWCHAR ), pBlob->from );
            pBlob->currentSize = pBlob->sizeUsed;

            if( NULL != pBlob->pData )
            {
                // We allocate WCHAR more than we need always to ensure that if the buffer contains a wide string it will be terminated
                rpal_memory_zero( pBlob->pData + pBlob->sizeUsed, sizeof( RWCHAR ) );
                isSuccess = TRUE;
            }
        }
    }

    return isSuccess;
}
static RVOID
    modKernelModeDiff
    (
        rEvent isTimeToStop
    )
{
    RU32 i = 0;
    RU32 nScratch = 0;
    RU32 prev_nScratch = 0;
    KernelAcqModule new_from_kernel[ 200 ] = { 0 };
    KernelAcqModule prev_from_kernel[ 200 ] = { 0 };

    while( !rEvent_wait( isTimeToStop, 1000 ) )
    {
        nScratch = ARRAY_N_ELEM( new_from_kernel );
        rpal_memory_zero( new_from_kernel, sizeof( new_from_kernel ) );
        if( !kAcq_getNewModules( new_from_kernel, &nScratch ) )
        {
            rpal_debug_warning( "kernel acquisition for new modules failed" );
            g_is_kernel_failure = TRUE;
            break;
        }

        for( i = 0; i < prev_nScratch; i++ )
        {
            notifyOfKernelModule( &(prev_from_kernel[ i ]) );
        }

        rpal_memory_memcpy( prev_from_kernel, new_from_kernel, sizeof( prev_from_kernel ) );
        prev_nScratch = nScratch;
    }
}
Exemplo n.º 3
0
RBOOL
    rStack_atIndex
    (
        rStack stack,
        RU32 i,
        RPVOID pOutElem
    )
{
    RBOOL isSuccess = FALSE;
    _prStack pStack = (_prStack)stack;
    RPVOID tmpElem = NULL;

    if( NULL != stack &&
        NULL != pOutElem &&
        0 < pStack->nElements &&
        i < pStack->nElements )
    {
        if( rMutex_lock( pStack->lock ) )
        {
            tmpElem = rpal_blob_arrElem( pStack->blob, pStack->elemSize, i );

            if( NULL != tmpElem )
            {
                rpal_memory_memcpy( pOutElem, tmpElem, pStack->elemSize );

                isSuccess = TRUE;
            }

            rMutex_unlock( pStack->lock );
        }
    }

    return isSuccess;
}
Exemplo n.º 4
0
RBOOL
	rpal_blob_insert
	(
		rBlob blob,
		RPVOID pData,
		RU32 size,
        RU32 offset
	)
{
	RBOOL isAdded = FALSE;

    _prBlob pBlob = (_prBlob)blob;

	if( rpal_memory_isValid( blob ) &&
		NULL != pData &&
		0 != size )
	{
		if( pBlob->currentSize - pBlob->sizeUsed < size )
		{
			pBlob->currentSize += ( 0 != pBlob->growBy ? pBlob->growBy : size );
			pBlob->pData = rpal_memory_realloc_from( pBlob->pData,
													 pBlob->currentSize + sizeof( RWCHAR ),
													 pBlob->from );
		}

		if( rpal_memory_isValid( pBlob->pData ) )
		{
            // Relocate existing data
            rpal_memory_memmove( pBlob->pData + offset + size, 
                                 pBlob->pData + offset, 
                                 pBlob->sizeUsed - offset );

			rpal_memory_memcpy( pBlob->pData + offset, pData, size );

			pBlob->sizeUsed += size;
            
            // We allocate WCHAR more than we need always to ensure that if the buffer contains a wide string it will be terminated
            rpal_memory_zero( pBlob->pData + pBlob->sizeUsed, sizeof( RWCHAR ) );

			isAdded = TRUE;
		}
	}
    else if( NULL == pData ||
		     0 == size )
    {
        isAdded = TRUE;
    }

    if( isAdded )
    {
        if( !rpal_memory_isValid( pBlob->pData ) )
        {
            isAdded = FALSE;
            rpal_debug_break();
        }
    }

	return isAdded;
}
Exemplo n.º 5
0
static
RBOOL
    getStoreConf
    (

    )
{
    RBOOL isSuccess = FALSE;

    RPU8 storeFile = NULL;
    RU32 storeFileSize = 0;

    rpHCPIdentStore* storeV2 = NULL;

    OBFUSCATIONLIB_DECLARE( store, RP_HCP_CONFIG_IDENT_STORE );

    OBFUSCATIONLIB_TOGGLE( store );

    if( rpal_file_read( (RPNCHAR)store, (RPVOID)&storeFile, &storeFileSize, FALSE ) )
    {
        if( sizeof( rpHCPIdentStore ) <= storeFileSize )
        {
            storeV2 = (rpHCPIdentStore*)storeFile;
            if( storeV2->enrollmentTokenSize == storeFileSize - sizeof( rpHCPIdentStore ) )
            {
                isSuccess = TRUE;
                rpal_debug_info( "ident store found" );
                if( NULL != ( g_hcpContext.enrollmentToken = rpal_memory_alloc( storeV2->enrollmentTokenSize ) ) )
                {
                    rpal_memory_memcpy( g_hcpContext.enrollmentToken, storeV2->enrollmentToken, storeV2->enrollmentTokenSize );
                    g_hcpContext.enrollmentTokenSize = storeV2->enrollmentTokenSize;
                }
                g_hcpContext.currentId = storeV2->agentId;
            }
            else
            {
                rpal_debug_warning( "inconsistent ident store, reseting" );
                rpal_file_delete( (RPNCHAR)store, FALSE );
            }
        }

        rpal_memory_free( storeFile );
    }

    OBFUSCATIONLIB_TOGGLE( store );

    // Set some always-correct defaults
    g_hcpContext.currentId.id.platformId = RP_HCP_ID_MAKE_PLATFORM( RP_HCP_PLATFORM_CURRENT_CPU, RP_HCP_PLATFORM_CURRENT_MAJOR, RP_HCP_PLATFORM_CURRENT_MINOR );

    return isSuccess;
}
Exemplo n.º 6
0
rBlob
    rpal_blob_duplicate_from
    (
        rBlob original,
		RU32 from
    )
{
    _prBlob newBlob = NULL;
    _prBlob originalBlob = (_prBlob)original;

    if( NULL != original )
    {
        if( NULL != ( newBlob = rpal_memory_alloc_from( sizeof( _rBlob ), from ) ) )
        {
            newBlob->currentSize = originalBlob->currentSize;
            newBlob->growBy = originalBlob->growBy;
            newBlob->sizeUsed = originalBlob->sizeUsed;
			newBlob->from = from;

            if( 0 != originalBlob->currentSize &&
                NULL != originalBlob->pData )
            {
                newBlob->pData = rpal_memory_alloc_from( newBlob->currentSize + sizeof( RWCHAR ), from );
            
                if( NULL != newBlob->pData )
                {
                    rpal_memory_memcpy( newBlob->pData, originalBlob->pData, newBlob->currentSize + sizeof( RWCHAR ) );

                    if( !rpal_memory_isValid( newBlob->pData ) )
                    {
                        rpal_memory_free( newBlob );
                        newBlob = NULL;
                        rpal_debug_break();
                    }
                }
                else
                {
                    rpal_memory_free( newBlob );
                    newBlob = NULL;
                    rpal_debug_break();
                }
            }
            else
            {
                newBlob->pData = NULL;
            }
        }
    }

    return newBlob;
}
Exemplo n.º 7
0
RBOOL
	rpal_blob_add
	(
		rBlob blob,
		RPVOID pData,
		RU32 size
	)
{
	RBOOL isAdded = FALSE;

	if( rpal_memory_isValid( blob ) &&
		NULL != pData &&
		0 != size )
	{
		if( ((_prBlob)blob)->currentSize - ((_prBlob)blob)->sizeUsed < size )
		{
			((_prBlob)blob)->currentSize += ( ( 0 != ((_prBlob)blob)->growBy && size < ((_prBlob)blob)->growBy ) ? ((_prBlob)blob)->growBy : size );
			((_prBlob)blob)->pData = rpal_memory_realloc_from( ((_prBlob)blob)->pData,
                                                               ((_prBlob)blob)->currentSize + sizeof( RWCHAR ),
															   ((_prBlob)blob)->from );
		}

		if( rpal_memory_isValid( ((_prBlob)blob)->pData ) )
		{
			rpal_memory_memcpy( ((_prBlob)blob)->pData + ((_prBlob)blob)->sizeUsed, pData, size );

			((_prBlob)blob)->sizeUsed += size;
            
            // We allocate WCHAR more than we need always to ensure that if the buffer contains a wide string it will be terminated
            rpal_memory_zero( ((_prBlob)blob)->pData + ((_prBlob)blob)->sizeUsed, sizeof( RWCHAR ) );

			isAdded = TRUE;
		}
	}
    else if( NULL == pData ||
		     0 == size )
    {
        isAdded = TRUE;
    }

    if( isAdded )
    {
        if( !rpal_memory_isValid( ((_prBlob)blob)->pData ) )
        {
            isAdded = FALSE;
            rpal_debug_break();
        }
    }

	return isAdded;
}
Exemplo n.º 8
0
RBOOL
    rStack_removeWith
    (
        rStack stack,
        rStack_compareFunc compFunc,
        RPVOID ref,
        RPVOID pElem
    )
{
    RBOOL isRemoved = FALSE;
    _prStack pStack = (_prStack)stack;
    RU32 i = 0;
    RPVOID tmpElem = NULL;

    if( NULL != stack &&
        NULL != compFunc )
    {
        if( rMutex_lock( pStack->lock ) )
        {
            for( i = 0; i < ( rpal_blob_getSize( pStack->blob ) / pStack->elemSize ); i++ )
            {
                if( NULL != ( tmpElem = rpal_blob_arrElem( pStack->blob, pStack->elemSize, i ) ) )
                {
                    if( compFunc( tmpElem, ref ) )
                    {
                        if( NULL != pElem )
                        {
                            rpal_memory_memcpy( pElem, tmpElem, pStack->elemSize );
                        }

                        if( rpal_blob_remove( pStack->blob, i * pStack->elemSize, pStack->elemSize ) )
                        {
                            pStack->nElements--;

                            isRemoved = TRUE;
                        }
                        break;
                    }
                }
            }

            rMutex_unlock( pStack->lock );
        }
    }

    return isRemoved;
}
Exemplo n.º 9
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 );
        }
    }
}
static
ProcExtInfo*
    getProcContext
    (
        RPU8 atomId
    )
{
    ProcExtInfo* procInfo = NULL;
    RU32 index = 0;

    if( (RU32)-1 != ( index = rpal_binsearch_array( g_procContexts->elements,
                                                    g_procContexts->nElements,
                                                    sizeof( ProcExtInfo* ),
                                                    &atomId,
                                                    (rpal_ordering_func)_cmpContext ) ) )
    {
        procInfo = g_procContexts->elements[ index ];
    }
    else
    {
        if( NULL != ( procInfo = rpal_memory_alloc( sizeof( *procInfo ) ) ) )
        {
            rpal_memory_memcpy( procInfo->atomId, atomId, sizeof( procInfo->atomId ) );

            if( !rpal_vector_add( g_procContexts, procInfo ) )
            {
                rpal_memory_free( procInfo );
                rpal_debug_error( "error adding new process to history" );
                procInfo = NULL;
            }
            else
            {
                rpal_sort_array( g_procContexts->elements, 
                                 g_procContexts->nElements, 
                                 sizeof( ProcExtInfo* ), 
                                 (rpal_ordering_func)_cmpContext );
            }
        }
    }

    return procInfo;
}
RPRIVATE
RVOID
    dnsKmDiffThread
    (
        rEvent isTimeToStop
    )
{
    RU8 new_from_kernel[ DNS_KB_PACKET_BUFFER * 1024 ] = { 0 };
    RU8 prev_from_kernel[ DNS_KB_PACKET_BUFFER * 1024 ] = { 0 };

    RU32 sizeInNew = 0;
    RU32 sizeInPrev = 0;

    KernelAcqDnsPacket* pPacket = NULL;

    while( !rEvent_wait( isTimeToStop, 1000 ) )
    {
        rpal_memory_zero( new_from_kernel, sizeof( new_from_kernel ) );
        sizeInNew = sizeof( new_from_kernel );

        if( !kAcq_getNewDnsPackets( (KernelAcqDnsPacket*)new_from_kernel, &sizeInNew ) )
        {
            rpal_debug_warning( "kernel acquisition for new dns packets failed" );
            break;
        }

        pPacket = (KernelAcqDnsPacket*)prev_from_kernel;
        while( IS_WITHIN_BOUNDS( pPacket, sizeof( *pPacket ), prev_from_kernel, sizeInPrev ) &&
               0 != pPacket->ts &&
               IS_WITHIN_BOUNDS( pPacket, sizeof( *pPacket ) + pPacket->packetSize, prev_from_kernel, sizeInPrev ) )
        {
            processDnsPacket( pPacket );

            pPacket = (KernelAcqDnsPacket*)( (RPU8)pPacket + sizeof( *pPacket ) + pPacket->packetSize );
        }

        rpal_memory_memcpy( prev_from_kernel, new_from_kernel, sizeInNew );
        sizeInPrev = sizeInNew;
    }
}
Exemplo n.º 12
0
RBOOL
    rStack_pop
    (
        rStack stack,
        RPVOID pOutElem
    )
{
    RBOOL isSuccess = FALSE;
    _prStack pStack = (_prStack)stack;
    RPVOID tmpElem = NULL;

    if( NULL != stack &&
        NULL != pOutElem &&
        0 < pStack->nElements )
    {
        if( rMutex_lock( pStack->lock ) )
        {
            tmpElem = rpal_blob_arrElem( pStack->blob, pStack->elemSize, pStack->nElements - 1 );

            if( NULL != tmpElem )
            {
                rpal_memory_memcpy( pOutElem, tmpElem, pStack->elemSize );

                if( rpal_blob_remove( pStack->blob, 
                                      pStack->elemSize * ( pStack->nElements - 1 ), 
                                      pStack->elemSize ) )
                {
                    isSuccess = TRUE;
                    pStack->nElements--;
                }
            }

            rMutex_unlock( pStack->lock );
        }
    }

    return isSuccess;
}
// Parses a label from a DNS packet and returns a pointer to the next byte after the label
// or label chain to be used to continue parsing the packet.
// If a human label is specified, will also assemble a human readable version of the labels
// in the buffer.
RPRIVATE
DnsLabel*
    dnsReadLabels
    (
        DnsLabel* pLabel,
        RCHAR humanLabel[ DNS_LABEL_MAX_SIZE ],
        RPU8 packetStart,
        RSIZET packetSize,
        RU32 labelOffset,
        RU32 recursiveDepth
    )
{
    RU32 copied = labelOffset;

    if( 3 < recursiveDepth )
    {
        return NULL;
    }

    if( NULL == pLabel )
    {
        return NULL;
    }

    while( IS_WITHIN_BOUNDS( pLabel, sizeof( *pLabel ), packetStart, packetSize ) &&
            ( DNS_LABEL_IS_OFFSET( pLabel ) ||
                ( IS_WITHIN_BOUNDS( pLabel, sizeof( *pLabel ) + pLabel->nChar, packetStart, packetSize ) &&
                0 != pLabel->nChar ) ) )
    {
        // It's possible for a pointer to be terminating a traditional label
        if( DNS_LABEL_IS_OFFSET( pLabel ) )
        {
            // Pointer to a label
            DnsLabel* tmpLabel = NULL;
            RU16 offset = DNS_LABEL_OFFSET( pLabel );

            if( !IS_WITHIN_BOUNDS( (RPU8)packetStart + offset, sizeof( RU16 ), packetStart, packetSize ) )
            {
                rpal_debug_warning( "error parsing dns packet" );
                return NULL;
            }

            tmpLabel = (DnsLabel*)( (RPU8)packetStart + offset );

            if( NULL == dnsReadLabels( tmpLabel, humanLabel, packetStart, packetSize, copied, recursiveDepth + 1 ) )
            {
                return NULL;
            }

            // Pointers are always terminating the label. So since there is
            // no 0 terminated label we don't need to skip an extra byte, we
            // just skip the current label pointer value.
            pLabel = (DnsLabel*)( (RPU8)pLabel + sizeof( RU16 ) );
            return pLabel;
        }
        else
        {
            if( DNS_LABEL_MAX_SIZE < copied + 1 + pLabel->nChar )
            {
                rpal_debug_warning( "error parsing dns packet" );
                return NULL;
            }

            if( NULL != humanLabel )
            {
                if( 0 != copied )
                {
                    humanLabel[ copied ] = '.';
                    copied++;
                }
                rpal_memory_memcpy( (RPU8)humanLabel + copied, pLabel->label, pLabel->nChar );
                copied += pLabel->nChar;
            }

            pLabel = (DnsLabel*)( (RPU8)pLabel + pLabel->nChar + 1 );
        }
    }

    // We do a last sanity check. A valid label parsing should end in a 0-val nChar within
    // the buffer, so we check it's all valid, otherwise we'll assume an error and will return an error.
    if( !IS_WITHIN_BOUNDS( pLabel, sizeof( *pLabel ), packetStart, packetSize ) ||
        0 != pLabel->nChar )
    {
        rpal_debug_warning( "error parsing dns packet" );
        return NULL;
    }

    // Get to the next valid byte, so we skip the 0-termination.
    pLabel = (DnsLabel*)( (RPU8)pLabel + 1 );

    return pLabel;
}
static
RU32
    _krnlSendReceive
    (
        RU32 op,
        RPU8 pArgs,
        RU32 argsSize,
        RPU8 pResult,
        RU32 resultSize,
        RU32* pSizeUsed
    )
{
    RU32 error = (RU32)(-1);
    RU32 nRetries = 1;

    // Check whether this particular function is available on
    // this platform via kernel.
    if( op >= KERNEL_ACQ_OP_COUNT ||
        !g_platform_availability[ op ] )
    {
        return error;
    }

    if( rMutex_lock( g_km_mutex ) )
    {
        while( 0 != nRetries )
        {
#ifdef RPAL_PLATFORM_MACOSX
            KernelAcqCommand cmd = { 0 };
            cmd.pArgs = pArgs;
            cmd.argsSize = argsSize;
            cmd.pResult = pResult;
            cmd.resultSize = resultSize;
            cmd.pSizeUsed = pSizeUsed;
            fd_set readset = { 0 };
            struct timeval timeout = { 0 };
            int waitVal = 0;

            error = setsockopt( g_km_socket, SYSPROTO_CONTROL, op, &cmd, sizeof( cmd ) );
#elif defined( RPAL_PLATFORM_WINDOWS )
            RU32 ioBufferSize = sizeof( KernelAcqCommand ) + argsSize;
            RPU8 ioBuffer = NULL;
            KernelAcqCommand* pCmd = NULL;

            if( NULL != ( ioBuffer = rpal_memory_alloc( ioBufferSize ) ) )
            {
                pCmd = (KernelAcqCommand*)ioBuffer;
                pCmd->op = op;
                pCmd->dataOffset = sizeof( KernelAcqCommand );
                pCmd->argsSize = argsSize;
                if( NULL != pArgs && 0 != argsSize )
                {
                    rpal_memory_memcpy( pCmd->data, pArgs, argsSize );
                }

                if( DeviceIoControl( g_km_handle,
                                     (DWORD)IOCTL_EXCHANGE_DATA,
                                     ioBuffer,
                                     ioBufferSize,
                                     pResult,
                                     resultSize,
                                     (LPDWORD)pSizeUsed,
                                     NULL ) )
                {
                    error = 0;
                }
                else
                {
                    error = rpal_error_getLast();
                }

                rpal_memory_free( ioBuffer );
            }
            else
            {
                error = RPAL_ERROR_NOT_ENOUGH_MEMORY;
            }
#else
            UNREFERENCED_PARAMETER( op );
            UNREFERENCED_PARAMETER( pArgs );
            UNREFERENCED_PARAMETER( argsSize );
            UNREFERENCED_PARAMETER( pResult );
            UNREFERENCED_PARAMETER( resultSize );
            UNREFERENCED_PARAMETER( pSizeUsed );
            break;
#endif

            // Success, return in.
            if( 0 == error )
            {
                break;
            }

            // Looks like we had a failure, this may be a sign from the kernel
            // that it must unload, so we'll give it a chance and toggle our
            // connection.
            _kAcq_deinit( FALSE );
            if( !_kAcq_init( FALSE ) )
            {
                break;
            }
            nRetries--;
        }
        rMutex_unlock( g_km_mutex );
    }

    return error;
}
Exemplo n.º 15
0
static
RVOID
    processCodeIdentW
    (
        RPWCHAR name,
        CryptoLib_Hash* pFileHash,
        RU64 codeSize,
        rSequence originalEvent
    )
{
    CodeIdent ident = { 0 };
    rSequence notif = NULL;
    rSequence sig = NULL;
    RBOOL isSigned = FALSE;
    RBOOL isVerifiedLocal = FALSE;
    RBOOL isVerifiedGlobal = FALSE;
    
    ident.codeSize = codeSize;

    if( NULL != name )
    {
        CryptoLib_hash( name, rpal_string_strlenw( name ) * sizeof( RWCHAR ), &ident.nameHash );
    }

    if( NULL != pFileHash )
    {
        rpal_memory_memcpy( &ident.fileHash, pFileHash, sizeof( *pFileHash ) );
    }

    if( rMutex_lock( g_mutex ) )
    {
        if( rpal_bloom_addIfNew( g_knownCode, &ident, sizeof( ident ) ) )
        {
            rMutex_unlock( g_mutex );

            if( NULL != ( notif = rSequence_new() ) )
            {
                hbs_markAsRelated( originalEvent, notif );

                if( ( rSequence_addSTRINGW( notif, RP_TAGS_FILE_PATH, name ) ||
                      rSequence_addSTRINGW( notif, RP_TAGS_DLL, name ) ||
                      rSequence_addSTRINGW( notif, RP_TAGS_EXECUTABLE, name ) ) &&
                    rSequence_addRU32( notif, RP_TAGS_MEMORY_SIZE, (RU32)codeSize ) &&
                    rSequence_addTIMESTAMP( notif, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() ) )
                {
                    if( NULL != pFileHash )
                    {
                        rSequence_addBUFFER( notif, RP_TAGS_HASH, (RPU8)pFileHash, sizeof( *pFileHash ) );
                    }

                    if( libOs_getSignature( name,
                                            &sig,
                                            ( OSLIB_SIGNCHECK_NO_NETWORK | OSLIB_SIGNCHECK_CHAIN_VERIFICATION ),
                                            &isSigned,
                                            &isVerifiedLocal,
                                            &isVerifiedGlobal ) )
                    {
                        if( !rSequence_addSEQUENCE( notif, RP_TAGS_SIGNATURE, sig ) )
                        {
                            rSequence_free( sig );
                        }
                    }

                    notifications_publish( RP_TAGS_NOTIFICATION_CODE_IDENTITY, notif );
                }
                rSequence_free( notif );
            }
        }
        else
        {
            rMutex_unlock( g_mutex );
        }
    }
}
Exemplo n.º 16
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;
}
Exemplo n.º 17
0
RBOOL
    processMessage
    (
        rSequence seq
    )
{
    RBOOL isSuccess = FALSE;
    RU8 command = 0;
    rSequence idSeq = NULL;
    rpHCPId tmpId = { 0 };
    rpHCPId emptyId = { 0 };
    RU64 tmpTime = 0;
    rThread hQuitThread = 0;

    rpHCPIdentStore identStore = {0};
    RPU8 token = NULL;
    RU32 tokenSize = 0;

    OBFUSCATIONLIB_DECLARE( store, RP_HCP_CONFIG_IDENT_STORE );

    if( NULL != seq )
    {
        if( rSequence_getRU8( seq, RP_TAGS_OPERATION, &command ) )
        {
            rpal_debug_info( "Received command 0x%0X.", command );
            switch( command )
            {
            case RP_HCP_COMMAND_LOAD_MODULE:
                isSuccess = loadModule( &g_hcpContext, seq );
                break;
            case RP_HCP_COMMAND_UNLOAD_MODULE:
                isSuccess = unloadModule( &g_hcpContext, seq );
                break;
            case RP_HCP_COMMAND_SET_HCP_ID:
                if( rSequence_getSEQUENCE( seq, RP_TAGS_HCP_IDENT, &idSeq ) )
                {
                    tmpId = seqToHcpId( idSeq );

                    if( 0 != rpal_memory_memcmp( &emptyId, &tmpId, sizeof( emptyId ) ) )
                    {
                        g_hcpContext.currentId = tmpId;
                        
                        OBFUSCATIONLIB_TOGGLE( store );
                        
                        if( rSequence_getBUFFER( seq, RP_TAGS_HCP_ENROLLMENT_TOKEN, &token, &tokenSize ) )
                        {
                            identStore.agentId = tmpId;

                            if( saveHcpId( (RPNCHAR)store, &identStore, token, tokenSize ) )
                            {
                                isSuccess = TRUE;
                            }

                            if( NULL != g_hcpContext.enrollmentToken )
                            {
                                rpal_memory_free( g_hcpContext.enrollmentToken );
                                g_hcpContext.enrollmentToken = NULL;
                            }

                            if( NULL != ( g_hcpContext.enrollmentToken = rpal_memory_alloc( tokenSize ) ) )
                            {
                                rpal_memory_memcpy( g_hcpContext.enrollmentToken, token, tokenSize );
                                g_hcpContext.enrollmentTokenSize = tokenSize;

                                isSuccess = TRUE;
                            }
                        }
                        else
                        {
                            rpal_debug_warning( "hcp id is missing token" );
                        }

                        OBFUSCATIONLIB_TOGGLE( store );
                    }
                }
                break;
            case RP_HCP_COMMAND_SET_GLOBAL_TIME:
                if( rSequence_getTIMESTAMP( seq, RP_TAGS_TIMESTAMP, &tmpTime ) )
                {
                    rpal_time_setGlobalOffset( tmpTime - rpal_time_getLocal() );
                    isSuccess = TRUE;
                }
                break;
            case RP_HCP_COMMAND_QUIT:
                if( 0 != ( hQuitThread = rpal_thread_new( thread_quitAndCleanup, NULL ) ) )
                {
                    rpal_thread_free( hQuitThread );
                    isSuccess = TRUE;
                }
                break;
            case RP_HCP_COMMAND_UPGRADE:
                isSuccess = upgradeHcp( seq );
                break;
            default:
                break;
            }

            if( isSuccess )
            {
                rpal_debug_info( "Command was successful." );
            }
            else
            {
                rpal_debug_warning( "Command was not successful." );
            }
        }
    }

    return isSuccess;
}