Exemple #1
0
/********************************************************************
 * Function: DCE2_ClInsertActTracker()
 *
 * Creates and inserts a new activity tracker into a list.
 *
 * Arguments:
 *  DCE2_ClTracker *
 *      Pointer to connectionless tracker.
 *  DceRpcClHdr *
 *      Pointer to the connectionless header in the packet.
 *
 * Returns:
 *  DCE2_ClActTracker *
 *      A valid pointer to an activity tracker on success.
 *      NULL on error.
 *
 ********************************************************************/
static DCE2_ClActTracker * DCE2_ClInsertActTracker(DCE2_ClTracker *clt, DceRpcClHdr *cl_hdr)
{
    Uuid *uuid = (Uuid *)DCE2_Alloc(sizeof(Uuid), DCE2_MEM_TYPE__CL_ACT);
    DCE2_ClActTracker *at;
    DCE2_Ret status;

    if (uuid == NULL)
        return NULL;

    at = (DCE2_ClActTracker *)DCE2_Alloc(sizeof(DCE2_ClActTracker), DCE2_MEM_TYPE__CL_ACT);
    if (at == NULL)
    {
        DCE2_Free((void *)uuid, sizeof(Uuid), DCE2_MEM_TYPE__CL_ACT);
        return NULL;
    }

    DCE2_CopyUuid(uuid, &cl_hdr->act_id, DceRpcClByteOrder(cl_hdr));
    DCE2_CopyUuid(&at->act, &cl_hdr->act_id, DceRpcClByteOrder(cl_hdr));

    status = DCE2_ListInsert(clt->act_trackers, (void *)uuid, (void *)at);
    if (status != DCE2_RET__SUCCESS)
    {
        DCE2_Free((void *)uuid, sizeof(Uuid), DCE2_MEM_TYPE__CL_ACT);
        DCE2_Free((void *)at, sizeof(DCE2_ClActTracker), DCE2_MEM_TYPE__CL_ACT);
        return NULL;
    }

    return at;
}
Exemple #2
0
/********************************************************************
 * Function:
 *
 * Purpose:
 *
 * Arguments:
 *
 * Returns:
 *
 ********************************************************************/
void DCE2_BufferDestroy(DCE2_Buffer *buf)
{
    if (buf == NULL)
        return;

    if (buf->data != NULL)
        DCE2_Free((void *)buf->data, buf->size, buf->mtype);

    DCE2_Free((void *)buf, sizeof(DCE2_Buffer), buf->mtype);
}
Exemple #3
0
/********************************************************************
 * Function: DCE2_ClFragDataFree()
 *
 * Callback to fragment list for freeing data kept in list.  Need
 * to free the frag node and the data attached to it.
 *
 * Arguments:
 *  void *
 *      Pointer to fragment data (a frag node).
 *
 * Returns: None
 *
 ********************************************************************/
static void DCE2_ClFragDataFree(void *data)
{
    DCE2_ClFragNode *fn = (DCE2_ClFragNode *)data;

    if (fn == NULL)
        return;

    if (fn->frag_data != NULL)
        DCE2_Free((void *)fn->frag_data, fn->frag_len, DCE2_MEM_TYPE__CL_FRAG);

    DCE2_Free((void *)fn, sizeof(DCE2_ClFragNode), DCE2_MEM_TYPE__CL_FRAG);
}
Exemple #4
0
/********************************************************************
 * Function:
 *
 * Purpose:
 *
 * Arguments:
 *
 * Returns:
 *
 ********************************************************************/
