#endif
#include "ftp_splitter.h"
+#include "protocols/ssl.h"
+#include "protocols/packet.h"
#include <cstring>
// flush at last line feed in data
// preproc will deal with any pipelined commands
StreamSplitter::Status FtpSplitter::scan(
- Packet*, const uint8_t* data, uint32_t len,
+ Packet* p, const uint8_t* data, uint32_t len,
uint32_t, uint32_t* fp)
{
+ if(IsSSL(data, len, p->packet_flags))
+ {
+ *fp = len;
+ return FLUSH;
+ }
#ifdef HAVE_MEMRCHR
uint8_t* lf = (uint8_t*)memrchr(data, '\n', len);
#else
#define MAXHOSTNAMELEN 256
#endif
-static THREAD_LOCAL DataBuffer DecodeBuffer;
-
/*
* Used to keep track of pipelined commands and the last one
* that resulted in a
*/
int initialize_ftp(FTP_SESSION* session, Packet* p, int iMode)
{
- int iRet;
const unsigned char* read_ptr = p->data;
FTP_CLIENT_REQ* req;
- char ignoreTelnetErase = FTPP_APPLY_TNC_ERASE_CMDS;
-
- /* Normalize this packet ala telnet */
- if (((iMode == FTPP_SI_CLIENT_MODE) &&
- session->client_conf->ignore_telnet_erase_cmds) ||
- ((iMode == FTPP_SI_SERVER_MODE) &&
- session->server_conf->ignore_telnet_erase_cmds) )
- ignoreTelnetErase = FTPP_IGNORE_TNC_ERASE_CMDS;
-
- iRet = normalize_telnet(nullptr, p, iMode, ignoreTelnetErase);
- if (iRet != FTPP_SUCCESS && iRet != FTPP_NORMALIZED)
+ if ( session->encr_state == NO_STATE )
{
- if (iRet == FTPP_ALERT)
- DetectionEngine::queue_event(GID_FTP, FTP_EVASIVE_TELNET_CMD);
+ int iRet;
+ char ignoreTelnetErase = FTPP_APPLY_TNC_ERASE_CMDS;
+ /* Normalize this packet ala telnet */
+ if (((iMode == FTPP_SI_CLIENT_MODE) &&
+ session->client_conf->ignore_telnet_erase_cmds) ||
+ ((iMode == FTPP_SI_SERVER_MODE) &&
+ session->server_conf->ignore_telnet_erase_cmds) )
+ ignoreTelnetErase = FTPP_IGNORE_TNC_ERASE_CMDS;
- return iRet;
- }
+ DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
- if ( DecodeBuffer.len )
- {
- /* Normalized data will always be in decode buffer */
- if ( (iMode == FTPP_SI_CLIENT_MODE) ||
- (iMode == FTPP_SI_SERVER_MODE) )
+ iRet = normalize_telnet(nullptr, p, buf, iMode, ignoreTelnetErase, true);
+
+ if (iRet != FTPP_SUCCESS && iRet != FTPP_NORMALIZED)
{
- DetectionEngine::queue_event(GID_FTP, FTP_TELNET_CMD);
- return FTPP_ALERT; /* Nothing else to do since we alerted */
+ if (iRet == FTPP_ALERT)
+ DetectionEngine::queue_event(GID_FTP, FTP_EVASIVE_TELNET_CMD);
+
+ return iRet;
}
- read_ptr = DecodeBuffer.data;
+
+ if ( buf.len )
+ {
+ /* Normalized data will always be in decode buffer */
+ if ( (iMode == FTPP_SI_CLIENT_MODE) ||
+ (iMode == FTPP_SI_SERVER_MODE) )
+ {
+ DetectionEngine::queue_event(GID_FTP, FTP_TELNET_CMD);
+ return FTPP_ALERT; /* Nothing else to do since we alerted */
+ }
+
+ read_ptr = buf.data;
+ }
}
if (iMode == FTPP_SI_CLIENT_MODE)
const unsigned char* end = p->data + p->dsize;
- if ( DecodeBuffer.len )
- end = DecodeBuffer.data + DecodeBuffer.len;
+ DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
+ if ( buf.len )
+ end = buf.data + buf.len;
if (iMode == FTPP_SI_CLIENT_MODE)
{
*
*/
int normalize_telnet(
- TELNET_SESSION* tnssn, Packet* p,
- int iMode, char ignoreEraseCmds)
+ TELNET_SESSION* tnssn, Packet* p, DataBuffer& buf,
+ int iMode, char ignoreEraseCmds, bool on_ftp_channel)
{
int ret = FTPP_NORMALIZED;
const unsigned char* read_ptr, * sb_start = nullptr;
int normalization_required = 0;
int consec_8bit_chars = 0;
- DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
const unsigned char* start = buf.data;
+ buf.len = 0;
/* Telnet commands are handled in here.
* They can be 2 bytes long -- ie, IAC NOP, IAC AYT, etc.
}
else
{
+ if ( on_ftp_channel )
+ {
+ return FTPP_SUCCESS;
+ }
/* Okay, it wasn't an IAC also its a midstream pickup */
if (*read_ptr > 0x7F && Stream::is_midstream(p->flow))
{
if (write_ptr > start)
{
write_ptr--;
+ buf.len--;
}
}
break;
{
/* Go to previous char */
write_ptr--;
+ buf.len--;
if ((*write_ptr == CR) &&
((*(write_ptr+1) == NUL) || (*(write_ptr+1) == LF)) )
* beginning of this line
*/
write_ptr+=2;
+ buf.len+=2;
break;
}
}
* in the data stream since it was escaped */
read_ptr++; /* skip past the first IAC */
*write_ptr++ = *read_ptr++;
+ buf.len++;
break;
case TNC_WILL:
case TNC_WONT:
if (write_ptr > start)
{
write_ptr--;
+ buf.len--;
}
read_ptr++;
break;
default:
*write_ptr++ = *read_ptr++;
+ buf.len++;
break;
}
#define FTPP_APPLY_TNC_ERASE_CMDS 0
#define FTPP_IGNORE_TNC_ERASE_CMDS 1
+struct DataBuffer;
/* list of function prototypes for this preprocessor */
-extern int normalize_telnet(TELNET_SESSION*, snort::Packet*, int iMode, char ignoreEraseCmd);
+extern int normalize_telnet(TELNET_SESSION*, snort::Packet*, DataBuffer&, int iMode, char ignoreEraseCmd, bool on_ftp_channel);
void reset_telnet_buffer(snort::Packet*);
const uint8_t* get_telnet_buffer(snort::Packet*, unsigned&);
#include "telnet.h"
+#include "detection/detection_engine.h"
#include "log/messages.h"
#include "profiler/profiler.h"
#include "protocols/packet.h"
if ( telnet_config->normalize )
{
- int ret = normalize_telnet(Telnetsession, p, iInspectMode,
- FTPP_APPLY_TNC_ERASE_CMDS);
+ DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
+ int ret = normalize_telnet(Telnetsession, p, buf, iInspectMode,
+ FTPP_APPLY_TNC_ERASE_CMDS, false);
if ( ret == FTPP_SUCCESS || ret == FTPP_NORMALIZED )
{