diff options
author | Michael Mann <mmann78@netscape.net> | 2019-08-26 19:41:14 -0400 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2019-08-27 04:04:12 +0000 |
commit | 698126581eebdd757d2e55830370b8dd3d9b759d (patch) | |
tree | 16b98793aada34650bae6e3af846be23aa92c722 | |
parent | c9f2b9b3edcc7d99a0eb9b506ff3b5f0101bd1a8 (diff) |
SMTP: Add support for multiline responses
Commands with "-" at the end mean another line with the same command will
follow. Group all of those lines in a single response tree and don't append
the command value in the Info column for the additional lines.
Bug: 15933
Change-Id: Icba167f2f1d22ebaf53a6844285ba83ed8a20106
Reviewed-on: https://code.wireshark.org/review/34381
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r-- | epan/dissectors/packet-smtp.c | 75 |
1 files changed, 53 insertions, 22 deletions
diff --git a/epan/dissectors/packet-smtp.c b/epan/dissectors/packet-smtp.c index d1567851fc..76423e4207 100644 --- a/epan/dissectors/packet-smtp.c +++ b/epan/dissectors/packet-smtp.c @@ -77,6 +77,7 @@ static gint ett_smtp_data_fragment = -1; static gint ett_smtp_data_fragments = -1; static expert_field ei_smtp_base64_decode = EI_INIT; +static expert_field ei_smtp_rsp_code = EI_INIT; static gboolean smtp_auth_parameter_decoding_enabled = FALSE; /* desegmentation of SMTP command and response lines */ @@ -155,6 +156,14 @@ typedef enum { SMTP_AUTH_STATE_FAILED /* authentication failed, no decoding */ } smtp_auth_state_t; +typedef enum { + SMTP_MULTILINE_NONE, + SMTP_MULTILINE_START, + SMTP_MULTILINE_CONTINUE, + SMTP_MULTILINE_END + +} smtp_multiline_state_t; + struct smtp_session_state { smtp_state_t smtp_state; /* Current state */ smtp_auth_state_t auth_state; /* Current authentication state */ @@ -739,10 +748,8 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_ col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMTP"); col_clear(pinfo->cinfo, COL_INFO); - if (tree) { /* Build the tree info ... */ - ti = proto_tree_add_item(tree, proto_smtp, tvb, offset, -1, ENC_NA); - smtp_tree = proto_item_add_subtree(ti, ett_smtp); - } + ti = proto_tree_add_item(tree, proto_smtp, tvb, offset, -1, ENC_NA); + smtp_tree = proto_item_add_subtree(ti, ett_smtp); if (request) { /* @@ -1058,13 +1065,16 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_ * Process the response, a line at a time, until we hit a line * that doesn't have a continuation indication on it. */ - if (tree) { - hidden_item = proto_tree_add_boolean(smtp_tree, hf_smtp_rsp, tvb, - 0, 0, TRUE); - proto_item_set_hidden(hidden_item); - } + hidden_item = proto_tree_add_boolean(smtp_tree, hf_smtp_rsp, tvb, 0, 0, TRUE); + proto_item_set_hidden(hidden_item); loffset = offset; + + //Multiline information + smtp_multiline_state_t multiline_state = SMTP_MULTILINE_NONE; + guint32 multiline_code = 0; + proto_item* code_item = NULL; + while (tvb_offset_exists(tvb, offset)) { /* * Find the end of the line. @@ -1076,16 +1086,6 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_ else col_append_str(pinfo->cinfo, COL_INFO, " | "); - if (tree) { - /* - * Put it into the protocol tree. - */ - ti = proto_tree_add_item(smtp_tree, hf_smtp_response, tvb, - offset, next_offset - offset, ENC_ASCII|ENC_NA); - cmdresp_tree = proto_item_add_subtree(ti, ett_smtp_cmdresp); - } else - cmdresp_tree = NULL; - if (linelen >= 3) { line_code[0] = tvb_get_guint8(tvb, offset); line_code[1] = tvb_get_guint8(tvb, offset+1); @@ -1096,6 +1096,16 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_ * We have a 3-digit response code. */ code = (line_code[0] - '0')*100 + (line_code[1] - '0')*10 + (line_code[2] - '0'); + if ((linelen > 3) && (tvb_get_guint8(tvb, offset + 3) == '-')) { + if (multiline_state == SMTP_MULTILINE_NONE) { + multiline_state = SMTP_MULTILINE_START; + multiline_code = code; + } else { + multiline_state = SMTP_MULTILINE_CONTINUE; + } + } else if ((multiline_state == SMTP_MULTILINE_START) || (multiline_state == SMTP_MULTILINE_CONTINUE)) { + multiline_state = SMTP_MULTILINE_END; + } /* * If we're awaiting the response to a STARTTLS code, this @@ -1155,9 +1165,19 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_ /* * Put the response code and parameters into the protocol tree. + * Only create a new response tree when not in the middle of multiline response. */ - proto_tree_add_uint(cmdresp_tree, hf_smtp_rsp_code, tvb, offset, 3, - code); + if ((multiline_state != SMTP_MULTILINE_CONTINUE) && + (multiline_state != SMTP_MULTILINE_END)) + { + ti = proto_tree_add_item(smtp_tree, hf_smtp_response, tvb, + offset, next_offset - offset, ENC_ASCII | ENC_NA); + cmdresp_tree = proto_item_add_subtree(ti, ett_smtp_cmdresp); + + code_item = proto_tree_add_uint(cmdresp_tree, hf_smtp_rsp_code, tvb, offset, 3, code); + } else if (multiline_code != code) { + expert_add_info_format(pinfo, code_item, &ei_smtp_rsp_code, "Unexpected response code %u in multiline response. Expected %u", code, multiline_code); + } decrypt = NULL; if (linelen >= 4) { @@ -1187,14 +1207,24 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_ proto_tree_add_item(cmdresp_tree, hf_smtp_rsp_parameter, tvb, offset + 4, linelen - 4, ENC_ASCII|ENC_NA); - col_append_fstr(pinfo->cinfo, COL_INFO, "%s", + if ((multiline_state != SMTP_MULTILINE_CONTINUE) && + (multiline_state != SMTP_MULTILINE_END)) { + col_append_fstr(pinfo->cinfo, COL_INFO, "%s", tvb_format_text(tvb, offset, linelen)); + } else { + col_append_fstr(pinfo->cinfo, COL_INFO, "%s", + tvb_format_text(tvb, offset+4, linelen-4)); + } } } else { col_append_str(pinfo->cinfo, COL_INFO, tvb_format_text(tvb, offset, linelen)); } } + + //Clear multiline state if this is the last line + if (multiline_state == SMTP_MULTILINE_END) + multiline_state = SMTP_MULTILINE_NONE; } /* * Step past this line. @@ -1318,6 +1348,7 @@ proto_register_smtp(void) static ei_register_info ei[] = { { &ei_smtp_base64_decode, { "smtp.base64_decode", PI_PROTOCOL, PI_WARN, "base64 decode failed or is not enabled (check SMTP preferences)", EXPFILL }}, + { &ei_smtp_rsp_code,{ "smtp.response.code.unexpected", PI_PROTOCOL, PI_WARN, "Unexpected response code in multiline response", EXPFILL } }, }; module_t *smtp_module; |