void * DCE2_ReAlloc(void *old_mem, uint32_t old_size, uint32_t new_size, DCE2_MemType mtype)
{
    void *new_mem;
    DCE2_Ret status;

    if (dce2_mem_state == DCE2_MEM_STATE__MEMCAP)
        return NULL;

    if (old_mem == NULL)
    {
        DCE2_Log(DCE2_LOG_TYPE__ERROR,
                 "%s(%d) Old memory passed in was NULL.",
                 __FILE__, __LINE__);
        return NULL;
    }
    else if (new_size < old_size)
    {
        DCE2_Log(DCE2_LOG_TYPE__ERROR,
                 "%s(%d) New size is less than old size.",
                 __FILE__, __LINE__);
        return NULL;
    }
    else if (new_size == old_size)
    {
        return old_mem;
    }

    if (DCE2_CheckMemcap(new_size - old_size, mtype) == DCE2_MEMCAP_EXCEEDED)
        return NULL;

    new_mem = DCE2_Alloc(new_size, mtype);
    if (new_mem == NULL)
        return NULL;

    status = DCE2_Memcpy(new_mem, old_mem, old_size,
                         new_mem, (void *)((uint8_t *)new_mem + new_size));

    if (status != DCE2_RET__SUCCESS)
    {
        DCE2_Log(DCE2_LOG_TYPE__ERROR,
                 "%s(%d) Failed to copy old memory into new memory.",
                 __FILE__, __LINE__);
        DCE2_Free(new_mem, new_size, mtype);
        return NULL;
    }

    DCE2_Free(old_mem, old_size, mtype);

    return new_mem;
}
Exemple #5
0
/********************************************************************
 * Function: DCE2_ClActKeyFree()
 *
 * Callback to activity tracker list for freeing the key (this is
 * the activity UUID).  Since key is dynamically allocated, we need
 * to free it.
 *
 * Arguments:
 *  void *
 *      The activity UUID to free.
 *
 * Returns: None
 *
 ********************************************************************/
static void DCE2_ClActKeyFree(void *key)
{
    if (key == NULL)
        return;

    DCE2_Free(key, sizeof(Uuid), DCE2_MEM_TYPE__CL_ACT);
}
Exemple #6
0
/********************************************************************
 * Function:
 *
 * Purpose:
 *
 * Arguments:
 *
 * Returns:
 *
 ********************************************************************/
DCE2_Buffer * DCE2_BufferNew(uint32_t initial_size, uint32_t min_add_size, DCE2_MemType mem_type)
{
    DCE2_Buffer *buf = (DCE2_Buffer *)DCE2_Alloc(sizeof(DCE2_Buffer), mem_type);

    if (buf == NULL)
        return NULL;

    if (initial_size != 0)
    {
        buf->data = (uint8_t *)DCE2_Alloc(initial_size, mem_type);
        if (buf->data == NULL)
        {
            DCE2_Free((void *)buf, sizeof(DCE2_Buffer), mem_type);
            return NULL;
        }
    }

    buf->size = initial_size;
    buf->len = 0;
    buf->mtype = mem_type;
    buf->min_add_size = min_add_size;
    buf->offset = 0;

    return buf;
}
Exemple #7
0
/********************************************************************
 * Function: DCE2_HttpSsnFree()
 *
 * Frees the session data structure and any dynamically allocated
 * data within it.
 *
 * Arguments:
 *  void *
 *      Pointer to an RPC over HTTP session data structure.
 *
 * Returns: None
 *
 ********************************************************************/
void DCE2_HttpSsnFree(void *ssn)
{
    DCE2_HttpSsnData *hsd = (DCE2_HttpSsnData *)ssn;

    if (hsd == NULL)
        return;

    DCE2_HttpDataFree(hsd);
    DCE2_Free((void *)hsd, sizeof(DCE2_HttpSsnData), DCE2_MEM_TYPE__HTTP_SSN);
}
Exemple #8
0
/********************************************************************
 * Function: DCE2_UdpSsnFree()
 *
 * Purpose: Callback to session for freeing sessiond data.
 *
 * Arguments:
 *  void * - pointer to the memory to be freed.
 *
 * Returns: None
 *
 ********************************************************************/
void DCE2_UdpSsnFree(void *data)
{
    DCE2_UdpSsnData *usd = (DCE2_UdpSsnData *)data;

    if (usd == NULL)
        return;

    DCE2_UdpDataFree(usd);
    DCE2_Free((void *)usd, sizeof(DCE2_UdpSsnData), DCE2_MEM_TYPE__UDP_SSN);
}
Exemple #9
0
/********************************************************************
 * Function:
 *
 * Purpose:
 *
 * Arguments:
 *
 * Returns:
 *
 ********************************************************************/
void DCE2_StatsFree(void)
{
    if (dce2_trans_strs != NULL)
    {
        unsigned int i;

        for (i = DCE2_TRANS_TYPE__NONE; i < DCE2_TRANS_TYPE__MAX; i++)
        {
            if (dce2_trans_strs[i] != NULL)
            {
                DCE2_Free((void *)dce2_trans_strs[i],
                          strlen(dce2_trans_strs[i]) + 1, DCE2_MEM_TYPE__INIT);
            }
        }

        DCE2_Free((void *)dce2_trans_strs, (DCE2_TRANS_TYPE__MAX * sizeof(char *)), DCE2_MEM_TYPE__INIT);

        dce2_trans_strs = NULL;
    }
}
Exemple #10
0
/********************************************************************
 * Function: DCE2_ClActDataFree()
 *
 * Callback to activity tracker list for freeing activity trackers.
 *
 * Arguments:
 *  void *
 *      Activity tracker to free.
 *
 * Returns: None
 *
 ********************************************************************/
static void DCE2_ClActDataFree(void *data)
{
    DCE2_ClActTracker *at = (DCE2_ClActTracker *)data;

    if (at == NULL)
        return;

    DCE2_ListDestroy(at->frag_tracker.frags);
    at->frag_tracker.frags = NULL;
    DCE2_Free((void *)at, sizeof(DCE2_ClActTracker), DCE2_MEM_TYPE__CL_ACT);
}
/******************************************************************
 * Function: DCE2_EventsFree()
 *
 * Frees any global data that was dynamically allocated.
 *
 * Arguments: None
 *
 * Returns: None
 *
 ******************************************************************/
void DCE2_EventsFree(void)
{
    unsigned int i;

    for (i = 0; i < DCE2_EVENT__MAX; i++)
    {
        if (dce2_events[i].format != NULL)
        {
            DCE2_Free((void *)dce2_events[i].format, strlen(dce2_events[i].format) + 1, DCE2_MEM_TYPE__INIT);
            dce2_events[i].format = NULL;
        }
    }

    for (i = 0; i < (sizeof(dce2_pdu_types) / sizeof(char *)); i++)
    {
        if (dce2_pdu_types[i] != NULL)
        {
            DCE2_Free((void *)dce2_pdu_types[i], strlen(dce2_pdu_types[i]) + 1, DCE2_MEM_TYPE__INIT);
            dce2_pdu_types[i] = NULL;
        }
    }
}
Exemple #12
0
/********************************************************************
 * Function: DCE2_ClHandleFrag()
 *
 * Handles connectionless fragments.  Creates a new fragment list
 * if necessary and inserts fragment into list.  Sets rule option
 * values based on the fragment.
 *
 * Arguments:
 *  DCE2_SsnData *
 *      Pointer to the session data structure.
 *  DCE2_ClActTracker *
 *      Pointer to the connectionless activity tracker.
 *  DceRpcClHdr *
 *      Pointer to the connectionless header in the packet.
 *  const uint8_t *
 *      Pointer to current position in the packet payload.
 *  uint16_t
 *      Length of packet payload left from current pointer
 *      position.
 *
 * Returns: None
 *
 ********************************************************************/
