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>
This commit is contained in:
Michael Mann 2015-11-05 23:20:45 -05:00
parent b56d323412
commit 3aefd3b5b2
19 changed files with 203 additions and 227 deletions

View File

@ -940,7 +940,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) {
@ -953,12 +953,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);
}

View File

@ -2399,13 +2399,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);
}
}

View File

@ -1239,8 +1239,8 @@ libwireshark.so.0 libwireshark0 #MINVER#
srt_table_iterate_tables@Base 1.99.8
srtcp_add_address@Base 1.9.1
srtp_add_address@Base 1.9.1
ssl_dissector_add@Base 1.9.1
ssl_dissector_delete@Base 1.9.1
ssl_dissector_add@Base 2.1.0
ssl_dissector_delete@Base 2.1.0
ssl_session_hash@Base 1.9.1
ssl_crandom_hash@Base 1.99.4
ssl_set_master_secret@Base 1.9.1

View File

@ -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);
}
}

View File

@ -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");

View File

@ -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);
}

View File

@ -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) {

View File

@ -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");
}
/*

View File

@ -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);
}
}

View File

@ -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 */

View File

@ -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);
}

View File

@ -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);
}
/*

View File

@ -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);
}
/*

View File

@ -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 */

View File

@ -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");

View File

@ -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.");
}
@ -4893,31 +4850,6 @@ ssldecrypt_uat_fld_port_chk_cb(void* r _U_, const char* p, guint len _U_, const
return TRUE;
}
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)
{
@ -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. */

View File

@ -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);
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_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);
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

View File

@ -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)));
}
}
@ -441,39 +451,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);
}
/*

View File

@ -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__ */