aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2015-11-05 23:20:45 -0500
committerMichael Mann <mmann78@netscape.net>2015-11-07 14:11:01 +0000
commit3aefd3b5b2a64f5da9670e28af4bb409fff3fcd1 (patch)
tree819f6a9594023280d3593d61813a23d52bec2eaa /epan
parentb56d323412306604b1d2a42943d170258476931a (diff)
Create real dissector tables for SSL and DTLS to use.
Since ssl_dissector_[add|delete] only take TCP dissectors, remove the parameter and just use it within the "internal" ssl_association_add call. Change-Id: I0fdf941389934c20cbacf910250e17520614e706 Reviewed-on: https://code.wireshark.org/review/11591 Petri-Dish: Michael Mann <mmann78@netscape.net> Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-amqp.c4
-rw-r--r--epan/dissectors/packet-dtls.c69
-rw-r--r--epan/dissectors/packet-h225.c7
-rw-r--r--epan/dissectors/packet-http.c4
-rw-r--r--epan/dissectors/packet-imap.c2
-rw-r--r--epan/dissectors/packet-ldap.c4
-rw-r--r--epan/dissectors/packet-pop.c2
-rw-r--r--epan/dissectors/packet-sip.c4
-rw-r--r--epan/dissectors/packet-skinny.c2
-rw-r--r--epan/dissectors/packet-skinny.c.in2
-rw-r--r--epan/dissectors/packet-smtp.c2
-rw-r--r--epan/dissectors/packet-spdy.c2
-rw-r--r--epan/dissectors/packet-ssl-utils.c156
-rw-r--r--epan/dissectors/packet-ssl-utils.h27
-rw-r--r--epan/dissectors/packet-ssl.c121
-rw-r--r--epan/dissectors/packet-ssl.h7
16 files changed, 195 insertions, 220 deletions
diff --git a/epan/dissectors/packet-amqp.c b/epan/dissectors/packet-amqp.c
index 9b7eab4262..1d17d7501a 100644
--- a/epan/dissectors/packet-amqp.c
+++ b/epan/dissectors/packet-amqp.c
@@ -14012,12 +14012,12 @@ proto_reg_handoff_amqp(void)
/* Register for TLS/SSL payload dissection */
if (old_amqps_port != 0 && old_amqps_port != amqps_port){
- ssl_dissector_delete(old_amqps_port, "amqp", TRUE);
+ ssl_dissector_delete(old_amqps_port, amqp_tcp_handle);
}
if (amqps_port != 0 && old_amqps_port != amqps_port) {
old_amqps_port = amqps_port;
- ssl_dissector_add(amqps_port, "amqp", TRUE);
+ ssl_dissector_add(amqps_port, amqp_tcp_handle);
}
}
diff --git a/epan/dissectors/packet-dtls.c b/epan/dissectors/packet-dtls.c
index 900aed3b09..3f02c7b7eb 100644
--- a/epan/dissectors/packet-dtls.c
+++ b/epan/dissectors/packet-dtls.c
@@ -136,8 +136,9 @@ static expert_field ei_dtls_heartbeat_payload_length = EI_INIT;
static ssl_master_key_map_t dtls_master_key_map;
static GHashTable *dtls_key_hash = NULL;
+static wmem_stack_t *key_list_stack = NULL;
static reassembly_table dtls_reassembly_table;
-static GTree* dtls_associations = NULL;
+static dissector_table_t dtls_associations = NULL;
static dissector_handle_t dtls_handle = NULL;
static StringInfo dtls_compressed_data = {NULL, 0};
static StringInfo dtls_decrypted_data = {NULL, 0};
@@ -201,6 +202,10 @@ dtls_init(void)
static void
dtls_cleanup(void)
{
+ if (key_list_stack != NULL) {
+ wmem_destroy_stack(key_list_stack);
+ key_list_stack = NULL;
+ }
reassembly_table_destroy(&dtls_reassembly_table);
ssl_common_cleanup(&dtls_master_key_map, &dtls_keylog_file,
&dtls_decrypted_data, &dtls_compressed_data);
@@ -210,8 +215,8 @@ dtls_cleanup(void)
static void
dtls_parse_uat(void)
{
- wmem_stack_t *tmp_stack;
- guint i;
+ guint i, port;
+ dissector_handle_t handle;
if (dtls_key_hash)
{
@@ -219,12 +224,14 @@ dtls_parse_uat(void)
}
/* remove only associations created from key list */
- tmp_stack = wmem_stack_new(NULL);
- g_tree_foreach(dtls_associations, ssl_assoc_from_key_list, tmp_stack);
- while (wmem_stack_count(tmp_stack) > 0) {
- ssl_association_remove(dtls_associations, (SslAssociation *)wmem_stack_pop(tmp_stack));
+ if (key_list_stack != NULL) {
+ while (wmem_stack_count(key_list_stack) > 0) {
+ port = GPOINTER_TO_UINT(wmem_stack_pop(key_list_stack));
+ handle = dissector_get_uint_handle(dtls_associations, port);
+ if (handle != NULL)
+ ssl_association_remove("dtls.port", dtls_handle, handle, port, FALSE);
+ }
}
- wmem_destroy_stack(tmp_stack);
/* parse private keys string, load available keys and put them in key hash*/
dtls_key_hash = g_hash_table_new_full(ssl_private_key_hash,
@@ -234,10 +241,15 @@ dtls_parse_uat(void)
if (ndtlsdecrypt > 0)
{
+ if (key_list_stack == NULL)
+ key_list_stack = wmem_stack_new(NULL);
+
for (i = 0; i < ndtlsdecrypt; i++)
{
ssldecrypt_assoc_t *d = &(dtlskeylist_uats[i]);
- ssl_parse_key_list(d, dtls_key_hash, dtls_associations, dtls_handle, FALSE);
+ ssl_parse_key_list(d, dtls_key_hash, "dtls.port", dtls_handle, FALSE);
+ if (key_list_stack)
+ wmem_stack_push(key_list_stack, GUINT_TO_POINTER(atoi(d->port)));
}
}
@@ -869,10 +881,10 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo,
if (!session->app_handle) {
/* Unknown protocol handle, ssl_starttls_ack was not called before.
* Try to find an appropriate dissection handle and cache it. */
- SslAssociation *association;
- association = ssl_association_find(dtls_associations, pinfo->srcport, pinfo->ptype == PT_TCP);
- association = association ? association : ssl_association_find(dtls_associations, pinfo->destport, pinfo->ptype == PT_TCP);
- if (association) session->app_handle = association->handle;
+ dissector_handle_t handle;
+ handle = dissector_get_uint_handle(dtls_associations, pinfo->srcport);
+ handle = handle ? handle : dissector_get_uint_handle(dtls_associations, pinfo->destport);
+ if (handle) session->app_handle = handle;
}
proto_item_set_text(dtls_record_tree,
@@ -1622,6 +1634,31 @@ UAT_CSTRING_CB_DEF(sslkeylist_uats,port,ssldecrypt_assoc_t)
UAT_CSTRING_CB_DEF(sslkeylist_uats,protocol,ssldecrypt_assoc_t)
UAT_FILENAME_CB_DEF(sslkeylist_uats,keyfile,ssldecrypt_assoc_t)
UAT_CSTRING_CB_DEF(sslkeylist_uats,password,ssldecrypt_assoc_t)
+
+static gboolean
+dtlsdecrypt_uat_fld_protocol_chk_cb(void* r _U_, const char* p, guint len _U_, const void* u1 _U_, const void* u2 _U_, char** err)
+{
+ if (!p || strlen(p) == 0u) {
+ *err = g_strdup_printf("No protocol given.");
+ return FALSE;
+ }
+
+ if (!find_dissector(p)) {
+ if (proto_get_id_by_filter_name(p) != -1) {
+ *err = g_strdup_printf("While '%s' is a valid dissector filter name, that dissector is not configured"
+ " to support DTLS decryption.\n\n"
+ "If you need to decrypt '%s' over DTLS, please contact the Wireshark development team.", p, p);
+ } else {
+ char* ssl_str = ssl_association_info("dtls.port", "UDP");
+ *err = g_strdup_printf("Could not find dissector for: '%s'\nCommonly used DTLS dissectors include:\n%s", p, ssl_str);
+ g_free(ssl_str);
+ }
+ return FALSE;
+ }
+
+ *err = NULL;
+ return TRUE;
+}
#endif
void proto_reg_handoff_dtls(void);
@@ -1823,6 +1860,8 @@ proto_register_dtls(void)
proto_dtls = proto_register_protocol("Datagram Transport Layer Security",
"DTLS", "dtls");
+ dtls_associations = register_dissector_table("dtls.port", "DTLS UDP Dissector", FT_UINT16, BASE_DEC, DISSECTOR_TABLE_NOT_ALLOW_DUPLICATE);
+
/* Required function calls to register the header fields and
* subtrees used */
proto_register_field_array(proto_dtls, hf, array_length(hf));
@@ -1838,7 +1877,7 @@ proto_register_dtls(void)
static uat_field_t dtlskeylist_uats_flds[] = {
UAT_FLD_CSTRING_OTHER(sslkeylist_uats, ipaddr, "IP address", ssldecrypt_uat_fld_ip_chk_cb, "IPv4 or IPv6 address"),
UAT_FLD_CSTRING_OTHER(sslkeylist_uats, port, "Port", ssldecrypt_uat_fld_port_chk_cb, "Port Number"),
- UAT_FLD_CSTRING_OTHER(sslkeylist_uats, protocol, "Protocol", ssldecrypt_uat_fld_protocol_chk_cb, "Protocol"),
+ UAT_FLD_CSTRING_OTHER(sslkeylist_uats, protocol, "Protocol", dtlsdecrypt_uat_fld_protocol_chk_cb, "Protocol"),
UAT_FLD_FILENAME_OTHER(sslkeylist_uats, keyfile, "Key File", ssldecrypt_uat_fld_fileopen_chk_cb, "Path to the keyfile."),
UAT_FLD_CSTRING_OTHER(sslkeylist_uats, password," Password (p12 file)", ssldecrypt_uat_fld_password_chk_cb, "Password"),
UAT_END_FIELDS
@@ -1880,8 +1919,6 @@ proto_register_dtls(void)
register_dissector("dtls", dissect_dtls, proto_dtls);
dtls_handle = find_dissector("dtls");
- dtls_associations = g_tree_new(ssl_association_cmp);
-
register_init_routine(dtls_init);
register_cleanup_routine(dtls_cleanup);
dtls_tap = register_tap("dtls");
diff --git a/epan/dissectors/packet-h225.c b/epan/dissectors/packet-h225.c
index 867bf8da33..cf611e473a 100644
--- a/epan/dissectors/packet-h225.c
+++ b/epan/dissectors/packet-h225.c
@@ -11691,7 +11691,7 @@ void
proto_reg_handoff_h225(void)
{
static gboolean h225_prefs_initialized = FALSE;
- static dissector_handle_t h225ras_handle;
+ static dissector_handle_t h225ras_handle, q931_tpkt_handle;
static guint saved_h225_tls_port;
if (!h225_prefs_initialized) {
@@ -11704,12 +11704,13 @@ proto_reg_handoff_h225(void)
h4501_handle = find_dissector("h4501");
data_handle = find_dissector("data");
h225_prefs_initialized = TRUE;
+ q931_tpkt_handle = find_dissector("q931.tpkt");
} else {
- ssl_dissector_delete(saved_h225_tls_port, "q931.tpkt", TRUE);
+ ssl_dissector_delete(saved_h225_tls_port, q931_tpkt_handle);
}
saved_h225_tls_port = h225_tls_port;
- ssl_dissector_add(saved_h225_tls_port, "q931.tpkt", TRUE);
+ ssl_dissector_add(saved_h225_tls_port, q931_tpkt_handle);
}
diff --git a/epan/dissectors/packet-http.c b/epan/dissectors/packet-http.c
index 695ba6eabc..6e57020286 100644
--- a/epan/dissectors/packet-http.c
+++ b/epan/dissectors/packet-http.c
@@ -2994,12 +2994,12 @@ dissect_ssdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static void
range_delete_http_ssl_callback(guint32 port) {
- ssl_dissector_delete(port, "http", TRUE);
+ ssl_dissector_delete(port, http_handle);
}
static void
range_add_http_ssl_callback(guint32 port) {
- ssl_dissector_add(port, "http", TRUE);
+ ssl_dissector_add(port, http_handle);
}
static void reinit_http(void) {
diff --git a/epan/dissectors/packet-imap.c b/epan/dissectors/packet-imap.c
index a95da306f4..9673f6b149 100644
--- a/epan/dissectors/packet-imap.c
+++ b/epan/dissectors/packet-imap.c
@@ -359,7 +359,7 @@ void
proto_reg_handoff_imap(void)
{
dissector_add_uint("tcp.port", TCP_PORT_IMAP, imap_handle);
- ssl_dissector_add(TCP_PORT_SSL_IMAP, "imap", TRUE);
+ ssl_dissector_add(TCP_PORT_SSL_IMAP, imap_handle);
ssl_handle = find_dissector("ssl");
}
/*
diff --git a/epan/dissectors/packet-ldap.c b/epan/dissectors/packet-ldap.c
index fe26c37390..025f3f89f7 100644
--- a/epan/dissectors/packet-ldap.c
+++ b/epan/dissectors/packet-ldap.c
@@ -5964,13 +5964,13 @@ prefs_register_ldap(void)
if(ssl_port != global_ldaps_tcp_port) {
if(ssl_port)
- ssl_dissector_delete(ssl_port, "ldap", TRUE);
+ ssl_dissector_delete(ssl_port, ldap_handle);
/* Set our port number for future use */
ssl_port = global_ldaps_tcp_port;
if(ssl_port)
- ssl_dissector_add(ssl_port, "ldap", TRUE);
+ ssl_dissector_add(ssl_port, ldap_handle);
}
}
diff --git a/epan/dissectors/packet-pop.c b/epan/dissectors/packet-pop.c
index a90c44eb28..2d7bbbd028 100644
--- a/epan/dissectors/packet-pop.c
+++ b/epan/dissectors/packet-pop.c
@@ -468,7 +468,7 @@ proto_reg_handoff_pop(void)
{
pop_handle = find_dissector("pop");
dissector_add_uint("tcp.port", TCP_PORT_POP, pop_handle);
- ssl_dissector_add(TCP_PORT_SSL_POP, "pop", TRUE);
+ ssl_dissector_add(TCP_PORT_SSL_POP, pop_handle);
data_handle = find_dissector("data");
/* find the IMF dissector */
diff --git a/epan/dissectors/packet-sip.c b/epan/dissectors/packet-sip.c
index 08a70181fc..a41df2b21d 100644
--- a/epan/dissectors/packet-sip.c
+++ b/epan/dissectors/packet-sip.c
@@ -6453,13 +6453,13 @@ proto_reg_handoff_sip(void)
} else {
dissector_delete_uint_range("tcp.port", sip_tcp_port_range, sip_tcp_handle);
g_free(sip_tcp_port_range);
- ssl_dissector_delete(saved_sip_tls_port, "sip.tcp", TRUE);
+ ssl_dissector_delete(saved_sip_tls_port, sip_tcp_handle);
}
/* Set our port number for future use */
sip_tcp_port_range = range_copy(global_sip_tcp_port_range);
dissector_add_uint_range("tcp.port", sip_tcp_port_range, sip_tcp_handle);
saved_sip_tls_port = sip_tls_port;
- ssl_dissector_add(saved_sip_tls_port, "sip.tcp", TRUE);
+ ssl_dissector_add(saved_sip_tls_port, sip_tcp_handle);
exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_7);
}
diff --git a/epan/dissectors/packet-skinny.c b/epan/dissectors/packet-skinny.c
index 9883ee8c27..01f79cdbf8 100644
--- a/epan/dissectors/packet-skinny.c
+++ b/epan/dissectors/packet-skinny.c
@@ -9732,7 +9732,7 @@ proto_reg_handoff_skinny(void)
/* Skinny content type and internet media type used by other dissectors are the same */
media_type_dissector_table = find_dissector_table("media_type");
dissector_add_uint("tcp.port", TCP_PORT_SKINNY, skinny_handle);
- ssl_dissector_add(SSL_PORT_SKINNY, "skinny", TRUE);
+ ssl_dissector_add(SSL_PORT_SKINNY, skinny_handle);
}
/*
diff --git a/epan/dissectors/packet-skinny.c.in b/epan/dissectors/packet-skinny.c.in
index 464cd4b076..8d09e9352c 100644
--- a/epan/dissectors/packet-skinny.c.in
+++ b/epan/dissectors/packet-skinny.c.in
@@ -543,7 +543,7 @@ proto_reg_handoff_skinny(void)
/* Skinny content type and internet media type used by other dissectors are the same */
media_type_dissector_table = find_dissector_table("media_type");
dissector_add_uint("tcp.port", TCP_PORT_SKINNY, skinny_handle);
- ssl_dissector_add(SSL_PORT_SKINNY, "skinny", TRUE);
+ ssl_dissector_add(SSL_PORT_SKINNY, skinny_handle);
}
/*
diff --git a/epan/dissectors/packet-smtp.c b/epan/dissectors/packet-smtp.c
index d428c40e41..d8621300d5 100644
--- a/epan/dissectors/packet-smtp.c
+++ b/epan/dissectors/packet-smtp.c
@@ -1298,7 +1298,7 @@ proto_reg_handoff_smtp(void)
{
smtp_handle = find_dissector("smtp");
dissector_add_uint("tcp.port", TCP_PORT_SMTP, smtp_handle);
- ssl_dissector_add(TCP_PORT_SSL_SMTP, "smtp", TRUE);
+ ssl_dissector_add(TCP_PORT_SSL_SMTP, smtp_handle);
dissector_add_uint("tcp.port", TCP_PORT_SUBMISSION, smtp_handle);
/* find the IMF dissector */
diff --git a/epan/dissectors/packet-spdy.c b/epan/dissectors/packet-spdy.c
index e79b100e40..98d81364a7 100644
--- a/epan/dissectors/packet-spdy.c
+++ b/epan/dissectors/packet-spdy.c
@@ -1940,7 +1940,7 @@ void proto_reg_handoff_spdy(void) {
dissector_add_uint("tcp.port", TCP_PORT_SPDY, spdy_handle);
/* Use "0" to avoid overwriting HTTPS port and still offer support over SSL */
- ssl_dissector_add(0, "spdy", TRUE);
+ ssl_dissector_add(0, spdy_handle);
data_handle = find_dissector("data");
media_handle = find_dissector("media");
diff --git a/epan/dissectors/packet-ssl-utils.c b/epan/dissectors/packet-ssl-utils.c
index 41a021edb7..9aceb8eb38 100644
--- a/epan/dissectors/packet-ssl-utils.c
+++ b/epan/dissectors/packet-ssl-utils.c
@@ -4137,82 +4137,37 @@ ssl_private_key_hash (gconstpointer v)
/* Handling of association between tls/dtls ports and clear text protocol. {{{ */
void
-ssl_association_add(GTree* associations, dissector_handle_t handle, guint port, const gchar *protocol, gboolean tcp, gboolean from_key_list)
+ssl_association_add(const char* dissector_table_name, dissector_handle_t main_handle, dissector_handle_t subdissector_handle, guint port, gboolean tcp)
{
+ DISSECTOR_ASSERT(main_handle);
+ DISSECTOR_ASSERT(subdissector_handle);
+ ssl_debug_printf("association_add %s port %d handle %p\n", dissector_table_name, port, (void *)subdissector_handle);
- SslAssociation* assoc;
- assoc = (SslAssociation *)g_malloc(sizeof(SslAssociation));
-
- assoc->tcp = tcp;
- assoc->ssl_port = port;
- assoc->info=g_strdup(protocol);
- assoc->handle = find_dissector(protocol);
- assoc->from_key_list = from_key_list;
-
- ssl_debug_printf("association_add %s port %d protocol %s handle %p\n",
- (assoc->tcp)?"TCP":"UDP", port, protocol, (void *)(assoc->handle));
-
-
- if (!assoc->handle) {
- ssl_debug_printf("association_add could not find handle for protocol '%s', try to find 'data' dissector\n", protocol);
- assoc->handle = find_dissector("data");
- }
-
- DISSECTOR_ASSERT(assoc->handle != NULL);
if (port) {
+ dissector_add_uint(dissector_table_name, port, subdissector_handle);
if (tcp)
- dissector_add_uint("tcp.port", port, handle);
+ dissector_add_uint("tcp.port", port, main_handle);
else
- dissector_add_uint("udp.port", port, handle);
- dissector_add_uint("sctp.port", port, handle);
+ dissector_add_uint("udp.port", port, main_handle);
+ dissector_add_uint("sctp.port", port, main_handle);
+ } else {
+ dissector_add_for_decode_as(dissector_table_name, subdissector_handle);
}
- g_tree_insert(associations, assoc, assoc);
}
void
-ssl_association_remove(GTree* associations, SslAssociation *assoc)
+ssl_association_remove(const char* dissector_table_name, dissector_handle_t main_handle, dissector_handle_t subdissector_handle, guint port, gboolean tcp)
{
- ssl_debug_printf("ssl_association_remove removing %s %u - %s handle %p\n",
- (assoc->tcp)?"TCP":"UDP", assoc->ssl_port, assoc->info, (void *)(assoc->handle));
- if (assoc->handle) {
- dissector_delete_uint((assoc->tcp)?"tcp.port":"udp.port", assoc->ssl_port, assoc->handle);
- dissector_delete_uint("sctp.port", assoc->ssl_port, assoc->handle);
+ ssl_debug_printf("ssl_association_remove removing %s %u - handle %p\n",
+ tcp?"TCP":"UDP", port, (void *)subdissector_handle);
+ if (main_handle) {
+ dissector_delete_uint(tcp?"tcp.port":"udp.port", port, main_handle);
+ dissector_delete_uint("sctp.port", port, main_handle);
}
- g_free(assoc->info);
-
- g_tree_remove(associations, assoc);
- g_free(assoc);
-}
-
-gint
-ssl_association_cmp(gconstpointer a, gconstpointer b)
-{
- const SslAssociation *assoc_a=(const SslAssociation *)a, *assoc_b=(const SslAssociation *)b;
- if (assoc_a->tcp != assoc_b->tcp) return (assoc_a->tcp)?1:-1;
- return assoc_a->ssl_port - assoc_b->ssl_port;
-}
-
-SslAssociation*
-ssl_association_find(GTree * associations, guint port, gboolean tcp)
-{
- register SslAssociation* ret;
- SslAssociation assoc_tmp;
-
- assoc_tmp.tcp = tcp;
- assoc_tmp.ssl_port = port;
- ret = (SslAssociation *)g_tree_lookup(associations, &assoc_tmp);
-
- ssl_debug_printf("association_find: %s port %d found %p\n", (tcp)?"TCP":"UDP", port, (void *)ret);
- return ret;
-}
-
-gint
-ssl_assoc_from_key_list(gpointer key _U_, gpointer data, gpointer user_data)
-{
- if (((SslAssociation*)data)->from_key_list)
- wmem_stack_push((wmem_stack_t*)user_data, data);
- return FALSE;
+ if (port) {
+ dissector_delete_uint(dissector_table_name, port, subdissector_handle);
+ }
}
void
@@ -4224,7 +4179,7 @@ ssl_set_server(SslSession *session, address *addr, port_type ptype, guint32 port
}
int
-ssl_packet_from_server(SslSession *session, GTree *associations, packet_info *pinfo)
+ssl_packet_from_server(SslSession *session, dissector_table_t table, packet_info *pinfo)
{
gint ret;
if (session->srv_ptype != PT_NONE) {
@@ -4232,7 +4187,7 @@ ssl_packet_from_server(SslSession *session, GTree *associations, packet_info *pi
(session->srv_port == pinfo->srcport) &&
addresses_equal(&session->srv_addr, &pinfo->src);
} else {
- ret = ssl_association_find(associations, pinfo->srcport, pinfo->ptype != PT_UDP) != 0;
+ ret = (dissector_get_uint_handle(table, pinfo->srcport) != 0);
}
ssl_debug_printf("packet_from_server: is from server - %s\n", (ret)?"TRUE":"FALSE");
@@ -4382,7 +4337,7 @@ ssl_common_cleanup(ssl_master_key_map_t *mk_map, FILE **ssl_keylog_file,
#if defined(HAVE_LIBGNUTLS) && defined(HAVE_LIBGCRYPT)
/* Load a single RSA key file item from preferences. {{{ */
void
-ssl_parse_key_list(const ssldecrypt_assoc_t *uats, GHashTable *key_hash, GTree* associations, dissector_handle_t handle, gboolean tcp)
+ssl_parse_key_list(const ssldecrypt_assoc_t *uats, GHashTable *key_hash, const char* dissector_table_name, dissector_handle_t main_handle, gboolean tcp)
{
gnutls_x509_privkey_t priv_key;
gcry_sexp_t private_key;
@@ -4390,7 +4345,7 @@ ssl_parse_key_list(const ssldecrypt_assoc_t *uats, GHashTable *key_hash, GTree*
int ret;
size_t key_id_len = 20;
guchar *key_id = NULL;
-
+ dissector_handle_t handle;
/* try to load keys file first */
fp = ws_fopen(uats->keyfile, "rb");
if (!fp) {
@@ -4439,7 +4394,9 @@ ssl_parse_key_list(const ssldecrypt_assoc_t *uats, GHashTable *key_hash, GTree*
int port = atoi(uats->port); /* Also maps "start_tls" -> 0 (wildcard) */
ssl_debug_printf("ssl_init port '%d' filename '%s' password(only for p12 file) '%s'\n",
port, uats->keyfile, uats->password);
- ssl_association_add(associations, handle, port, uats->protocol, tcp, TRUE);
+
+ handle = find_dissector(uats->protocol);
+ ssl_association_add(dissector_table_name, main_handle, handle, port, tcp);
}
end:
@@ -4449,7 +4406,7 @@ end:
/* }}} */
#else
void
-ssl_parse_key_list(const ssldecrypt_assoc_t *uats _U_, GHashTable *key_hash _U_, GTree* associations _U_, dissector_handle_t handle _U_, gboolean tcp _U_)
+ssl_parse_key_list(const ssldecrypt_assoc_t *uats _U_, GHashTable *key_hash _U_, const char* dissector_table_name _U_, dissector_handle_t main_handle _U_, gboolean tcp _U_)
{
report_failure("Can't load private key files, support is not compiled in.");
}
@@ -4894,31 +4851,6 @@ ssldecrypt_uat_fld_port_chk_cb(void* r _U_, const char* p, guint len _U_, const
}
gboolean
-ssldecrypt_uat_fld_protocol_chk_cb(void* r _U_, const char* p, guint len _U_, const void* u1 _U_, const void* u2 _U_, char** err)
-{
- if (!p || strlen(p) == 0u) {
- *err = g_strdup_printf("No protocol given.");
- return FALSE;
- }
-
- if (!find_dissector(p)) {
- if (proto_get_id_by_filter_name(p) != -1) {
- *err = g_strdup_printf("While '%s' is a valid dissector filter name, that dissector is not configured"
- " to support SSL decryption.\n\n"
- "If you need to decrypt '%s' over SSL, please contact the Wireshark development team.", p, p);
- } else {
- char* ssl_str = ssl_association_info();
- *err = g_strdup_printf("Could not find dissector for: '%s'\nCommonly used SSL dissectors include:\n%s", p, ssl_str);
- g_free(ssl_str);
- }
- return FALSE;
- }
-
- *err = NULL;
- return TRUE;
-}
-
-gboolean
ssldecrypt_uat_fld_fileopen_chk_cb(void* r _U_, const char* p, guint len _U_, const void* u1 _U_, const void* u2 _U_, char** err)
{
ws_statb64 st;
@@ -4973,6 +4905,40 @@ ssldecrypt_uat_fld_password_chk_cb(void *r _U_, const char *p _U_, guint len _U_
}
/* UAT preferences callbacks. }}} */
+/** maximum size of ssl_association_info() string */
+#define SSL_ASSOC_MAX_LEN 8192
+
+typedef struct ssl_association_info_callback_data
+{
+ gchar *str;
+ const char *table_protocol;
+} ssl_association_info_callback_data_t;
+
+/**
+ * callback function used by ssl_association_info() to traverse the SSL associations.
+ */
+static void
+ssl_association_info_(const gchar *table _U_, gpointer handle, gpointer user_data)
+{
+ ssl_association_info_callback_data_t* data = (ssl_association_info_callback_data_t*)user_data;
+ const int l = (const int)strlen(data->str);
+ g_snprintf(data->str+l, SSL_ASSOC_MAX_LEN-l, "'%s' %s\n", dissector_handle_get_short_name((dissector_handle_t)handle), data->table_protocol);
+}
+
+/**
+ * @return an information string on the SSL protocol associations. The string has ephemeral lifetime/scope.
+ */
+gchar*
+ssl_association_info(const char* dissector_table_name, const char* table_protocol)
+{
+ ssl_association_info_callback_data_t data;
+
+ data.str = (gchar *)g_malloc0(SSL_ASSOC_MAX_LEN);
+ data.table_protocol = table_protocol;
+ dissector_table_foreach_handle(dissector_table_name, ssl_association_info_, &data);
+ return data.str;
+}
+
/** Begin of code related to dissection of wire data. */
diff --git a/epan/dissectors/packet-ssl-utils.h b/epan/dissectors/packet-ssl-utils.h
index f7a2496759..dcf1f8b515 100644
--- a/epan/dissectors/packet-ssl-utils.h
+++ b/epan/dissectors/packet-ssl-utils.h
@@ -410,14 +410,6 @@ typedef struct _SslDecryptSession {
} SslDecryptSession;
-typedef struct _SslAssociation {
- gboolean tcp;
- guint ssl_port;
- dissector_handle_t handle;
- gchar* info;
- gboolean from_key_list;
-} SslAssociation;
-
/* User Access Table */
typedef struct _ssldecrypt_assoc_t {
char* ipaddr;
@@ -447,9 +439,9 @@ gint ssl_get_keyex_alg(gint cipher);
gboolean ssldecrypt_uat_fld_ip_chk_cb(void*, const char*, unsigned, const void*, const void*, char** err);
gboolean ssldecrypt_uat_fld_port_chk_cb(void*, const char*, unsigned, const void*, const void*, char** err);
-gboolean ssldecrypt_uat_fld_protocol_chk_cb(void*, const char*, unsigned, const void*, const void*, char** err);
gboolean ssldecrypt_uat_fld_fileopen_chk_cb(void*, const char*, unsigned, const void*, const void*, char** err);
gboolean ssldecrypt_uat_fld_password_chk_cb(void*, const char*, unsigned, const void*, const void*, char** err);
+gchar* ssl_association_info(const char* dissector_table_name, const char* table_protocol);
/** Retrieve a SslSession, creating it if it did not already exist.
* @param conversation The SSL conversation.
@@ -541,22 +533,13 @@ ssl_private_key_free(gpointer key);
/* handling of association between tls/dtls ports and clear text protocol */
extern void
-ssl_association_add(GTree* associations, dissector_handle_t handle, guint port, const gchar *protocol, gboolean tcp, gboolean from_key_list);
+ssl_association_add(const char* dissector_table_name, dissector_handle_t main_handle, dissector_handle_t subdissector_handle, guint port, gboolean tcp);
extern void
-ssl_association_remove(GTree* associations, SslAssociation *assoc);
-
-extern gint
-ssl_association_cmp(gconstpointer a, gconstpointer b);
-
-extern SslAssociation*
-ssl_association_find(GTree * associations, guint port, gboolean tcp);
-
-extern gint
-ssl_assoc_from_key_list(gpointer key _U_, gpointer data, gpointer user_data);
+ssl_association_remove(const char* dissector_table_name, dissector_handle_t main_handle, dissector_handle_t subdissector_handle, guint port, gboolean tcp);
extern gint
-ssl_packet_from_server(SslSession *session, GTree *associations, packet_info *pinfo);
+ssl_packet_from_server(SslSession *session, dissector_table_t table, packet_info *pinfo);
/* add to packet data a copy of the specified real data */
extern void
@@ -587,7 +570,7 @@ ssl_load_keyfile(const gchar *ssl_keylog_filename, FILE **keylog_file,
/* parse ssl related preferences (private keys and ports association strings) */
extern void
-ssl_parse_key_list(const ssldecrypt_assoc_t * uats, GHashTable *key_hash, GTree* associations, dissector_handle_t handle, gboolean tcp);
+ssl_parse_key_list(const ssldecrypt_assoc_t * uats, GHashTable *key_hash, const char* dissector_table_name, dissector_handle_t main_handle, gboolean tcp);
/* store master secret into session data cache */
extern void
diff --git a/epan/dissectors/packet-ssl.c b/epan/dissectors/packet-ssl.c
index ae9daf8956..23d7a6d7c3 100644
--- a/epan/dissectors/packet-ssl.c
+++ b/epan/dissectors/packet-ssl.c
@@ -308,7 +308,8 @@ GHashTable *ssl_session_hash;
GHashTable *ssl_crandom_hash;
static GHashTable *ssl_key_hash = NULL;
-static GTree *ssl_associations = NULL;
+static wmem_stack_t *key_list_stack = NULL;
+static dissector_table_t ssl_associations = NULL;
static dissector_handle_t ssl_handle = NULL;
static StringInfo ssl_compressed_data = {NULL, 0};
static StringInfo ssl_decrypted_data = {NULL, 0};
@@ -363,6 +364,10 @@ ssl_init(void)
static void
ssl_cleanup(void)
{
+ if (key_list_stack != NULL) {
+ wmem_destroy_stack(key_list_stack);
+ key_list_stack = NULL;
+ }
reassembly_table_destroy(&ssl_reassembly_table);
ssl_common_cleanup(&ssl_master_key_map, &ssl_keylog_file,
&ssl_decrypted_data, &ssl_compressed_data);
@@ -377,8 +382,8 @@ ssl_cleanup(void)
static void
ssl_parse_uat(void)
{
- wmem_stack_t *tmp_stack;
- guint i;
+ guint i, port;
+ dissector_handle_t handle;
ssl_set_debug(ssl_debug_file_name);
@@ -388,22 +393,27 @@ ssl_parse_uat(void)
}
/* remove only associations created from key list */
- tmp_stack = wmem_stack_new(NULL);
- g_tree_foreach(ssl_associations, ssl_assoc_from_key_list, tmp_stack);
- while (wmem_stack_count(tmp_stack) > 0) {
- ssl_association_remove(ssl_associations, (SslAssociation *)wmem_stack_pop(tmp_stack));
+ if (key_list_stack != NULL) {
+ while (wmem_stack_count(key_list_stack) > 0) {
+ port = GPOINTER_TO_UINT(wmem_stack_pop(key_list_stack));
+ handle = dissector_get_uint_handle(ssl_associations, port);
+ if (handle != NULL)
+ ssl_association_remove("ssl.port", ssl_handle, handle, port, FALSE);
+ }
}
- wmem_destroy_stack(tmp_stack);
-
/* parse private keys string, load available keys and put them in key hash*/
ssl_key_hash = g_hash_table_new_full(ssl_private_key_hash,
ssl_private_key_equal, g_free, ssl_private_key_free);
if (nssldecrypt > 0) {
+ if (key_list_stack == NULL)
+ key_list_stack = wmem_stack_new(NULL);
for (i = 0; i < nssldecrypt; i++) {
ssldecrypt_assoc_t *ssl_uat = &(sslkeylist_uats[i]);
- ssl_parse_key_list(ssl_uat, ssl_key_hash, ssl_associations, ssl_handle, TRUE);
+ ssl_parse_key_list(ssl_uat, ssl_key_hash, "ssl.port", ssl_handle, TRUE);
+ if (key_list_stack)
+ wmem_stack_push(key_list_stack, GUINT_TO_POINTER(atoi(ssl_uat->port)));
}
}
@@ -443,39 +453,6 @@ ssl_parse_old_keys(void)
/*********************************************************************
*
- * SSL Associations tree
- *
- *********************************************************************/
-
-/** maximum size of ssl_association_info() string */
-#define SSL_ASSOC_MAX_LEN 8192
-
-/**
- * callback function used by ssl_association_info() to traverse the SSL associations.
- */
-static gboolean
-ssl_association_info_(gpointer key_ _U_, gpointer value_, gpointer s_)
-{
- SslAssociation *value = (SslAssociation *)value_;
- gchar *s = (gchar *)s_;
- const int l = (const int)strlen(s);
- g_snprintf(s+l, SSL_ASSOC_MAX_LEN-l, "'%s' %s %i\n", value->info, value->tcp ? "TCP":"UDP", value->ssl_port);
- return FALSE;
-}
-
-/**
- * @return an information string on the SSL protocol associations. The string has ephemeral lifetime/scope.
- */
-gchar*
-ssl_association_info(void)
-{
- gchar *s = (gchar *)g_malloc0(SSL_ASSOC_MAX_LEN);
- g_tree_foreach(ssl_associations, ssl_association_info_, s);
- return s;
-}
-
-/*********************************************************************
- *
* Forward Declarations
*
*********************************************************************/
@@ -1709,11 +1686,10 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo,
if (!session->app_handle) {
/* Unknown protocol handle, ssl_starttls_ack was not called before.
* Try to find an appropriate dissection handle and cache it. */
- SslAssociation *association;
- association = ssl_association_find(ssl_associations, pinfo->srcport, pinfo->ptype != PT_UDP);
- association = association ? association: ssl_association_find(ssl_associations, pinfo->destport, pinfo->ptype != PT_UDP);
- association = association ? association: ssl_association_find(ssl_associations, 0, pinfo->ptype != PT_UDP);
- if (association) session->app_handle = association->handle;
+ dissector_handle_t handle;
+ handle = dissector_get_uint_handle(ssl_associations, pinfo->srcport);
+ handle = handle ? handle : dissector_get_uint_handle(ssl_associations, pinfo->destport);
+ if (handle) session->app_handle = handle;
}
proto_item_set_text(ssl_record_tree,
@@ -3651,6 +3627,31 @@ UAT_CSTRING_CB_DEF(sslkeylist_uats,port,ssldecrypt_assoc_t)
UAT_CSTRING_CB_DEF(sslkeylist_uats,protocol,ssldecrypt_assoc_t)
UAT_FILENAME_CB_DEF(sslkeylist_uats,keyfile,ssldecrypt_assoc_t)
UAT_CSTRING_CB_DEF(sslkeylist_uats,password,ssldecrypt_assoc_t)
+
+static gboolean
+ssldecrypt_uat_fld_protocol_chk_cb(void* r _U_, const char* p, guint len _U_, const void* u1 _U_, const void* u2 _U_, char** err)
+{
+ if (!p || strlen(p) == 0u) {
+ *err = g_strdup_printf("No protocol given.");
+ return FALSE;
+ }
+
+ if (!find_dissector(p)) {
+ if (proto_get_id_by_filter_name(p) != -1) {
+ *err = g_strdup_printf("While '%s' is a valid dissector filter name, that dissector is not configured"
+ " to support SSL decryption.\n\n"
+ "If you need to decrypt '%s' over SSL, please contact the Wireshark development team.", p, p);
+ } else {
+ char* ssl_str = ssl_association_info("ssl.port", "TCP");
+ *err = g_strdup_printf("Could not find dissector for: '%s'\nCommonly used SSL dissectors include:\n%s", p, ssl_str);
+ g_free(ssl_str);
+ }
+ return FALSE;
+ }
+
+ *err = NULL;
+ return TRUE;
+}
#endif
/*********************************************************************
@@ -4090,6 +4091,8 @@ proto_register_ssl(void)
proto_ssl = proto_register_protocol("Secure Sockets Layer",
"SSL", "ssl");
+ ssl_associations = register_dissector_table("ssl.port", "SSL TCP Dissector", FT_UINT16, BASE_DEC, DISSECTOR_TABLE_NOT_ALLOW_DUPLICATE);
+
/* Required function calls to register the header fields and
* subtrees used */
proto_register_field_array(proto_ssl, hf, array_length(hf));
@@ -4167,8 +4170,6 @@ proto_register_ssl(void)
new_register_dissector("ssl", dissect_ssl, proto_ssl);
ssl_handle = find_dissector("ssl");
- ssl_associations = g_tree_new(ssl_association_cmp);
-
register_init_routine(ssl_init);
register_cleanup_routine(ssl_cleanup);
ssl_tap = register_tap("ssl");
@@ -4191,27 +4192,15 @@ proto_reg_handoff_ssl(void)
}
void
-ssl_dissector_add(guint port, const gchar *protocol, gboolean tcp)
+ssl_dissector_add(guint port, dissector_handle_t handle)
{
- SslAssociation *assoc;
-
- assoc = ssl_association_find(ssl_associations, port, tcp);
- if (assoc) {
- ssl_association_remove(ssl_associations, assoc);
- }
-
- ssl_association_add(ssl_associations, ssl_handle, port, protocol, tcp, FALSE);
+ ssl_association_add("ssl.port", ssl_handle, handle, port, TRUE);
}
void
-ssl_dissector_delete(guint port, const gchar *protocol, gboolean tcp)
+ssl_dissector_delete(guint port, dissector_handle_t handle)
{
- SslAssociation *assoc;
-
- assoc = ssl_association_find(ssl_associations, port, tcp);
- if (assoc && (assoc->handle == find_dissector(protocol))) {
- ssl_association_remove(ssl_associations, assoc);
- }
+ ssl_association_remove("ssl.port", ssl_handle, handle, port, TRUE);
}
/*
diff --git a/epan/dissectors/packet-ssl.h b/epan/dissectors/packet-ssl.h
index 499ba8d22e..ba800bddba 100644
--- a/epan/dissectors/packet-ssl.h
+++ b/epan/dissectors/packet-ssl.h
@@ -24,14 +24,15 @@
#define __PACKET_SSL_H__
#include "ws_symbol_export.h"
+#include <epan/packet.h>
/** Maps Session-ID to pre-master secrets. */
WS_DLL_PUBLIC GHashTable *ssl_session_hash;
/** Maps Client Random to pre-master secrets. */
WS_DLL_PUBLIC GHashTable *ssl_crandom_hash;
-WS_DLL_PUBLIC void ssl_dissector_add(guint port, const gchar *protocol, gboolean tcp);
-WS_DLL_PUBLIC void ssl_dissector_delete(guint port, const gchar *protocol, gboolean tcp);
+WS_DLL_PUBLIC void ssl_dissector_add(guint port, dissector_handle_t handle);
+WS_DLL_PUBLIC void ssl_dissector_delete(guint port, dissector_handle_t handle);
WS_DLL_PUBLIC void ssl_set_master_secret(guint32 frame_num, address *addr_srv, address *addr_cli,
port_type ptype, guint32 port_srv, guint32 port_cli,
@@ -41,6 +42,4 @@ WS_DLL_PUBLIC void ssl_set_master_secret(guint32 frame_num, address *addr_srv, a
extern gboolean ssl_ignore_mac_failed;
-gchar* ssl_association_info(void);
-
#endif /* __PACKET_SSL_H__ */