From: Jeff Lucovsky Date: Wed, 28 Aug 2019 22:54:14 +0000 (-0400) Subject: ftp: Use rust parsers to parse dynamic ports X-Git-Tag: suricata-5.0.0-rc1~19 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b4070b6dcd7942521181771de1d9b2fdb9db2d50;p=thirdparty%2Fsuricata.git ftp: Use rust parsers to parse dynamic ports --- diff --git a/src/app-layer-ftp.c b/src/app-layer-ftp.c index b2035378ce..6d29d5be1b 100644 --- a/src/app-layer-ftp.c +++ b/src/app-layer-ftp.c @@ -540,69 +540,6 @@ static uint32_t CopyCommandLine(uint8_t **dest, const uint8_t *src, uint32_t len return length; } -static uint16_t ftp_validate_port(int computed_port_value) -{ - unsigned int port_val = computed_port_value; - - if (port_val && port_val > UINT16_MAX) - return 0; - - return ((uint16_t) (port_val)); -} - -/** - * \brief This function extracts a port number from the command input line for IPv6 FTP usage - * \param input input line of the command - * \param input_len length of the request - * - * \retval 0 if a port number could not be extracted; otherwise, the dynamic port number - */ -static uint16_t FTPGetV6PortNumber(const uint8_t *input, uint32_t input_len) -{ - uint16_t res; - - uint8_t *ptr = memrchr(input, '|', input_len); - if (ptr == NULL) { - return 0; - } - - int n_length = ptr - input - 1; - if (n_length < 4) - return 0; - - ptr = memrchr(input, '|', n_length); - if (ptr == NULL) - return 0; - - if (ByteExtractStringUint16(&res, 10, 0, (const char *)ptr + 1) < 0) { - return 0; - } - return res; -} - -/** - * \brief This function extracts a port number from the command input line for IPv4 FTP usage - * \param input input line of the command - * \param input_len length of the request - * - * \retval 0 if a port number could not be extracted; otherwise, the dynamic port number - */ -static uint16_t FTPGetV4PortNumber(const uint8_t *input, uint32_t input_len) -{ - uint16_t part1, part2; - uint8_t *ptr = memrchr(input, ',', input_len); - if (ptr == NULL) - return 0; - - part2 = atoi((char *)ptr + 1); - ptr = memrchr(input, ',', (ptr - input) - 1); - if (ptr == NULL) - return 0; - part1 = atoi((char *)ptr + 1); - - return ftp_validate_port(256 * part1 + part2); -} - /** * \brief This function is called to retrieve a ftp request @@ -663,7 +600,7 @@ static int FTPParseRequest(Flow *f, void *ftp_state, if (state->current_line_len + 1 > state->port_line_size) { /* Allocate an extra byte for a NULL terminator */ ptmp = FTPRealloc(state->port_line, state->port_line_size, - state->current_line_len + 1); + state->current_line_len); if (ptmp == NULL) { if (state->port_line) { FTPFree(state->port_line, state->port_line_size); @@ -673,11 +610,10 @@ static int FTPParseRequest(Flow *f, void *ftp_state, return 0; } state->port_line = ptmp; - state->port_line_size = state->current_line_len + 1; + state->port_line_size = state->current_line_len; } memcpy(state->port_line, state->current_line, state->current_line_len); - state->port_line[state->current_line_len] = '\0'; state->port_line_len = state->current_line_len; break; case FTP_COMMAND_RETR: @@ -818,7 +754,7 @@ static int FTPParseResponse(Flow *f, void *ftp_state, AppLayerParserState *pstat } if (state->command == FTP_COMMAND_EPRT) { - uint16_t dyn_port = FTPGetV6PortNumber(state->port_line, state->port_line_len); + uint16_t dyn_port = rs_ftp_active_eprt(state->port_line, state->port_line_len); if (dyn_port == 0) { retcode = 0; goto tx_complete; @@ -832,7 +768,7 @@ static int FTPParseResponse(Flow *f, void *ftp_state, AppLayerParserState *pstat if (state->command == FTP_COMMAND_PORT) { if ((flags & STREAM_TOCLIENT)) { - uint16_t dyn_port = FTPGetV4PortNumber(state->port_line, state->port_line_len); + uint16_t dyn_port = rs_ftp_active_port(state->port_line, state->port_line_len); if (dyn_port == 0) { retcode = 0; goto tx_complete;