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

📄 snort_smtp.c

📁 著名的入侵检测系统snort的最新版本的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
                {                    bdat_chunk += (*tmp - '0') * ten_power;                }                /* bad bdat chunk size */                if (bdat_chunk == 0)                    break;                /* got a valid chunk size - check to see if this is the last chunk */                last = end_chunk;                while ((last < eolm) && isspace((int)*last))                    last++;                /* TODO need an ESMTP argument search */                if (last < eolm)                {                    /* must have at least 4 chars for 'last' */                    if ((eolm - last) >= 4)                    {                        if (*last == 'l' || *last == 'L')                        {                            last++;                            if (*last == 'a' || *last == 'A')                            {                                last++;                                if (*last == 's' || *last == 'S')                                {                                    last++;                                    if (*last == 't' || *last == 'T')                                    {                                        last++;                                        while ((last < eolm) && isspace((int)*last))                                            last++;                                        if (last != eolm)                                        {                                            break;                                        }                                                                                _smtp->bdat_last = 1;                                    }                                }                            }                        }                    }                }                _smtp->state = STATE_BDAT;                _smtp->bdat_chunk = bdat_chunk;            }            break;#endif        case CMD_DATA:            if (_smtp->state_flags & SMTP_FLAG_GOT_DATA_RESP)            {                DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Already got 354 data ready response - set "                                                    "to data state.\n"););                _smtp->state = STATE_DATA;                _smtp->state_flags &= ~(SMTP_FLAG_GOT_DATA_RESP | SMTP_FLAG_GOT_DATA_CMD);            }            else if (!(_smtp->state_flags & SMTP_FLAG_GOT_RCPT_CMD))            {                /* if this flag is set, then this is a reassembled packet with the last                  * command being the one that caused the error.  In this case it was the                 * DATA command that caused the error, so we shouldn't accept it and stay                 * in the command state */                 DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Didn't get MAIL -> RCPT command sequence or "                                                     "got server error on DATA command - "                                                     "stay in command state.\n"););            }            else            {                /* Since we're not keeping a more granular state (such as mail state, rcpt state)                 * we have no way of knowing whether the data command will be accepted.  Now, we                 * assume that it will be, but if the next server response is not 354 we will                 * revert back to command state */                 DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Got DATA command but no server response yet "                                                     "set to data response pending state.\n"););                _smtp->state = STATE_DATA_PEND;                _smtp->state_flags |= SMTP_FLAG_GOT_DATA_CMD;            }                 break;        case CMD_STARTTLS:            /* if reassembled we flush after seeing a 220 so this should be the last             * command in reassembled packet and if not reassembled it should be the             * last line in the packet as you can't pipeline the tls hello */            if (eol == end)            {                _smtp->state = STATE_TLS_CLIENT_PEND;            }            break;                case CMD_X_LINK2STATE:             if (_smtp_config.alert_xlink2state)            {                ParseXLink2State(p, ptr + _smtp_search_info.index);            }            break;                    default:            break;    }    /* normalize command line */    if (_smtp_config.normalize == NORMALIZE_ALL ||        _smtp_cmd_config[_smtp_search_info.id].normalize)    {        ret = SMTP_NormalizeCmd(p, ptr, eolm, eol);        if (ret == -1)            return NULL;    }                            else if (_smtp_normalizing) /* Already normalizing */    {        ret = SMTP_CopyToAltBuffer(p, ptr, eol - ptr);        if (ret == -1)            return NULL;    }    return eol;}static const u_int8_t * SMTP_HandleData(SFSnortPacket *p, const u_int8_t *ptr, const u_int8_t *end){    const u_int8_t *data_end_marker = NULL;    const u_int8_t *data_end = NULL;    int data_end_found;    int ret;    /* if we've just entered the data state, check for a dot + end of line     * if found, no data */    if (_smtp->data_state == STATE_DATA_INIT)    {        if ((ptr < end) && (*ptr == '.'))        {            const u_int8_t *eol = NULL;            const u_int8_t *eolm = NULL;            SMTP_GetEOL(ptr, end, &eol, &eolm);            /* this means we got a real end of line and not just end of payload              * and that the dot is only char on line */            if ((eolm != end) && (eolm == (ptr + 1)))            {                /* if we're normalizing and not ignoring data copy data end marker                 * and dot to alt buffer */                if (!_smtp_config.ignore_data && _smtp_normalizing)                {                    ret = SMTP_CopyToAltBuffer(p, ptr, eol - ptr);                    if (ret == -1)                        return NULL;                }                SMTP_ResetState();                return eol;            }        }        _smtp->data_state = STATE_DATA_HEADER;        /* XXX A line starting with a '.' that isn't followed by a '.' is         * deleted (RFC 821 - 4.5.2.  TRANSPARENCY).  If data starts with         * '. text', i.e a dot followed by white space then text, some         * servers consider it data header and some data body.         * Postfix and Qmail will consider the start of data:         * . text\r\n         * .  text\r\n         * to be part of the header and the effect will be that of a          * folded line with the '.' deleted.  Exchange will put the same         * in the body which seems more reasonable. */    }    /* get end of data body     * TODO check last bytes of previous packet to see if we had a partial     * end of data */    _smtp_current_search = &_smtp_data_end_search[0];    data_end_found = _dpd.searchAPI->search_find(SEARCH_DATA_END, (const char *)ptr,                                                 end - ptr, 0, SMTP_SearchStrFound);    if (data_end_found > 0)    {        data_end_marker = ptr + _smtp_search_info.index;        data_end = data_end_marker + _smtp_search_info.length;    }    else    {        data_end_marker = data_end = end;    }    if (_smtp->data_state == STATE_DATA_HEADER)    {        DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "DATA HEADER STATE ~~~~~~~~~~~~~~~~~~~~~~\n"););        ptr = SMTP_HandleHeader(p, ptr, data_end_marker);        if (ptr == NULL)            return NULL;    }    /* if we're ignoring data and not already normalizing, copy everything     * up to here into alt buffer so detection engine doesn't have     * to look at the data; otherwise, if we're normalizing and not     * ignoring data, copy all of the data into the alt buffer */    if (_smtp_config.ignore_data && !_smtp_normalizing)    {        ret = SMTP_CopyToAltBuffer(p, p->payload, ptr - p->payload);        if (ret == -1)            return NULL;    }    else if (!_smtp_config.ignore_data && _smtp_normalizing)    {        ret = SMTP_CopyToAltBuffer(p, ptr, data_end - ptr);        if (ret == -1)            return NULL;    }    /* now we shouldn't have to worry about copying any data to the alt buffer     * only mime headers if we find them and only if we're ignoring data */    while ((ptr != NULL) && (ptr < data_end_marker))    {        switch (_smtp->data_state)        {            case STATE_MIME_HEADER:                DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "MIME HEADER STATE ~~~~~~~~~~~~~~~~~~~~~~\n"););                ptr = SMTP_HandleHeader(p, ptr, data_end_marker);                break;            case STATE_DATA_BODY:                DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "DATA BODY STATE ~~~~~~~~~~~~~~~~~~~~~~~~\n"););                ptr = SMTP_HandleDataBody(p, ptr, data_end_marker);                break;        }    }    /* if we got the data end reset state, otherwise we're probably still in the data     * to expect more data in next packet */    if (data_end_marker != end)    {        SMTP_ResetState();    }    return data_end;}/* * Handle Headers - Data or Mime * * @param   packet  standard Packet structure * * @param   i       index into p->payload buffer to start looking at data * * @return  i       index into p->payload where we stopped looking at data */static const u_int8_t * SMTP_HandleHeader(SFSnortPacket *p, const u_int8_t *ptr,                                          const u_int8_t *data_end_marker){    const u_int8_t *eol;    const u_int8_t *eolm;    const u_int8_t *colon;    const u_int8_t *content_type_ptr = NULL;    int header_line_len;    int header_found;    int ret;    const u_int8_t *start_hdr;    int header_name_len;    start_hdr = ptr;    /* if we got a content-type in a previous packet and are     * folding, the boundary still needs to be checked for */    if (_smtp->state_flags & SMTP_FLAG_IN_CONTENT_TYPE)        content_type_ptr = ptr;    while (ptr < data_end_marker)    {        SMTP_GetEOL(ptr, data_end_marker, &eol, &eolm);                /* got a line with only end of line marker should signify end of header */        if (eolm == ptr)        {            /* reset global header state values */            _smtp->state_flags &= ~(SMTP_FLAG_FOLDING | SMTP_FLAG_IN_CONTENT_TYPE);            _smtp->data_state = STATE_DATA_BODY;            /* if no headers, treat as data */            if (ptr == start_hdr)                return eolm;            else                return eol;        }        /* if we're not folding, see if we should interpret line as a data line          * instead of a header line */        if (!(_smtp->state_flags & SMTP_FLAG_FOLDING))        {            char got_space_in_header_name = 0;            /* if we're not folding and the first char is a space or             * colon, it's not a header */            if (isspace((int)*ptr) || *ptr == ':')            {                _smtp->data_state = STATE_DATA_BODY;                return ptr;            }            /* look for header field colon - if we're not folding then we need             * to find a header which will be all printables (except colon)              * followed by a colon */            colon = ptr;            while ((colon < eolm) && (*colon != ':'))            {                if (isspace((int)*colon))                    got_space_in_header_name = 1;                colon++;            }            /* Check for Exim 4.32 exploit where number of chars before colon is greater than 64 */            header_name_len = colon - ptr;            if ((colon < eolm) && (header_name_len > MAX_HEADER_NAME_LEN))            {                SMTP_GenerateAlert(SMTP_HEADER_NAME_OVERFLOW, "%s: %d chars before colon",                                   SMTP_HEADER_NAME_OVERFLOW_STR, header_name_len);            }            if ((colon == eolm) || got_space_in_header_name)            {                /* no colon or spaces in header name (won't be interpreted as a header)                 * assume we're in the body */                _smtp->data_state = STATE_DATA_BODY;                return ptr;            }            _smtp_current_search = &_smtp_hdr_search[0];            header_found = _dpd.searchAPI->search_find(SEARCH_HDR, (const char *)ptr,                                                       eolm - ptr, 1, SMTP_SearchStrFound);            /* Headers must start at beginning of line */            if ((header_found > 0) && (_smtp_search_info.index == 0))            {                switch (_smtp_search_info.id)                {                    case HDR_CONTENT_TYPE:                        /* for now we're just looking for the boundary in the data                         * header section */                        if (_smtp->data_state == STATE_DATA_HEADER)                        {                            content_type_ptr = ptr + _smtp_search_info.length;                            _smtp->state_flags |= SMTP_FLAG_IN_CONTENT_TYPE;                        }                        break;                                            default:                        break;                }            }        }        /* get length of header line */        header_line_len = eol - ptr;        if ((_smtp_config.max_header_line_len != 0) &&            (header_line_len > _smtp_config.max_header_line_len))        {            SMTP_GenerateAlert(SMTP_DATA_HDR_OVERFLOW, "%s: %d chars",                               SMTP_DATA_HDR_OVERFLOW_STR, header_line_len);        }        /* XXX Does VRT want data headers normalized?         * currently the code does not normalize headers */        if (_smtp_normalizing)        {            ret = SMTP_CopyToAltBuffer(p, ptr, eol - ptr);            if (ret == -1)                return NULL;        }        /* check for folding          * if char on next line is a space and not \n or \r\n, we are folding */        if ((eol < data_end_marker) && isspace((int)eol[0]) && (eol[0] != '\n'))        {            if ((eol < (data_end_marker - 1)) && (eol[0] != '\r') && (eol[1] != '\n'))            {                _smtp->state_flags |= SMTP_FLAG_FOLDING;            }            else            {                _smtp->state_flags &= ~SMTP_FLAG_FOLDING;            }        }        else        {            _smtp->state_flags &= ~SMTP_FLAG_FOLDING;        }        /* check if we're in a content-type header and not folding. if so we have the whole         * header line/lines for content-type - see if we got a multipart with boundary         * we don't check each folded line, but wait until we have the complete header         * because boundary=BOUNDARY can be split across mulitple folded lines before         * or after the '=' */        if ((_smtp->state_flags &             (SMTP_FLAG_IN_CONTENT_TYPE | SMTP_FLAG_FOLDING)) == SMTP_FLAG_IN_CONTENT_TYPE)        {            /* we got the full content-type header - look for boundary string */            ret = SMTP_GetBoundary((const char *)content_type_ptr, eolm - content_type_ptr);            if (ret != -1)            {                ret = SMTP_BoundarySearchInit();                if (ret != -1)                {                    DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Got mime boundary: %s\n",                                                         _smtp->mime_boundary.boundary););                    _smtp->state_flags |= SMTP_FLAG_GOT_BOUNDARY;                }            }            _smtp->state_flags &= ~SMTP_FLAG_IN_CONTENT_TYPE;            content_type_ptr = NULL;        }        ptr = eol;    }    return ptr;}

⌨️ 快捷键说明

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