static void DCE2_ClHandleFrag(DCE2_SsnData *sd, DCE2_ClActTracker *at, DceRpcClHdr *cl_hdr,
                              const uint8_t *data_ptr, uint16_t data_len)
{
    DCE2_ClFragTracker *ft = &at->frag_tracker;
    DCE2_ClFragNode *fn;
    uint16_t frag_len;
    int status;
    PROFILE_VARS;

    PREPROC_PROFILE_START(dce2_pstat_cl_frag);

    /* If the frag length is less than data length there might be authentication
     * data that we don't want to include, otherwise just set to data len */
    if (DceRpcClLen(cl_hdr) < data_len)
        frag_len = DceRpcClLen(cl_hdr);
    else
        frag_len = data_len;

    if (frag_len == 0)
    {
        PREPROC_PROFILE_END(dce2_pstat_cl_frag);
        return;
    }

    if (frag_len > dce2_stats.cl_max_frag_size)
        dce2_stats.cl_max_frag_size = frag_len;

    if (DCE2_GcMaxFrag() && (frag_len > DCE2_GcMaxFragLen()))
        frag_len = DCE2_GcMaxFragLen();

    if (ft->frags == NULL)
    {
        /* Create new list if we don't have one already */
        ft->frags = DCE2_ListNew(DCE2_LIST_TYPE__SORTED, DCE2_ClFragCompare, DCE2_ClFragDataFree,
                                 NULL, DCE2_LIST_FLAG__NO_DUPS | DCE2_LIST_FLAG__INS_TAIL,
                                 DCE2_MEM_TYPE__CL_FRAG);

        if (ft->frags == NULL)
        {
            PREPROC_PROFILE_END(dce2_pstat_cl_frag);
            return;
        }
    }
    else
    {
        /* If we already have a fragment in the list with the same fragment number,
         * that fragment will take precedence over this fragment and this fragment
         * will not be used by the server */
        fn = (DCE2_ClFragNode *)DCE2_ListFind(ft->frags, (void *)(uintptr_t)DceRpcClFragNum(cl_hdr));
        if (fn != NULL)
        {
            PREPROC_PROFILE_END(dce2_pstat_cl_frag);
            return;
        }
    }

    /* Create a new frag node to insert into the list */
    fn = (DCE2_ClFragNode *)DCE2_Alloc(sizeof(DCE2_ClFragNode), DCE2_MEM_TYPE__CL_FRAG);
    if (fn == NULL)
    {
        PREPROC_PROFILE_END(dce2_pstat_cl_frag);

        DCE2_ClFragReassemble(sd, at, cl_hdr);
        return;
    }

    fn->frag_number = DceRpcClFragNum(cl_hdr);
    fn->frag_len = frag_len;

    /* Allocate space for the fragment data */
    fn->frag_data = (uint8_t *)DCE2_Alloc(frag_len, DCE2_MEM_TYPE__CL_FRAG);
    if (fn->frag_data == NULL)
    {
        DCE2_Free((void *)fn, sizeof(DCE2_ClFragNode), DCE2_MEM_TYPE__CL_FRAG);

        PREPROC_PROFILE_END(dce2_pstat_cl_frag);

        DCE2_ClFragReassemble(sd, at, cl_hdr);
        return;
    }

    /* Copy the fragment data in the packet to the space just allocated */
    status = DCE2_Memcpy(fn->frag_data, data_ptr, frag_len, fn->frag_data, fn->frag_data + frag_len);
    if (status != DCE2_RET__SUCCESS)
    {
        DCE2_Free((void *)fn->frag_data, frag_len, DCE2_MEM_TYPE__CL_FRAG);
        DCE2_Free((void *)fn, sizeof(DCE2_ClFragNode), DCE2_MEM_TYPE__CL_FRAG);

        PREPROC_PROFILE_END(dce2_pstat_cl_frag);

        DCE2_ClFragReassemble(sd, at, cl_hdr);
        return;
    }

    if (DCE2_ListIsEmpty(ft->frags))
    {
        /* If this is the first fragment we've received, set interface uuid */
        DCE2_CopyUuid(&ft->iface, DceRpcClIface(cl_hdr), DceRpcClByteOrder(cl_hdr));
        ft->iface_vers = DceRpcClIfaceVers(cl_hdr);
    }

    if (DceRpcClLastFrag(cl_hdr))
    {
        /* Set number of expected frags on last frag */
        ft->num_expected_frags = DceRpcClFragNum(cl_hdr) + 1;
    }
    else if (DceRpcClFirstFrag(cl_hdr))
    {
        /* Set opum and byte order on first frag */
        ft->opnum = DceRpcClOpnum(cl_hdr);
        ft->data_byte_order = DceRpcClByteOrder(cl_hdr);
    }

    /* Insert frag node into the list */
    status = DCE2_ListInsert(ft->frags, (void *)(uintptr_t)fn->frag_number, (void *)fn);
    if (status != DCE2_RET__SUCCESS)
    {
        DCE2_Free((void *)fn->frag_data, frag_len, DCE2_MEM_TYPE__CL_FRAG);
        DCE2_Free((void *)fn, sizeof(DCE2_ClFragNode), DCE2_MEM_TYPE__CL_FRAG);

        PREPROC_PROFILE_END(dce2_pstat_cl_frag);

        DCE2_ClFragReassemble(sd, at, cl_hdr);
        return;
    }

    /* Fragment number field in header is uint16_t */
    if ((ft->num_expected_frags != DCE2_SENTINEL) &&
        (uint16_t)ft->frags->num_nodes == (uint16_t)ft->num_expected_frags)
    {
        PREPROC_PROFILE_END(dce2_pstat_cl_frag);

        /* We got all of the frags - reassemble */
        DCE2_ClFragReassemble(sd, at, cl_hdr);
        at->seq_num_invalid = 1;

        return;
    }

    PREPROC_PROFILE_END(dce2_pstat_cl_frag);

    /* Cache relevant values for rule option processing */
    sd->ropts.first_frag = DceRpcClFirstFrag(cl_hdr);
    DCE2_CopyUuid(&sd->ropts.iface, &ft->iface, DCERPC_BO_FLAG__NONE);
    sd->ropts.iface_vers = ft->iface_vers;
    sd->ropts.hdr_byte_order = DceRpcClByteOrder(cl_hdr);

    if (ft->data_byte_order != DCE2_SENTINEL)
        sd->ropts.data_byte_order = ft->data_byte_order;
    else
        sd->ropts.data_byte_order = DceRpcClByteOrder(cl_hdr);

    if (ft->opnum != DCE2_SENTINEL)
        sd->ropts.opnum = ft->opnum;
    else
        sd->ropts.opnum = DceRpcClOpnum(cl_hdr);

    sd->ropts.stub_data = (uint8_t *)cl_hdr + sizeof(DceRpcClHdr);

    DCE2_Detect(sd);
}
Exemple #13
0
/********************************************************************
 * Function:
 *
 * Must have allocated data in buffer and data_len must fit in
 * buffer.
 *
 * Arguments:
 *
 * Returns:
 *
 ********************************************************************/
