From: Russ Combs (rucombs) Date: Tue, 12 Apr 2022 14:59:40 +0000 (+0000) Subject: Pull request #3363: ftp: splitter and inspector fixes X-Git-Tag: 3.1.28.0~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e4c6e1207dd70a26518015f7de48f546c5c811be;p=thirdparty%2Fsnort3.git Pull request #3363: ftp: splitter and inspector fixes Merge in SNORT/snort3 from ~BRASTULT/snort3:ftp_splitter_fix to master Squashed commit of the following: commit 5dae1d6e2ad7c446d8f1ff565de6730e47fb4eab Author: Brandon Stultz Date: Tue Apr 5 03:39:36 2022 -0400 ftp: fix FTP response parsing commit 08fdc2b94f137b87caca64e66ecae33f2e696329 Author: Brandon Stultz Date: Tue Apr 5 00:54:37 2022 -0400 ftp: flush FTP cmds ending in just carriage return --- diff --git a/src/service_inspectors/ftp_telnet/ftp_splitter.cc b/src/service_inspectors/ftp_telnet/ftp_splitter.cc index d98c2342a..137a2f47e 100644 --- a/src/service_inspectors/ftp_telnet/ftp_splitter.cc +++ b/src/service_inspectors/ftp_telnet/ftp_splitter.cc @@ -24,6 +24,7 @@ #include "ftp_splitter.h" #include "protocols/ssl.h" #include "protocols/packet.h" +#include "utils/util.h" #include @@ -31,34 +32,34 @@ using namespace snort; FtpSplitter::FtpSplitter(bool c2s) : StreamSplitter(c2s) { } -// flush at last line feed in data +// flush at last CR or LF in data // preproc will deal with any pipelined commands StreamSplitter::Status FtpSplitter::scan( Packet* p, const uint8_t* data, uint32_t len, uint32_t, uint32_t* fp) { - if(IsSSL(data, len, p->packet_flags)) + if ( IsSSL(data, len, p->packet_flags) ) { *fp = len; return FLUSH; } -#ifdef HAVE_MEMRCHR - const uint8_t* lf = (const uint8_t*)memrchr(data, '\n', len); -#else - uint32_t n = len; - const uint8_t* lf = nullptr, * tmp = data; - while ( (tmp = (const uint8_t*)memchr(tmp, '\n', n)) ) - { - lf = tmp++; - n = len - (tmp - data); - } -#endif + const uint8_t* cr = snort_memrchr(data, '\r', len); + const uint8_t* lf = snort_memrchr(data, '\n', len); + + const uint8_t* ptr = nullptr; + + if ( cr && !lf ) + ptr = cr; + else if ( !cr && lf ) + ptr = lf; + else if ( cr && lf ) + ptr = ( cr > lf ) ? cr : lf; - if ( !lf ) + if ( !ptr ) return SEARCH; - *fp = lf - data + 1; + *fp = ptr - data + 1; return FLUSH; } diff --git a/src/service_inspectors/ftp_telnet/pp_ftp.cc b/src/service_inspectors/ftp_telnet/pp_ftp.cc index 550807fb9..a703f07ed 100644 --- a/src/service_inspectors/ftp_telnet/pp_ftp.cc +++ b/src/service_inspectors/ftp_telnet/pp_ftp.cc @@ -1596,7 +1596,7 @@ int check_ftp(FTP_SESSION* ftpssn, Packet* p, int iMode) { req->cmd_begin = nullptr; req->cmd_end = nullptr; - if (*read_ptr != SP) + if (*read_ptr != SP && read_ptr != p->data) read_ptr--; state = FTP_RESPONSE_CONT; } diff --git a/src/utils/util.cc b/src/utils/util.cc index 6694e037f..8e109303d 100644 --- a/src/utils/util.cc +++ b/src/utils/util.cc @@ -534,6 +534,25 @@ char* snort_strdup(const char* str) return p; } +const uint8_t* snort_memrchr(const uint8_t* buf, char c, size_t len) +{ +#ifdef HAVE_MEMRCHR + return (const uint8_t*)memrchr(buf, c, len); +#else + size_t n = len; + const uint8_t* tmp = buf; + const uint8_t* ptr = nullptr; + + while ( n > 0 && (tmp = (const uint8_t*)memchr(tmp, c, n)) ) + { + ptr = tmp++; + n = len - (tmp - buf); + } + + return ptr; +#endif +} + void ts_print(const struct timeval* tvp, char* timebuf, bool yyyymmdd) { struct timeval tv; diff --git a/src/utils/util.h b/src/utils/util.h index 31ab353bf..61f658c14 100644 --- a/src/utils/util.h +++ b/src/utils/util.h @@ -108,6 +108,7 @@ SO_PUBLIC extern char** protocol_names; SO_PUBLIC const char* get_error(int errnum); SO_PUBLIC char* snort_strdup(const char*); SO_PUBLIC char* snort_strndup(const char*, size_t); +SO_PUBLIC const uint8_t* snort_memrchr(const uint8_t*, char, size_t); SO_PUBLIC void ts_print(const struct timeval*, char*, bool yyyymmdd = false); }