diff options
author | Peter Wu <peter@lekensteyn.nl> | 2015-02-06 12:31:46 +0100 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2015-02-09 16:26:28 +0000 |
commit | 2078a95e934cf1063f2525a93b5f81ddb7b43e77 (patch) | |
tree | 033b7dd37e708240a99ee1e2d7e97ad0f9424418 /epan/dissectors/packet-pgsql.c | |
parent | a58cf528fcb35e6e07b91a899860621e7d6925e2 (diff) |
pgsql,imap: add STARTTLS support
The PGSQL "STARTTLS" protocol is documented at
http://www.postgresql.org/docs/9.4/static/protocol-flow.html
While at it, convert some tvb_length[_remaining] users.
Tested against pgsql-ssl.pcapng,
Tested against imap-ssl.pcapng,
http://wiki.wireshark.org/SampleCaptures#SSL_with_decryption_keys
Change-Id: I1a00a6daa7f03de93339c2c13b07b4cfb8cdbd86
Reviewed-on: https://code.wireshark.org/review/6821
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan/dissectors/packet-pgsql.c')
-rw-r--r-- | epan/dissectors/packet-pgsql.c | 59 |
1 files changed, 48 insertions, 11 deletions
diff --git a/epan/dissectors/packet-pgsql.c b/epan/dissectors/packet-pgsql.c index 1ac35b151d..343cd4ca2a 100644 --- a/epan/dissectors/packet-pgsql.c +++ b/epan/dissectors/packet-pgsql.c @@ -27,11 +27,15 @@ #include <epan/packet.h> #include <epan/prefs.h> +#include "packet-ssl-utils.h" #include "packet-tcp.h" void proto_register_pgsql(void); void proto_reg_handoff_pgsql(void); +static dissector_handle_t pgsql_handle; +static dissector_handle_t ssl_handle; + static int proto_pgsql = -1; static int hf_frontend = -1; static int hf_type = -1; @@ -88,6 +92,10 @@ static guint pgsql_port = 5432; static gboolean pgsql_desegment = TRUE; static gboolean first_message = TRUE; +typedef struct pgsql_conn_data { + gboolean ssl_requested; +} pgsql_conn_data_t; + static const value_string fe_messages[] = { { 'p', "Password message" }, { 'Q', "Simple query" }, @@ -158,7 +166,8 @@ static const value_string format_vals[] = { }; static void dissect_pgsql_fe_msg(guchar type, guint length, tvbuff_t *tvb, - gint n, proto_tree *tree) + gint n, proto_tree *tree, + pgsql_conn_data_t *conv_data) { guchar c; gint i, siz; @@ -291,8 +300,8 @@ static void dissect_pgsql_fe_msg(guchar type, guint length, tvbuff_t *tvb, /* SSL request */ case 80877103: - /* There's nothing to parse here, but what do we do if the - SSL negotiation succeeds? */ + /* Next reply will be a single byte. */ + conv_data->ssl_requested = TRUE; break; /* Cancellation request */ @@ -551,6 +560,8 @@ dissect_pgsql_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat { proto_item *ti, *hidden_item; proto_tree *ptree; + conversation_t *conversation; + pgsql_conn_data_t *conn_data; gint n; guchar type; @@ -558,6 +569,14 @@ dissect_pgsql_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat guint length; gboolean fe = (pinfo->match_uint == pinfo->destport); + conversation = find_or_create_conversation(pinfo); + conn_data = (pgsql_conn_data_t *)conversation_get_proto_data(conversation, proto_pgsql); + if (!conn_data) { + conn_data = wmem_new(wmem_file_scope(), pgsql_conn_data_t); + conn_data->ssl_requested = FALSE; + conversation_add_proto_data(conversation, proto_pgsql, conn_data); + } + n = 0; type = tvb_get_guint8(tvb, 0); if (type != '\0') @@ -596,7 +615,7 @@ dissect_pgsql_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat ( first_message ? "" : "/" ), type); first_message = FALSE; - if (tree) { + { ti = proto_tree_add_item(tree, proto_pgsql, tvb, 0, -1, ENC_NA); ptree = proto_item_add_subtree(ti, ett_pgsql); @@ -610,12 +629,12 @@ dissect_pgsql_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat n += 4; if (fe) - dissect_pgsql_fe_msg(type, length, tvb, n, ptree); + dissect_pgsql_fe_msg(type, length, tvb, n, ptree, conn_data); else dissect_pgsql_be_msg(type, length, tvb, n, ptree); } - return tvb_length(tvb); + return tvb_captured_length(tvb); } /* This function is called once per TCP packet. It sets COL_PROTOCOL and @@ -625,21 +644,38 @@ dissect_pgsql_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat static int dissect_pgsql(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) { - /* conversation_t *cv; */ + conversation_t *conversation; + pgsql_conn_data_t *conn_data; first_message = TRUE; - /* We don't use conversation data yet, but... */ - /* cv = find_or_create_conversation(pinfo); */ + conversation = find_or_create_conversation(pinfo); + conn_data = (pgsql_conn_data_t *)conversation_get_proto_data(conversation, proto_pgsql); col_set_str(pinfo->cinfo, COL_PROTOCOL, "PGSQL"); col_set_str(pinfo->cinfo, COL_INFO, (pinfo->match_uint == pinfo->destport) ? ">" : "<"); + if (conn_data && conn_data->ssl_requested) { + /* Response to SSLRequest. */ + switch (tvb_get_guint8(tvb, 0)) { + case 'S': /* Willing to perform SSL */ + /* Next packet will start using SSL. */ + ssl_starttls_ack(ssl_handle, pinfo, pgsql_handle); + break; + case 'N': /* Unwilling to perform SSL */ + default: /* ErrorMessage when server does not support SSL. */ + /* TODO: maybe add expert info here? */ + break; + } + conn_data->ssl_requested = FALSE; + return tvb_captured_length(tvb); + } + tcp_dissect_pdus(tvb, pinfo, tree, pgsql_desegment, 5, pgsql_length, dissect_pgsql_msg, data); - return tvb_length(tvb); + return tvb_captured_length(tvb); } void @@ -865,7 +901,6 @@ void proto_reg_handoff_pgsql(void) { static gboolean initialized = FALSE; - static dissector_handle_t pgsql_handle; static guint saved_pgsql_port; if (!initialized) { @@ -877,6 +912,8 @@ proto_reg_handoff_pgsql(void) dissector_add_uint("tcp.port", pgsql_port, pgsql_handle); saved_pgsql_port = pgsql_port; + + ssl_handle = find_dissector("ssl"); } /* |