DCE2_Ret DCE2_BufferMoveData(DCE2_Buffer *buf, uint32_t data_offset,
                             const uint8_t *move, uint32_t move_len)
{
    DCE2_Ret status;
    uint8_t *offset, *end;

    if ((buf == NULL) || (buf->data == NULL) || (move == NULL))
        return DCE2_RET__ERROR;

    /* Return success for this since ultimately nothing _was_ moved */
    if (move_len == 0)
        return DCE2_RET__SUCCESS;

    offset = buf->data + data_offset;
    end = buf->data + buf->len;

    /* Moved data must be within current data */
    if ((move < buf->data) || ((move + move_len) > end))
        return DCE2_RET__ERROR;

    /* No move required */
    if (move == offset)
        return DCE2_RET__SUCCESS;

    /* Would have to do two moves.  One for the data and one to realign data
     * with start of moved data.  Don't want to succeed on the first and fail
     * on the second and leave the buffer in a bad state.  Don't want to use
     * an offset in data buffer because want to keep the size the same. */
    if (move == buf->data)
    {
        uint32_t tmp_size = buf->len;
        uint8_t *tmp = (uint8_t *)DCE2_Alloc(tmp_size, buf->mtype);
        uint8_t *tmp_offset, *tmp_end;
        uint32_t new_len;

        if (tmp == NULL)
            return DCE2_RET__ERROR;

        tmp_offset = tmp + data_offset;
        tmp_end = tmp + tmp_size;

        status = DCE2_Memcpy(tmp, buf->data, buf->len, tmp, tmp_end);
        if (status != DCE2_RET__SUCCESS)
        {
            DCE2_Free((void *)tmp, tmp_size, buf->mtype);
            DCE2_Log(DCE2_LOG_TYPE__ERROR,
                     "%s(%d) Failed to move data in buffer.", __FILE__, __LINE__);
            return DCE2_RET__ERROR;
        }

        status = DCE2_Memmove(tmp_offset, tmp, move_len, tmp_offset, tmp_end);
        if (status != DCE2_RET__SUCCESS)
        {
            DCE2_Free((void *)tmp, tmp_size, buf->mtype);
            DCE2_Log(DCE2_LOG_TYPE__ERROR,
                     "%s(%d) Failed to move data in buffer.", __FILE__, __LINE__);
            return DCE2_RET__ERROR;
        }

        if (tmp_offset > (tmp + move_len))
            tmp_offset = tmp + move_len;

        new_len = tmp_end - tmp_offset;

        status = DCE2_Memcpy(buf->data, tmp_offset, new_len, buf->data, end);
        if (status != DCE2_RET__SUCCESS)
        {
            DCE2_Free((void *)tmp, tmp_size, buf->mtype);
            DCE2_Log(DCE2_LOG_TYPE__ERROR,
                     "%s(%d) Failed to move data in buffer.", __FILE__, __LINE__);
            return DCE2_RET__ERROR;
        }

        buf->len = new_len;

        DCE2_Free((void *)tmp, tmp_size, buf->mtype);
    }
    else
    {
        status = DCE2_Memmove(offset, move, move_len, offset, end);
        if (status != DCE2_RET__SUCCESS)
        {
            DCE2_Log(DCE2_LOG_TYPE__ERROR,
                     "%s(%d) Failed to move data in buffer", __FILE__, __LINE__);
            return DCE2_RET__ERROR;
        }

        /* If we have a new end of data, adjust length */
        if ((move + move_len) == end)
            buf->len = data_offset + move_len;
    }

    return DCE2_RET__SUCCESS;
}