From 458dcb7ea2271200494707361b06208daa160a47 Mon Sep 17 00:00:00 2001 From: Pascal Quantin Date: Tue, 18 Jun 2013 01:13:07 +0000 Subject: [PATCH] Add ability to export decrypted SSL/DTLS PDUs svn path=/trunk/; revision=50001 --- asn1/credssp/packet-credssp-template.c | 36 +++++++++++++------ epan/dissectors/packet-credssp.c | 46 +++++++++++++++++-------- epan/dissectors/packet-dtls.c | 19 ++++++++-- epan/dissectors/packet-reload-framing.c | 42 +++++++++++++++++++--- epan/dissectors/packet-ssl.c | 15 ++++++++ epan/packet.c | 10 ++++++ epan/packet.h | 3 ++ 7 files changed, 138 insertions(+), 33 deletions(-) diff --git a/asn1/credssp/packet-credssp-template.c b/asn1/credssp/packet-credssp-template.c index f4db923051..7feff0e3c3 100644 --- a/asn1/credssp/packet-credssp-template.c +++ b/asn1/credssp/packet-credssp-template.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include "packet-ber.h" #include "packet-credssp.h" @@ -41,6 +43,8 @@ #define TS_SMARTCARD_CREDS 2 static gint creds_type; +static gint exported_pdu_tap = -1; + /* Initialize the protocol and registered fields */ static int proto_credssp = -1; @@ -97,15 +101,27 @@ dissect_credssp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, offset = get_ber_length(tvb, offset, NULL, NULL); offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); if((ber_class == BER_CLASS_CON) && (tag == 0)) { - offset = get_ber_length(tvb, offset, NULL, NULL); - offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); - if((ber_class == BER_CLASS_UNI) && (tag == BER_UNI_TAG_INTEGER)) { - offset = get_ber_length(tvb, offset, &length, NULL); - if((length == 1) && (tvb_get_guint8(tvb, offset) == 2)) { - dissect_credssp(tvb, pinfo, parent_tree); - return TRUE; - } - } + offset = get_ber_length(tvb, offset, NULL, NULL); + offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); + if((ber_class == BER_CLASS_UNI) && (tag == BER_UNI_TAG_INTEGER)) { + offset = get_ber_length(tvb, offset, &length, NULL); + if((length == 1) && (tvb_get_guint8(tvb, offset) == 2)) { + if (have_tap_listener(exported_pdu_tap)) { + exp_pdu_data_t *exp_pdu_data; + + exp_pdu_data = load_export_pdu_tags(pinfo, "credssp", -1, + (EXP_PDU_TAG_IP_SRC_BIT | EXP_PDU_TAG_IP_DST_BIT | EXP_PDU_TAG_SRC_PORT_BIT | + EXP_PDU_TAG_DST_PORT_BIT | EXP_PDU_TAG_ORIG_FNO_BIT)); + + exp_pdu_data->tvb_length = tvb_length(tvb); + exp_pdu_data->pdu_tvb = tvb; + + tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data); + } + dissect_credssp(tvb, pinfo, parent_tree); + return TRUE; + } + } } } } @@ -159,6 +175,6 @@ void proto_register_credssp(void) { void proto_reg_handoff_credssp(void) { heur_dissector_add("ssl", dissect_credssp_heur, proto_credssp); - + exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_7); } diff --git a/epan/dissectors/packet-credssp.c b/epan/dissectors/packet-credssp.c index 52ac249e5e..357538e155 100644 --- a/epan/dissectors/packet-credssp.c +++ b/epan/dissectors/packet-credssp.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include "packet-ber.h" #include "packet-credssp.h" @@ -49,6 +51,8 @@ #define TS_SMARTCARD_CREDS 2 static gint creds_type; +static gint exported_pdu_tap = -1; + /* Initialize the protocol and registered fields */ static int proto_credssp = -1; @@ -84,7 +88,7 @@ static int hf_credssp_authInfo = -1; /* T_authInfo */ static int hf_credssp_pubKeyAuth = -1; /* OCTET_STRING */ /*--- End of included file: packet-credssp-hf.c ---*/ -#line 54 "../../asn1/credssp/packet-credssp-template.c" +#line 58 "../../asn1/credssp/packet-credssp-template.c" /* Initialize the subtree pointers */ static gint ett_credssp = -1; @@ -100,7 +104,7 @@ static gint ett_credssp_TSCredentials = -1; static gint ett_credssp_TSRequest = -1; /*--- End of included file: packet-credssp-ett.c ---*/ -#line 58 "../../asn1/credssp/packet-credssp-template.c" +#line 62 "../../asn1/credssp/packet-credssp-template.c" /*--- Included file: packet-credssp-fn.c ---*/ @@ -328,7 +332,7 @@ static void dissect_TSRequest_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, pro /*--- End of included file: packet-credssp-fn.c ---*/ -#line 60 "../../asn1/credssp/packet-credssp-template.c" +#line 64 "../../asn1/credssp/packet-credssp-template.c" /* * Dissect CredSSP PDUs @@ -369,15 +373,27 @@ dissect_credssp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, offset = get_ber_length(tvb, offset, NULL, NULL); offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); if((ber_class == BER_CLASS_CON) && (tag == 0)) { - offset = get_ber_length(tvb, offset, NULL, NULL); - offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); - if((ber_class == BER_CLASS_UNI) && (tag == BER_UNI_TAG_INTEGER)) { - offset = get_ber_length(tvb, offset, &length, NULL); - if((length == 1) && (tvb_get_guint8(tvb, offset) == 2)) { - dissect_credssp(tvb, pinfo, parent_tree); - return TRUE; - } - } + offset = get_ber_length(tvb, offset, NULL, NULL); + offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag); + if((ber_class == BER_CLASS_UNI) && (tag == BER_UNI_TAG_INTEGER)) { + offset = get_ber_length(tvb, offset, &length, NULL); + if((length == 1) && (tvb_get_guint8(tvb, offset) == 2)) { + if (have_tap_listener(exported_pdu_tap)) { + exp_pdu_data_t *exp_pdu_data; + + exp_pdu_data = load_export_pdu_tags(pinfo, "credssp", -1, + (EXP_PDU_TAG_IP_SRC_BIT | EXP_PDU_TAG_IP_DST_BIT | EXP_PDU_TAG_SRC_PORT_BIT | + EXP_PDU_TAG_DST_PORT_BIT | EXP_PDU_TAG_ORIG_FNO_BIT)); + + exp_pdu_data->tvb_length = tvb_length(tvb); + exp_pdu_data->pdu_tvb = tvb; + + tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data); + } + dissect_credssp(tvb, pinfo, parent_tree); + return TRUE; + } + } } } } @@ -492,7 +508,7 @@ void proto_register_credssp(void) { "OCTET_STRING", HFILL }}, /*--- End of included file: packet-credssp-hfarr.c ---*/ -#line 135 "../../asn1/credssp/packet-credssp-template.c" +#line 151 "../../asn1/credssp/packet-credssp-template.c" }; /* List of subtrees */ @@ -510,7 +526,7 @@ void proto_register_credssp(void) { &ett_credssp_TSRequest, /*--- End of included file: packet-credssp-ettarr.c ---*/ -#line 141 "../../asn1/credssp/packet-credssp-template.c" +#line 157 "../../asn1/credssp/packet-credssp-template.c" }; @@ -532,6 +548,6 @@ void proto_register_credssp(void) { void proto_reg_handoff_credssp(void) { heur_dissector_add("ssl", dissect_credssp_heur, proto_credssp); - + exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_7); } diff --git a/epan/dissectors/packet-dtls.c b/epan/dissectors/packet-dtls.c index c49da60595..1d3dfff439 100644 --- a/epan/dissectors/packet-dtls.c +++ b/epan/dissectors/packet-dtls.c @@ -65,6 +65,7 @@ #include #include #include +#include void proto_register_dtls(void); @@ -85,6 +86,7 @@ static proto_tree *top_tree; /* Initialize the protocol and registered fields */ static gint dtls_tap = -1; +static gint exported_pdu_tap = -1; static gint proto_dtls = -1; static gint hf_dtls_record = -1; static gint hf_dtls_record_content_type = -1; @@ -998,9 +1000,6 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo, /* show on info column what we are decoding */ col_append_str(pinfo->cinfo, COL_INFO, "Application Data"); - if (!dtls_record_tree) - break; - /* we need dissector information when the selected packet is shown. * ssl session pointer is NULL at that time, so we can't access * info cached there*/ @@ -1036,6 +1035,19 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo, ssl_debug_printf("dissect_dtls_record found association %p\n", (void *)association); ssl_print_data("decrypted app data",appl_data->plain_data.data, appl_data->plain_data.data_len); + if (have_tap_listener(exported_pdu_tap)) { + exp_pdu_data_t *exp_pdu_data; + + exp_pdu_data = load_export_pdu_tags(pinfo, dissector_handle_get_dissector_name(association->handle), -1, + (EXP_PDU_TAG_IP_SRC_BIT | EXP_PDU_TAG_IP_DST_BIT | EXP_PDU_TAG_SRC_PORT_BIT | + EXP_PDU_TAG_DST_PORT_BIT | EXP_PDU_TAG_ORIG_FNO_BIT)); + + exp_pdu_data->tvb_length = tvb_length(next_tvb); + exp_pdu_data->pdu_tvb = next_tvb; + + tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data); + } + dissected = call_dissector_only(association->handle, next_tvb, pinfo, top_tree, NULL); } else { @@ -3564,6 +3576,7 @@ proto_reg_handoff_dtls(void) /* add now dissector to default ports.*/ dtls_parse_uat(); dtls_parse_old_keys(); + exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_7); if (initialized == FALSE) { heur_dissector_add("udp", dissect_dtls_heur, proto_dtls); diff --git a/epan/dissectors/packet-reload-framing.c b/epan/dissectors/packet-reload-framing.c index 9626272398..7657c50894 100644 --- a/epan/dissectors/packet-reload-framing.c +++ b/epan/dissectors/packet-reload-framing.c @@ -31,6 +31,8 @@ #include #include +#include +#include #include /* Initialize the protocol and registered fields */ @@ -51,6 +53,8 @@ static int hf_reload_framing_time = -1; static dissector_handle_t reload_handle; +static gint exported_pdu_tap = -1; + /* Structure containing transaction specific information */ typedef struct _reload_frame_t { guint32 data_frame; @@ -106,7 +110,7 @@ get_reload_framing_message_length(packet_info *pinfo _U_, tvbuff_t *tvb, int off static int -dissect_reload_framing_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +dissect_reload_framing_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean from_dtls) { proto_item *ti; proto_tree *reload_framing_tree; @@ -167,6 +171,19 @@ dissect_reload_framing_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr return 0; } + if (from_dtls && have_tap_listener(exported_pdu_tap)) { + exp_pdu_data_t *exp_pdu_data; + + exp_pdu_data = load_export_pdu_tags(pinfo, "reload-framing", -1, + (EXP_PDU_TAG_IP_SRC_BIT | EXP_PDU_TAG_IP_DST_BIT | EXP_PDU_TAG_SRC_PORT_BIT | + EXP_PDU_TAG_DST_PORT_BIT | EXP_PDU_TAG_ORIG_FNO_BIT)); + + exp_pdu_data->tvb_length = effective_length; + exp_pdu_data->pdu_tvb = tvb; + + tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data); + } + /* The message seems to be a valid RELOAD framing message! */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "RELOAD Frame"); @@ -430,13 +447,13 @@ dissect_reload_framing_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr static int dissect_reload_framing_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { - return dissect_reload_framing_message(tvb, pinfo, tree); + return dissect_reload_framing_message(tvb, pinfo, tree, FALSE); } static void dissect_reload_framing_message_no_return(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - dissect_reload_framing_message(tvb, pinfo, tree); + dissect_reload_framing_message(tvb, pinfo, tree, FALSE); } static void @@ -455,7 +472,20 @@ dissect_reload_framing_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) static gboolean dissect_reload_framing_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { - if (dissect_reload_framing_message(tvb, pinfo, tree) == 0) { + if (dissect_reload_framing_message(tvb, pinfo, tree, FALSE) == 0) { + /* + * It wasn't a valid RELOAD message, and wasn't + * dissected as such. + */ + return FALSE; + } + return TRUE; +} + +static gboolean +dissect_reload_framing_heur_dtls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) +{ + if (dissect_reload_framing_message(tvb, pinfo, tree, TRUE) == 0) { /* * It wasn't a valid RELOAD message, and wasn't * dissected as such. @@ -575,7 +605,9 @@ proto_reg_handoff_reload_framing(void) heur_dissector_add("udp", dissect_reload_framing_heur, proto_reload_framing); heur_dissector_add("tcp", dissect_reload_framing_heur, proto_reload_framing); - heur_dissector_add("dtls", dissect_reload_framing_heur, proto_reload_framing); + heur_dissector_add("dtls", dissect_reload_framing_heur_dtls, proto_reload_framing); + + exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_7); } /* diff --git a/epan/dissectors/packet-ssl.c b/epan/dissectors/packet-ssl.c index e8ed1817f7..8f38d451b9 100644 --- a/epan/dissectors/packet-ssl.c +++ b/epan/dissectors/packet-ssl.c @@ -110,6 +110,7 @@ #include "packet-ssl-utils.h" #include #include +#include static ssldecrypt_assoc_t *sslkeylist_uats = NULL; static guint nssldecrypt = 0; @@ -128,6 +129,7 @@ gboolean ssl_ignore_mac_failed = FALSE; /* Initialize the protocol and registered fields */ static gint ssl_tap = -1; +static gint exported_pdu_tap = -1; static gint proto_ssl = -1; static gint hf_ssl_record = -1; static gint hf_ssl_record_content_type = -1; @@ -1387,6 +1389,18 @@ process_ssl_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo, if (dissector_try_heuristic(ssl_heur_subdissector_list, next_tvb, pinfo, proto_tree_get_root(tree), NULL)) { } else { + if (have_tap_listener(exported_pdu_tap)) { + exp_pdu_data_t *exp_pdu_data; + + exp_pdu_data = load_export_pdu_tags(pinfo, dissector_handle_get_dissector_name(association->handle), -1, + (EXP_PDU_TAG_IP_SRC_BIT | EXP_PDU_TAG_IP_DST_BIT | EXP_PDU_TAG_SRC_PORT_BIT | + EXP_PDU_TAG_DST_PORT_BIT | EXP_PDU_TAG_ORIG_FNO_BIT)); + + exp_pdu_data->tvb_length = tvb_length(next_tvb); + exp_pdu_data->pdu_tvb = next_tvb; + + tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data); + } call_dissector(association->handle, next_tvb, pinfo, proto_tree_get_root(tree)); } } @@ -6000,6 +6014,7 @@ proto_reg_handoff_ssl(void) /* parse key list */ ssl_parse_uat(); ssl_parse_old_keys(); + exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_7); } void diff --git a/epan/packet.c b/epan/packet.c index c8e85cdc17..ef62e803c2 100644 --- a/epan/packet.c +++ b/epan/packet.c @@ -1972,6 +1972,16 @@ find_dissector(const char *name) return (dissector_handle_t)g_hash_table_lookup(registered_dissectors, name); } +/* Get a dissector name from handle. */ +const char * +dissector_handle_get_dissector_name(const dissector_handle_t handle) +{ + if (handle == NULL) { + return NULL; + } + return handle->name; +} + /* Create an anonymous handle for a dissector. */ dissector_handle_t create_dissector_handle(dissector_t dissector, const int proto) diff --git a/epan/packet.h b/epan/packet.h index 449389029a..a1d3c5a6f6 100644 --- a/epan/packet.h +++ b/epan/packet.h @@ -321,6 +321,9 @@ WS_DLL_PUBLIC int dissector_handle_get_protocol_index(const dissector_handle_t h /* Find a dissector by name. */ WS_DLL_PUBLIC dissector_handle_t find_dissector(const char *name); +/* Get a dissector name from handle. */ +WS_DLL_PUBLIC const char *dissector_handle_get_dissector_name(const dissector_handle_t handle); + /* Create an anonymous handle for a dissector. */ WS_DLL_PUBLIC dissector_handle_t create_dissector_handle(dissector_t dissector, const int proto);