aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2019-08-26 19:41:14 -0400
committerAnders Broman <a.broman58@gmail.com>2019-08-27 04:04:12 +0000
commit698126581eebdd757d2e55830370b8dd3d9b759d (patch)
tree16b98793aada34650bae6e3af846be23aa92c722
parentc9f2b9b3edcc7d99a0eb9b506ff3b5f0101bd1a8 (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.c75
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;