⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snort_smtp.c

📁 著名的入侵检测系统snort的最新版本的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    p->normalized_payload_size = 0;    p->flags &= ~FLAG_ALT_DECODE;    if ((p->stream_session_ptr == NULL) || (_smtp_config.inspection_type == SMTP_STATELESS))    {        SMTP_NoSessionFree();        memset(&_smtp_no_session, 0, sizeof(SMTP));        _smtp = &_smtp_no_session;        return;    }    _smtp = _dpd.streamAPI->get_application_data(p->stream_session_ptr, PP_SMTP);    if (_smtp == NULL)    {        _smtp = (SMTP *)calloc(1, sizeof(SMTP));        if (_smtp == NULL)        {            DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate SMTP session data\n");        }        else        {                  _dpd.streamAPI->set_application_data(p->stream_session_ptr, PP_SMTP,                                                 _smtp, &SMTP_SessionFree);           }    }}/* * Determine packet direction * * @param   p   standard Packet structure * * @return  none */static int SMTP_GetPacketDirection(SFSnortPacket *p, char reset_if_midstream){        int flags = 0;    int pkt_direction = SMTP_PKT_FROM_UNKNOWN;    if (p->stream_session_ptr != NULL)    {        flags = _dpd.streamAPI->get_session_flags(p->stream_session_ptr);    }    if (flags & SSNFLAG_MIDSTREAM)    {        /* We can't be sure what state we are in, in this case. */        if ((_smtp_config.inspection_type == SMTP_STATEFUL) && reset_if_midstream)            SMTP_ResetState();        /* Note that source port and destination port can both be 25         * TODO Maybe new function that dynamically determines whether client         * or server based on data */        if (SMTP_IsServer(p->src_port) && SMTP_IsServer(p->dst_port))        {            pkt_direction = SMTP_PKT_FROM_UNKNOWN;        }        else if (SMTP_IsServer(p->src_port))        {            pkt_direction = SMTP_PKT_FROM_SERVER;        }        else if (SMTP_IsServer(p->dst_port))        {            pkt_direction = SMTP_PKT_FROM_CLIENT;        }        else        {            pkt_direction = SMTP_PKT_FROM_UNKNOWN;        }    }    else if (p->flags & FLAG_FROM_SERVER)    {        pkt_direction = SMTP_PKT_FROM_SERVER;    }    else if (p->flags & FLAG_FROM_CLIENT)    {        pkt_direction = SMTP_PKT_FROM_CLIENT;    }    else    {        pkt_direction = SMTP_PKT_FROM_UNKNOWN;    }    return pkt_direction;}/* * Free SMTP-specific related to this session * * @param   v   pointer to SMTP session structure * * @return  none */static void SMTP_SessionFree(void *session_data){    SMTP *smtp = (SMTP *)session_data;    if (smtp != NULL)    {        if (smtp->mime_boundary.boundary_search != NULL)        {            _dpd.searchAPI->search_instance_free(smtp->mime_boundary.boundary_search);            smtp->mime_boundary.boundary_search = NULL;        }        free(smtp);    }}static void SMTP_NoSessionFree(void){    if (_smtp_no_session.mime_boundary.boundary_search != NULL)    {        _dpd.searchAPI->search_instance_free(_smtp_no_session.mime_boundary.boundary_search);        _smtp_no_session.mime_boundary.boundary_search = NULL;    }}/* * Free anything that needs it before shutting down preprocessor * * @param   none * * @return  none */void SMTP_Free(void){    SMTPToken *tmp;    _dpd.searchAPI->search_free();    SMTP_NoSessionFree();    for (tmp = _smtp_cmds; tmp->name != NULL; tmp++)    {        free(tmp->name);    }    if (_smtp_cmds != NULL)        free(_smtp_cmds);    if (_smtp_cmd_search != NULL)        free(_smtp_cmd_search);    if (_smtp_cmd_config != NULL)        free(_smtp_cmd_config);    if (_mime_boundary_pcre.re )        pcre_free(_mime_boundary_pcre.re);    if (_mime_boundary_pcre.pe )        pcre_free(_mime_boundary_pcre.pe);}/* * Callback function for string search * * @param   id      id in array of search strings from _smtp_config.cmds * @param   index   index in array of search strings from _smtp_config.cmds * @param   data    buffer passed in to search function * * @return response * @retval 1        commands caller to stop searching */static int SMTP_SearchStrFound(void *id, int index, void *data){    int search_id = (int)(uintptr_t)id;    _smtp_search_info.id = search_id;    _smtp_search_info.index = index;    _smtp_search_info.length = _smtp_current_search[search_id].name_len;    /* Returning non-zero stops search, which is okay since we only look for one at a time */    return 1;}/* * Callback function for boundary search * * @param   id      id in array of search strings * @param   index   index in array of search strings * @param   data    buffer passed in to search function * * @return response * @retval 1        commands caller to stop searching */static int SMTP_BoundaryStrFound(void *id, int index, void *data){    int boundary_id = (int)(uintptr_t)id;    _smtp_search_info.id = boundary_id;    _smtp_search_info.index = index;    _smtp_search_info.length = _smtp->mime_boundary.boundary_len;    return 1;}static int SMTP_GetBoundary(const char *data, int data_len){    int result;    int ovector[9];    int ovecsize = 9;    const char *boundary;    int boundary_len;    int ret;    char *mime_boundary;    int  *mime_boundary_len;    mime_boundary = &_smtp->mime_boundary.boundary[0];    mime_boundary_len = &_smtp->mime_boundary.boundary_len;        /* result will be the number of matches (including submatches) */    result = pcre_exec(_mime_boundary_pcre.re, _mime_boundary_pcre.pe,                       data, data_len, 0, 0, ovector, ovecsize);    if (result < 0)        return -1;    result = pcre_get_substring(data, ovector, result, 1, &boundary);    if (result < 0)        return -1;    boundary_len = strlen(boundary);    if (boundary_len > MAX_BOUNDARY_LEN)    {        /* XXX should we alert? breaking the law of RFC */        boundary_len = MAX_BOUNDARY_LEN;    }    mime_boundary[0] = '-';    mime_boundary[1] = '-';    ret = SafeMemcpy(mime_boundary + 2, boundary, boundary_len,                     mime_boundary + 2, mime_boundary + 2 + MAX_BOUNDARY_LEN);    pcre_free_substring(boundary);    if (ret != SAFEMEM_SUCCESS)    {        return -1;    }    *mime_boundary_len = 2 + boundary_len;    mime_boundary[*mime_boundary_len] = '\0';    return 0;}/* * Handle COMMAND state * * @param   p       standard Packet structure * @param   ptr     pointer into p->payload buffer to start looking at data * @param   end     points to end of p->payload buffer * * @return          pointer into p->payload where we stopped looking at data *                  will be end of line or end of packet */static const u_int8_t * SMTP_HandleCommand(SFSnortPacket *p, const u_int8_t *ptr, const u_int8_t *end){    const u_int8_t *eol;   /* end of line */    const u_int8_t *eolm;  /* end of line marker */    int cmd_line_len;    int ret;    int cmd_found;    char alert_long_command_line = 0;    /* get end of line and end of line marker */    SMTP_GetEOL(ptr, end, &eol, &eolm);    /* calculate length of command line */    cmd_line_len = eol - ptr;    /* check for command line exceeding maximum      * do this before checking for a command since this could overflow     * some server's buffers without the presence of a known command */    if ((_smtp_config.max_command_line_len != 0) &&        (cmd_line_len > _smtp_config.max_command_line_len))    {        alert_long_command_line = 1;    }    /* TODO If the end of line marker coincides with the end of payload we can't be     * sure that we got a command and not a substring which we could tell through     * inpsection of the next packet. Maybe a command pending state where the first     * char in the next packet is checked for a space and end of line marker */    /* do not confine since there could be space chars before command */    _smtp_current_search = &_smtp_cmd_search[0];    cmd_found = _dpd.searchAPI->search_find(SEARCH_CMD, (const char *)ptr, eolm - ptr,                                            0, SMTP_SearchStrFound);    /* see if we actually found a command and not a substring */    if (cmd_found > 0)    {        const u_int8_t *tmp = ptr;        const u_int8_t *cmd_start = ptr + _smtp_search_info.index;        const u_int8_t *cmd_end = cmd_start + _smtp_search_info.length;        /* move past spaces up until start of command */        while ((tmp < cmd_start) && isspace((int)*tmp))            tmp++;        /* if not all spaces before command, we found a          * substring */        if (tmp != cmd_start)            cmd_found = 0;                /* if we're before the end of line marker and the next         * character is not whitespace, we found a substring */        if ((cmd_end < eolm) && !isspace((int)*cmd_end))            cmd_found = 0;        /* there is a chance that end of command coincides with the end of payload         * in which case, it could be a substring, but for now, we will treat it as found */    }    /* if command not found, alert and move on */    if (!cmd_found)    {        DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "No known command found\n"););        if (_smtp_config.alert_unknown_cmds)        {            SMTP_GenerateAlert(SMTP_UNKNOWN_CMD, "%s", SMTP_UNKNOWN_CMD_STR);        }        if (alert_long_command_line)        {            SMTP_GenerateAlert(SMTP_COMMAND_OVERFLOW, "%s: more than %d chars",                               SMTP_COMMAND_OVERFLOW_STR, _smtp_config.max_command_line_len);        }        /* if normalizing, copy line to alt buffer */        if (_smtp_normalizing)        {            ret = SMTP_CopyToAltBuffer(p, ptr, eol - ptr);            if (ret == -1)                return NULL;        }        return eol;    }    /* At this point we have definitely found a legitimate command */    DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "%s\n", _smtp_cmds[_smtp_search_info.id].name););    /* check if max command line length for a specific command is exceeded */    if (_smtp_cmd_config[_smtp_search_info.id].max_line_len != 0)    {        if (cmd_line_len > _smtp_cmd_config[_smtp_search_info.id].max_line_len)        {            SMTP_GenerateAlert(SMTP_SPECIFIC_CMD_OVERFLOW, "%s: %s, %d chars",                               SMTP_SPECIFIC_CMD_OVERFLOW_STR,                               _smtp_cmd_search[_smtp_search_info.id].name, cmd_line_len);        }    }    else if (alert_long_command_line)    {        SMTP_GenerateAlert(SMTP_COMMAND_OVERFLOW, "%s: more than %d chars",                           SMTP_COMMAND_OVERFLOW_STR, _smtp_config.max_command_line_len);    }    /* Are we alerting on this command? */    if (_smtp_cmd_config[_smtp_search_info.id].alert)    {        SMTP_GenerateAlert(SMTP_ILLEGAL_CMD, "%s: %s",                           SMTP_ILLEGAL_CMD_STR, _smtp_cmds[_smtp_search_info.id].name);    }    switch (_smtp_search_info.id)    {        /* unless we do our own parsing of MAIL and RCTP commands we have to assume they         * are ok unless we got a server error in which case we flush and if this is a         * reassembled packet, the last command in this packet will be the command that         * caused the error */        case CMD_MAIL:            _smtp->state_flags |= SMTP_FLAG_GOT_MAIL_CMD;            break;        case CMD_RCPT:            if (_smtp->state_flags & SMTP_FLAG_GOT_MAIL_CMD)            {                _smtp->state_flags |= SMTP_FLAG_GOT_RCPT_CMD;            }            break;        case CMD_RSET:        case CMD_HELO:        case CMD_EHLO:        case CMD_QUIT:            _smtp->state_flags &= ~(SMTP_FLAG_GOT_MAIL_CMD | SMTP_FLAG_GOT_RCPT_CMD);            break;#if 0        case CMD_BDAT:            {                const u_int8_t *begin_chunk;                const u_int8_t *end_chunk;                const u_int8_t *last;                const u_int8_t *tmp;                int num_digits;                int ten_power;                u_int32_t bdat_chunk;                begin_chunk = ptr + _smtp_search_info.index + _smtp_search_info.length;                while ((begin_chunk < eolm) && isspace((int)*begin_chunk))                    begin_chunk++;                /* bad BDAT command - needs chunk argument */                if (begin_chunk == eolm)                    break;                                    end_chunk = begin_chunk;                while ((end_chunk < eolm) && isdigit((int)*end_chunk))                    end_chunk++;                /* didn't get all digits */                if ((end_chunk < eolm) && !isspace((int)*end_chunk))                    break;                /* get chunk size */                num_digits = end_chunk - begin_chunk;                /* more than 9 digits could potentially overflow a 32 bit integer                 * this allows for one less than a billion bytes which most servers                 * won't accept */                if (num_digits > 9)                    break;                tmp = end_chunk;                for (ten_power = 1, tmp--; tmp >= begin_chunk; ten_power *= 10, tmp--)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -