📄 snort_smtp.c
字号:
_smtp->mime_boundary.boundary_len, BOUNDARY); _dpd.searchAPI->search_instance_prep(_smtp->mime_boundary.boundary_search); return 0;}/* * Reset SMTP session state * * @param none * * @return none */static void SMTP_ResetState(void){ if (_smtp->mime_boundary.boundary_search != NULL) { _dpd.searchAPI->search_instance_free(_smtp->mime_boundary.boundary_search); _smtp->mime_boundary.boundary_search = NULL; } _smtp->state = STATE_COMMAND; _smtp->data_state = STATE_DATA_INIT; _smtp->state_flags = 0; memset(&_smtp->mime_boundary, 0, sizeof(SMTPMimeBoundary));}/* * Given a server configuration and a port number, we decide if the port is * in the SMTP server port list. * * @param port the port number to compare with the configuration * * @return integer * @retval 0 means that the port is not a server port * @retval !0 means that the port is a server port */int SMTP_IsServer(u_int16_t port){ if (_smtp_config.ports[port / 8] & (1 << (port % 8))) { return 1; } return 0;}/* * Do first-packet setup * * @param p standard Packet structure * * @return none */static void SMTP_Setup(SFSnortPacket *p){ int flags = 0; static char checked_reassembling = 0; /* reset normalization stuff */ _smtp_normalizing = 0; p->normalized_payload_size = 0; p->flags &= ~FLAG_ALT_DECODE; if (p->stream_session_ptr != NULL) { /* check to see if we're doing client reassembly in stream */ if (!checked_reassembling) { checked_reassembling = 1; if (_dpd.streamAPI->get_reassembly_direction(p->stream_session_ptr) & SSN_DIR_CLIENT) _smtp_reassembling = 1; } /* set flags to session flags */ flags = _dpd.streamAPI->get_session_flags(p->stream_session_ptr); } /* Figure out direction of packet */ _smtp_pkt_direction = SMTP_GetPacketDirection(p, flags); if ((p->stream_session_ptr == NULL) || (_smtp_config.inspection_type == SMTP_STATELESS)) {#ifdef DEBUG if (p->stream_session_ptr == NULL) { DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Stream session pointer is NULL - " "treating packet as stateless\n");); }#endif SMTP_NoSessionFree(); memset(&_smtp_no_session, 0, sizeof(SMTP)); _smtp = &_smtp_no_session; _smtp->session_flags |= SMTP_FLAG_CHECK_SSL; return; } _smtp = (SMTP *)_dpd.streamAPI->get_application_data(p->stream_session_ptr, PP_SMTP); if (_smtp == NULL) { DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Creating new session data structure\n");); _smtp = (SMTP *)calloc(1, sizeof(SMTP)); if (_smtp == NULL) { DynamicPreprocessorFatalMessage("Failed to allocate SMTP session data\n"); } else { _dpd.streamAPI->set_application_data(p->stream_session_ptr, PP_SMTP, _smtp, &SMTP_SessionFree); if (p->flags & SSNFLAG_MIDSTREAM) { DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Got midstream packet - " "setting state to unknown\n");); _smtp->state = STATE_UNKNOWN; }#ifdef DEBUG _smtp_session_counter++; _smtp->session_number = _smtp_session_counter;#endif } } DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Session number: "STDu64"\n", _smtp->session_number);); /* reset check ssl flag for new packet */ if (!(_smtp->session_flags & SMTP_FLAG_CHECK_SSL)) _smtp->session_flags |= SMTP_FLAG_CHECK_SSL; /* Check to see if there is a reassembly gap. If so, we won't know * what state we're in when we get the _next_ reassembled packet */ if (_smtp_check_gaps && (_smtp_pkt_direction != SMTP_PKT_FROM_SERVER) && (p->flags & FLAG_REBUILT_STREAM)) { char missing_in_rebuilt = _dpd.streamAPI->missing_in_reassembled(p->stream_session_ptr, SSN_DIR_CLIENT); if (_smtp->session_flags & SMTP_FLAG_NEXT_STATE_UNKNOWN) { DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Found gap in previous reassembly buffer - " "set state to unknown\n");); _smtp->state = STATE_UNKNOWN; _smtp->session_flags &= ~SMTP_FLAG_NEXT_STATE_UNKNOWN; } if (missing_in_rebuilt == 3) { DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Found missing packets before and after " "in reassembly buffer - set state to unknown and " "next state to unknown\n");); _smtp->state = STATE_UNKNOWN; _smtp->session_flags |= SMTP_FLAG_NEXT_STATE_UNKNOWN; } else if (missing_in_rebuilt == 2) { DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Found missing packets before " "in reassembly buffer - set state to unknown\n");); _smtp->state = STATE_UNKNOWN; } else if (missing_in_rebuilt == 1) { DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Found missing packets after " "in reassembly buffer - set next state to unknown\n");); _smtp->session_flags |= SMTP_FLAG_NEXT_STATE_UNKNOWN; } }}/* * Determine packet direction * * @param p standard Packet structure * * @return none */static int SMTP_GetPacketDirection(SFSnortPacket *p, int flags){ int pkt_direction = SMTP_PKT_FROM_UNKNOWN; if (flags & SSNFLAG_MIDSTREAM) { if (SMTP_IsServer(p->src_port) && !SMTP_IsServer(p->dst_port)) { pkt_direction = SMTP_PKT_FROM_SERVER; } else if (!SMTP_IsServer(p->src_port) && SMTP_IsServer(p->dst_port)) { pkt_direction = SMTP_PKT_FROM_CLIENT; } } 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; } /* if direction is still unknown ... */ if (pkt_direction == SMTP_PKT_FROM_UNKNOWN) { if (SMTP_IsServer(p->src_port) && !SMTP_IsServer(p->dst_port)) { pkt_direction = SMTP_PKT_FROM_SERVER; } else if (!SMTP_IsServer(p->src_port) && SMTP_IsServer(p->dst_port)) { pkt_direction = SMTP_PKT_FROM_CLIENT; } } } 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 */#ifdef DETECTION_OPTION_TREEstatic int SMTP_SearchStrFound(void *id, void *unused, int index, void *data)#elsestatic int SMTP_SearchStrFound(void *id, int index, void *data)#endif{ 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 */#ifdef DETECTION_OPTION_TREEstatic int SMTP_BoundaryStrFound(void *id, void *unused, int index, void *data)#elsestatic int SMTP_BoundaryStrFound(void *id, int index, void *data)#endif{ 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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -