static void
dtls_parse(void)
{
+ ep_stack_t tmp_stack;
+ SslAssociation *tmp_assoc;
+
if (dtls_key_hash)
{
g_hash_table_foreach(dtls_key_hash, ssl_private_key_free, NULL);
g_hash_table_destroy(dtls_key_hash);
}
- if (dtls_associations)
- {
- g_tree_traverse(dtls_associations, ssl_association_remove_handle_udp, G_IN_ORDER, NULL);
- g_tree_destroy(dtls_associations);
- }
+
+ /* remove only associations created from key list */
+ tmp_stack = ep_stack_new();
+ g_tree_traverse(dtls_associations, ssl_assoc_from_key_list, G_IN_ORDER, tmp_stack);
+ while (tmp_assoc = ep_stack_pop(tmp_stack)) {
+ ssl_association_remove(dtls_associations, tmp_assoc);
+ }
/* parse private keys string, load available keys and put them in key hash*/
dtls_key_hash = g_hash_table_new(ssl_private_key_hash, ssl_private_key_equal);
- dtls_associations = g_tree_new(ssl_association_cmp);
if (dtls_keys_list && (dtls_keys_list[0] != 0))
{
ssl_set_debug(dtls_debug_file_name);
/* [re] add dtls dissection to default port in openssl 0.9.8b implementation */
- ssl_association_add(dtls_associations, dtls_handle, 4433, "http", FALSE);
+ ssl_association_add(dtls_associations, dtls_handle, 4433, "http", FALSE,FALSE);
}
/*
conversation_add_proto_data(conversation, proto_dtls, ssl_session);
/* we need to know witch side of conversation is speaking */
- if (ssl_packet_from_server(dtls_associations, pinfo->srcport)) {
+ if (ssl_packet_from_server(dtls_associations, pinfo->srcport, pinfo->ptype == PT_TCP)) {
dummy.addr = pinfo->src;
dummy.port = pinfo->srcport;
}
}
/* retrive decoder for this packet direction */
- if ((direction = ssl_packet_from_server(dtls_associations, pinfo->srcport)) != 0) {
+ if ((direction = ssl_packet_from_server(dtls_associations, pinfo->srcport, pinfo->ptype == PT_TCP)) != 0) {
ssl_debug_printf("decrypt_dtls_record: using server decoder\n");
decoder = &ssl->server;
}
record_length = tvb_get_ntohs(tvb, offset + 11);
if(ssl){
- if(ssl_packet_from_server(dtls_associations, pinfo->srcport)){
+ if(ssl_packet_from_server(dtls_associations, pinfo->srcport, pinfo->ptype == PT_TCP)){
ssl->server.seq=sequence_number;
ssl->server.epoch=epoch;
}
/* 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*/
- association = ssl_association_find(dtls_associations, pinfo->srcport);
- association = association ? association: ssl_association_find(dtls_associations, pinfo->destport);
+ 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);
proto_item_set_text(dtls_record_tree,
"%s Record Layer: %s Protocol: %s",
}
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);
ssl_lib_init();
dtls_tap = register_tap("dtls");
void
proto_reg_handoff_dtls(void)
{
- dtls_handle = find_dissector("dtls");
/* add now dissector to default ports.*/
dtls_parse();
/* handling of association between tls/dtls ports and clear text protocol */
void
-ssl_association_add(GTree* associations, dissector_handle_t handle, guint port, gchar *protocol, gboolean tcp)
+ssl_association_add(GTree* associations, dissector_handle_t handle, guint port, gchar *protocol, gboolean tcp, gboolean from_key_list)
{
SslAssociation* assoc;
assoc = g_malloc(sizeof(SslAssociation));
+ assoc->tcp = tcp;
+ assoc->ssl_port = port;
assoc->info=g_malloc(strlen(protocol)+1);
strcpy(assoc->info, protocol);
- assoc->ssl_port = port;
-
assoc->handle = find_dissector(protocol);
+ assoc->from_key_list = from_key_list;
- ssl_debug_printf("association_add port %d protocol %s handle %p\n",
- port, protocol, assoc->handle);
+ ssl_debug_printf("association_add %s port %d protocol %s handle %p\n",
+ (assoc->tcp)?"TCP":"UDP", port, protocol, assoc->handle);
if(!assoc->handle){
dissector_add("tcp.port", port, handle);
else
dissector_add("udp.port", port, handle);
- g_tree_insert(associations, (gpointer)port, assoc);
+ g_tree_insert(associations, assoc, assoc);
}
}
+void
+ssl_association_remove(GTree* associations, SslAssociation *assoc)
+{
+ ssl_debug_printf("ssl_association_remove removing %s %u - %s handle %p\n",
+ (assoc->tcp)?"TCP":"UDP", assoc->ssl_port, assoc->info, assoc->handle);
+ if (assoc->handle)
+ dissector_delete((assoc->tcp)?"tcp.port":"udp.port", assoc->ssl_port, assoc->handle);
+
+ g_tree_remove(associations, assoc);
+ g_free(assoc);
+}
gint
ssl_association_cmp(gconstpointer a, gconstpointer b)
{
- return (gint)a-(gint)b;
+ const SslAssociation *assoc_a=a, *assoc_b=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)
+ssl_association_find(GTree * associations, guint port, gboolean tcp)
{
register SslAssociation* ret;
- ret = g_tree_lookup(associations, (gpointer)port);
+ SslAssociation assoc_tmp;
- ssl_debug_printf("association_find: port %d found %p\n", port, ret);
- return ret;
-}
+ assoc_tmp.tcp = tcp;
+ assoc_tmp.ssl_port = port;
+ ret = g_tree_lookup(associations, &assoc_tmp);
-gint
-ssl_association_remove_handle_tcp (gpointer key _U_,
- gpointer data, gpointer user_data _U_)
-{
- SslAssociation* assoc;
- assoc = (SslAssociation*) data;
-
- ssl_debug_printf("association_remove_handle removing ptr %p handle %p\n",
- data, assoc->handle);
- if (assoc->handle)
- dissector_delete("tcp.port", assoc->ssl_port, assoc->handle);
- g_free(data);
- return 0;
+ ssl_debug_printf("association_find: %s port %d found %p\n", (tcp)?"TCP":"UDP", port, ret);
+ return ret;
}
gint
-ssl_association_remove_handle_udp (gpointer key _U_,
- gpointer data, gpointer user_data _U_)
+ssl_assoc_from_key_list(gpointer key _U_, gpointer data, gpointer user_data)
{
- SslAssociation* assoc;
- assoc = (SslAssociation*) data;
-
- ssl_debug_printf("association_remove_handle removing ptr %p handle %p\n",
- data, assoc->handle);
- if (assoc->handle)
- dissector_delete("tcp.port", assoc->ssl_port, assoc->handle);
- g_free(data);
- return 0;
+ if (((SslAssociation*)data)->from_key_list)
+ ep_stack_push((ep_stack_t)user_data, data);
}
int
-ssl_packet_from_server(GTree* associations, guint port)
+ssl_packet_from_server(GTree* associations, guint port, gboolean tcp)
{
register gint ret;
- ret = ssl_association_find(associations, port) != 0;
+ ret = ssl_association_find(associations, port, tcp) != 0;
ssl_debug_printf("packet_from_server: is from server %d\n", ret);
return ret;
filename);
g_hash_table_insert(key_hash, service, private_key);
- ssl_association_add(associations, handle, atoi(port), protocol, tcp);
+ ssl_association_add(associations, handle, atoi(port), protocol, tcp, TRUE);
} while (end != NULL);
free(tmp);
} SslDecryptSession;
typedef struct _SslAssociation {
+ gboolean tcp;
guint ssl_port;
dissector_handle_t handle;
gchar* info;
+ gboolean from_key_list;
} SslAssociation;
typedef struct _SslService {
/* handling of association between tls/dtls ports and clear text protocol */
extern void
-ssl_association_add(GTree* associations, dissector_handle_t handle, guint port, gchar *protocol, gboolean tcp);
+ssl_association_add(GTree* associations, dissector_handle_t handle, guint port, gchar *protocol, gboolean tcp, gboolean from_key_list);
+
+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);
-
-extern gint
-ssl_association_remove_handle_tcp (gpointer key _U_,
- gpointer data, gpointer user_data _U_);
+ssl_association_find(GTree * associations, guint port, gboolean tcp);
extern gint
-ssl_association_remove_handle_udp (gpointer key _U_,
- gpointer data, gpointer user_data _U_);
+ssl_assoc_from_key_list(gpointer key _U_, gpointer data, gpointer user_data);
extern gint
-ssl_packet_from_server(GTree* associations, guint port);
+ssl_packet_from_server(GTree* associations, guint port, gboolean tcp);
/* add to packet data a newly allocated tvb with the specified real data*/
extern void
#include <epan/dissectors/packet-x509af.h>
#include <epan/emem.h>
#include <epan/tap.h>
+#include "packet-ssl.h"
#include "packet-ssl-utils.h"
static gchar* ssl_keys_list = NULL;
static gchar* ssl_debug_file_name = NULL;
+/* Forward declaration we need below */
+void proto_reg_handoff_ssl(void);
+
/* initialize/reset per capture state data (ssl sessions cache) */
static void
ssl_init(void)
static void
ssl_parse(void)
{
+ ep_stack_t tmp_stack;
+ SslAssociation *tmp_assoc;
+
ssl_set_debug(ssl_debug_file_name);
if (ssl_key_hash)
g_hash_table_foreach(ssl_key_hash, ssl_private_key_free, NULL);
g_hash_table_destroy(ssl_key_hash);
}
- if (ssl_associations)
- {
- g_tree_traverse(ssl_associations, ssl_association_remove_handle_tcp, G_IN_ORDER, NULL);
- g_tree_destroy(ssl_associations);
- }
+
+ /* remove only associations created from key list */
+ tmp_stack = ep_stack_new();
+ g_tree_traverse(ssl_associations, ssl_assoc_from_key_list, G_IN_ORDER, tmp_stack);
+ while (tmp_assoc = ep_stack_pop(tmp_stack)) {
+ ssl_association_remove(ssl_associations, tmp_assoc);
+ }
/* parse private keys string, load available keys and put them in key hash*/
ssl_key_hash = g_hash_table_new(ssl_private_key_hash,ssl_private_key_equal);
- ssl_associations = g_tree_new(ssl_association_cmp);
if (ssl_keys_list && (ssl_keys_list[0] != 0))
{
ssl_parse_key_list(ssl_keys_list,ssl_key_hash,ssl_associations,ssl_handle,TRUE);
}
- /* [re] add ssl dissection to defaults ports */
- ssl_association_add(ssl_associations, ssl_handle, 443, "http", TRUE);
- ssl_association_add(ssl_associations, ssl_handle, 636, "ldap", TRUE);
- ssl_association_add(ssl_associations, ssl_handle, 993, "imap", TRUE);
- ssl_association_add(ssl_associations, ssl_handle, 995, "pop", TRUE);
}
/* function that save app_data during sub protocol reassembling */
tvbuff_t* new_tvb;
packet_info * pp;
/* find out a dissector using server port*/
- association = ssl_association_find(ssl_associations, pinfo->srcport);
- association = association ? association: ssl_association_find(ssl_associations, pinfo->destport);
+ association = ssl_association_find(ssl_associations, pinfo->srcport, pinfo->ptype == PT_TCP);
+ association = association ? association: ssl_association_find(ssl_associations, pinfo->destport, pinfo->ptype == PT_TCP);
/* create a copy of packet_info */
pp=g_malloc(sizeof(packet_info));
memcpy(pp, pinfo, sizeof(packet_info));
conversation_add_proto_data(conversation, proto_ssl, ssl_session);
/* we need to know witch side of conversation is speaking*/
- if (ssl_packet_from_server(ssl_associations, pinfo->srcport)) {
+ if (ssl_packet_from_server(ssl_associations, pinfo->srcport, pinfo->ptype == PT_TCP)) {
dummy.addr = pinfo->src;
dummy.port = pinfo->srcport;
}
}
/* retrive decoder for this packet direction*/
- if ((direction = ssl_packet_from_server(ssl_associations, pinfo->srcport)) != 0) {
+ if ((direction = ssl_packet_from_server(ssl_associations, pinfo->srcport, pinfo->ptype == PT_TCP)) != 0) {
ssl_debug_printf("decrypt_ssl3_record: using server decoder\n");
decoder = &ssl->server;
}
/* 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*/
- association = ssl_association_find(ssl_associations, pinfo->srcport);
- association = association ? association: ssl_association_find(ssl_associations, pinfo->destport);
+ association = ssl_association_find(ssl_associations, pinfo->srcport, pinfo->ptype == PT_TCP);
+ association = association ? association: ssl_association_find(ssl_associations, pinfo->destport, pinfo->ptype == PT_TCP);
proto_item_set_text(ssl_record_tree,
"%s Record Layer: %s Protocol: %s",
proto_register_subtree_array(ett, array_length(ett));
{
- module_t *ssl_module = prefs_register_protocol(proto_ssl, ssl_parse);
+ module_t *ssl_module = prefs_register_protocol(proto_ssl, proto_reg_handoff_ssl);
prefs_register_bool_preference(ssl_module,
"desegment_ssl_records",
"Reassemble SSL records spanning multiple TCP segments",
}
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);
ssl_lib_init();
void
proto_reg_handoff_ssl(void)
{
- ssl_handle = find_dissector("ssl");
- /* add now dissector to default ports.*/
+ /* parse key list */
ssl_parse();
+
+ /* add ssl dissection to defaults ports */
+ ssl_dissector_add(443, "http", TRUE);
+ ssl_dissector_add(636, "ldap", TRUE);
+ ssl_dissector_add(993, "imap", TRUE);
+ ssl_dissector_add(995, "pop", TRUE);
}
+void
+ssl_dissector_add(guint port, gchar *protocol, gboolean tcp)
+{
+ 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);
+}
smb_cmd_vals DATA
smb2_cmd_vals DATA
sminmpec_values DATA
+ssl_dissector_add
start_requested_stats
started_with_special_privs
stats_tree_branch_max_namelen