aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-smtp.c
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2015-02-06 12:35:09 +0100
committerMichael Mann <mmann78@netscape.net>2015-02-09 14:03:34 +0000
commite190253478cea8ab10903e83daafeb3574ad0f04 (patch)
treeb1a6619a21c6979bb598dcb6f2c3d6f76cc66c20 /epan/dissectors/packet-smtp.c
parent93ed72642b3bc0771c6099c4861a39c080040b0e (diff)
Fix STARTTLS handling in various dissectors
This patch lets a dissector hand over control to the SSL dissector which simplifies dissector code ("TCP | App | SSL | App" becomes "TCP | SSL | App"). After this patch, all of the affected dissectors will now be dissected as SSL with its Application Data being treated as the protocol before STARTTLS. This was previously not the case because the port was not registered for dissection via ssl_dissector_add. The desegmentation issue within the MySQL dissector is now also gone. Convert some tvb_length[_remaining] users in pop and smtp as well. Tested against mysql-ssl.pcapng and mysql-ssl-larger.pcapng(*1), Tested against pop-ssl.pcapng (note: only first stream is decrypted, either the key after negotiation is wrong or there is a bug), Tested against smtp-ssl.pcapng and smtp2525-ssl.pcapng (with Decode As) and smtp-ssl.pcapng with filter "tcp.len>0", Tested against xmpp-ssl.pcapng, http://wiki.wireshark.org/SampleCaptures#SSL_with_decryption_keys *1) mysql-ssl-larger has MySQL dissector errors for the fragmented SSL packet, but reassembly seems to work. Needs further investigation. Bug: 9515 Change-Id: I408ef8ff30d9edc8954dab9b3615900666dfa932 Reviewed-on: https://code.wireshark.org/review/6981 Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan/dissectors/packet-smtp.c')
-rw-r--r--epan/dissectors/packet-smtp.c41
1 files changed, 9 insertions, 32 deletions
diff --git a/epan/dissectors/packet-smtp.c b/epan/dissectors/packet-smtp.c
index 5cd734d321..3ebbd7f8a6 100644
--- a/epan/dissectors/packet-smtp.c
+++ b/epan/dissectors/packet-smtp.c
@@ -36,6 +36,7 @@
#include <epan/reassemble.h>
#include <wsutil/base64.h>
#include "packet-ssl.h"
+#include "packet-ssl-utils.h"
/* RFC 2821 */
#define TCP_PORT_SMTP 25
@@ -109,6 +110,7 @@ static const fragment_items smtp_data_frag_items = {
"DATA fragments"
};
+static dissector_handle_t smtp_handle;
static dissector_handle_t ssl_handle;
static dissector_handle_t imf_handle;
static dissector_handle_t ntlmssp_handle;
@@ -167,7 +169,6 @@ struct smtp_session_state {
guint32 msg_read_len; /* Length of BDAT message read so far */
guint32 msg_tot_len; /* Total length of BDAT message */
gboolean msg_last; /* Is this the last BDAT chunk */
- guint32 last_nontls_frame; /* last non-TLS frame; 0 if not known or no TLS */
guint32 username_cmd_frame; /* AUTH command contains username */
guint32 user_pass_cmd_frame; /* AUTH command contains username and password */
guint32 user_pass_frame; /* Frame contains username and password */
@@ -412,29 +413,6 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
conversation_add_proto_data(conversation, proto_smtp, session_state);
}
- /* Are we doing TLS?
- * FIXME In my understanding of RFC 2487 client and server can send SMTP cmds
- * after a rejected TLS negotiation
- */
- if (session_state->last_nontls_frame != 0 && pinfo->fd->num > session_state->last_nontls_frame) {
- guint16 save_can_desegment;
- guint32 save_last_nontls_frame;
-
- /* This is TLS, not raw SMTP. TLS can desegment */
- save_can_desegment = pinfo->can_desegment;
- pinfo->can_desegment = pinfo->saved_can_desegment;
-
- /* Make sure the SSL dissector will not be called again after decryption */
- save_last_nontls_frame = session_state->last_nontls_frame;
- session_state->last_nontls_frame = 0;
-
- call_dissector(ssl_handle, tvb, pinfo, tree);
-
- pinfo->can_desegment = save_can_desegment;
- session_state->last_nontls_frame = save_last_nontls_frame;
- return;
- }
-
/* Is this a request or a response? */
request = pinfo->destport == pinfo->match_uint;
@@ -486,7 +464,7 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
return;
} else {
- linelen = tvb_length_remaining(tvb, loffset);
+ linelen = tvb_reported_length_remaining(tvb, loffset);
next_offset = loffset + linelen;
}
}
@@ -507,7 +485,7 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
tvb_strneql(tvb, loffset, "\r\n.\r\n", 5) == 0)
eom_seen = TRUE;
- length_remaining = tvb_length_remaining(tvb, loffset);
+ length_remaining = tvb_captured_length_remaining(tvb, loffset);
if (length_remaining == tvb_reported_length_remaining(tvb, loffset) &&
tvb_strneql(tvb, loffset + length_remaining - 2, "\r\n", 2) == 0)
session_state->crlf_seen = TRUE;
@@ -543,7 +521,7 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
* We are handling a BDAT message.
* Check if we have reached end of the data chunk.
*/
- session_state->msg_read_len += tvb_length_remaining(tvb, loffset);
+ session_state->msg_read_len += tvb_reported_length_remaining(tvb, loffset);
if (session_state->msg_read_len == session_state->msg_tot_len) {
/*
@@ -762,7 +740,7 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
case SMTP_PDU_MESSAGE:
/* Column Info */
- length_remaining = tvb_length_remaining(tvb, offset);
+ length_remaining = tvb_reported_length_remaining(tvb, offset);
col_set_str(pinfo->cinfo, COL_INFO, smtp_data_desegment ? "C: DATA fragment" : "C: Message Body");
col_append_fstr(pinfo->cinfo, COL_INFO, ", %d byte%s", length_remaining,
plurality (length_remaining, "", "s"));
@@ -770,7 +748,8 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (smtp_data_desegment) {
frag_msg = fragment_add_seq_next(&smtp_data_reassembly_table, tvb, 0,
pinfo, spd_frame_data->conversation_id, NULL,
- tvb_length(tvb), spd_frame_data->more_frags);
+ tvb_reported_length(tvb),
+ spd_frame_data->more_frags);
} else {
/*
* Message body.
@@ -1061,7 +1040,7 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (session_state->smtp_state == SMTP_STATE_AWAITING_STARTTLS_RESPONSE) {
if (code == 220) {
/* This is the last non-TLS frame. */
- session_state->last_nontls_frame = pinfo->fd->num;
+ ssl_starttls_ack(ssl_handle, pinfo, smtp_handle);
}
session_state->smtp_state = SMTP_STATE_READING_CMDS;
}
@@ -1309,8 +1288,6 @@ proto_register_smtp(void)
void
proto_reg_handoff_smtp(void)
{
- dissector_handle_t smtp_handle;
-
smtp_handle = find_dissector("smtp");
dissector_add_uint("tcp.port", TCP_PORT_SMTP, smtp_handle);
ssl_dissector_add(TCP_PORT_SSL_SMTP, "smtp", TRUE);