eve/ftp: Bug fix and banner capture

1. Correct off-by-one error in server response whitespace removal
2. Include banner response (before first command entered)
pull/4046/head
Zach Kelly 7 years ago committed by Victor Julien
parent a04b1c1664
commit 1588cd8735

@ -473,17 +473,21 @@ static void FtpTransferCmdFree(void *data)
static uint32_t CopyCommandLine(uint8_t **dest, uint8_t *src, uint32_t length) static uint32_t CopyCommandLine(uint8_t **dest, uint8_t *src, uint32_t length)
{ {
if (likely(length)) { if (likely(length)) {
uint8_t *where = FTPCalloc(length, sizeof(char)); if (unlikely(length == UINT32_MAX)) {
return 0;
}
uint8_t *where = FTPCalloc(length + 1, sizeof(char));
if (unlikely(where == NULL)) { if (unlikely(where == NULL)) {
return 0; return 0;
} }
memcpy(where, src, length); memcpy(where, src, length);
/* Remove trailing newlines/carriage returns */ /* Remove trailing newlines/carriage returns */
if (isspace((unsigned char)where[length - 1])) { while (length && isspace((unsigned char) where[length - 1])) {
while(length && isspace((unsigned char)where[--length - 1])); length--;
where[length] = '\0';
} }
where[length] = '\0';
*dest = where; *dest = where;
} }
/* either 0 or actual */ /* either 0 or actual */
@ -750,6 +754,7 @@ static int FTPParseResponse(Flow *f, void *ftp_state, AppLayerParserState *pstat
void *local_data, const uint8_t flags) void *local_data, const uint8_t flags)
{ {
FtpState *state = (FtpState *)ftp_state; FtpState *state = (FtpState *)ftp_state;
FTPTransaction *tx = NULL;
int retcode = 1; int retcode = 1;
FTPTransaction *tx; FTPTransaction *tx;
@ -769,9 +774,9 @@ static int FTPParseResponse(Flow *f, void *ftp_state, AppLayerParserState *pstat
tx->command_descriptor = &FtpCommands[FTP_COMMAND_MAX -1]; tx->command_descriptor = &FtpCommands[FTP_COMMAND_MAX -1];
} else { } else {
tx = FTPGetOldestTx(state); tx = FTPGetOldestTx(state);
state->curr_tx = tx;
} }
state->curr_tx = tx;
if (state->command == FTP_COMMAND_AUTH_TLS) { if (state->command == FTP_COMMAND_AUTH_TLS) {
if (input_len >= 4 && SCMemcmp("234 ", input, 4) == 0) { if (input_len >= 4 && SCMemcmp("234 ", input, 4) == 0) {
AppLayerRequestProtocolTLSUpgrade(f); AppLayerRequestProtocolTLSUpgrade(f);

@ -69,14 +69,21 @@ static void JsonFTPLogJSON(json_t *tjs, Flow *f, FTPTransaction *tx)
} else { } else {
cjs = json_object(); cjs = json_object();
if (cjs) { if (cjs) {
json_object_set_new(cjs, "command", FTPString *response;
json_string(tx->command_descriptor->command_name_upper)); if (tx->command_descriptor->command == FTP_COMMAND_UNKNOWN) {
// alternatively, `command` could be left out of the object completely
json_object_set_new(cjs, "command", json_null());
} else {
json_object_set_new(cjs, "command", json_string(tx->command_descriptor->command_name_upper));
}
uint32_t min_length = tx->command_descriptor->command_length + 1; /* command + space */ uint32_t min_length = tx->command_descriptor->command_length + 1; /* command + space */
json_object_set_new(cjs, "command_data", if (tx->request_length > min_length) {
tx->request_length >= min_length ? json_object_set_new(cjs, "command_data",
JsonAddStringN((const char *)tx->request + min_length, JsonAddStringN((const char *)tx->request + min_length,
tx->request_length - min_length) : tx->request_length - min_length));
json_string(NULL)); } else {
json_object_set_new(cjs, "command_data", json_string(NULL));
}
if (!TAILQ_EMPTY(&tx->response_list)) { if (!TAILQ_EMPTY(&tx->response_list)) {
json_t *js_resplist = json_array(); json_t *js_resplist = json_array();
if (likely(js_resplist != NULL)) { if (likely(js_resplist != NULL)) {

Loading…
Cancel
Save