forked from osmocom/wireshark
From Ivan Sy via bug 3343:
- Support for DTLS and SSL RSA keys list using User Accessible Table - Support for IPv6 SSL as posted by bug#3343 comment#1 - 'any' and 'anyipv4' for IPv4 wildcard - 'anyipv6' for IPv6 wildcard - UAT fields validation. From me: - Update paramaters to match UAT API changes. - Change the UAT filename. - Fix buffer overflow for IPv6 addresses. - Allow the use of hostnames along with numeric addresses. - Don't convert strings to addresses twice. - Don't use the same variable name for different data types. - Make "any" mean "any IPv4 or any IPv6". - Bend the concept of obsolete preferences slightly so that we can convert and old-style key list to a UAT. - Clean up whitespace. - Don't point to a User's Guide section for now; it may make more sense to keep using the wiki page. SSL dissector changes have been tested. DTLS dissector changes have not. svn path=/trunk/; revision=36875
This commit is contained in:
parent
6eae60aa2f
commit
c6fecb57b0
|
@ -74,6 +74,12 @@
|
|||
#include "wsutil/inet_v6defs.h"
|
||||
#endif
|
||||
#include "packet-ssl-utils.h"
|
||||
#include <wsutil/file_util.h>
|
||||
#include <epan/uat.h>
|
||||
|
||||
/* DTLS User Access Table */
|
||||
static ssldecrypt_assoc_t *dtlskeylist_uats = NULL;
|
||||
static guint ndtlsdecrypt = 0;
|
||||
|
||||
/* we need to remember the top tree so that subdissectors we call are created
|
||||
* at the root and not deep down inside the DTLS decode
|
||||
|
@ -174,6 +180,7 @@ static StringInfo dtls_compressed_data = {NULL, 0};
|
|||
static StringInfo dtls_decrypted_data = {NULL, 0};
|
||||
static gint dtls_decrypted_data_avail = 0;
|
||||
|
||||
static uat_t *dtlsdecrypt_uat = NULL;
|
||||
static gchar* dtls_keys_list = NULL;
|
||||
#ifdef HAVE_LIBGNUTLS
|
||||
static gchar* dtls_debug_file_name = NULL;
|
||||
|
@ -204,8 +211,19 @@ static const fragment_items dtls_frag_items = {
|
|||
static void
|
||||
dtls_init(void)
|
||||
{
|
||||
module_t *dtls_module = prefs_find_module("dtls");
|
||||
pref_t *keys_list_pref;
|
||||
|
||||
ssl_common_init(&dtls_session_hash, &dtls_decrypted_data, &dtls_compressed_data);
|
||||
fragment_table_init (&dtls_fragment_table);
|
||||
|
||||
/* We should have loaded "keys_list" by now. Mark it obsolete */
|
||||
if (dtls_module) {
|
||||
keys_list_pref = prefs_find_preference(dtls_module, "keys_list");
|
||||
if (! prefs_get_preference_obsolete(keys_list_pref)) {
|
||||
prefs_set_preference_obsolete(keys_list_pref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* parse dtls related preferences (private keys and ports association strings) */
|
||||
|
@ -214,6 +232,9 @@ dtls_parse(void)
|
|||
{
|
||||
ep_stack_t tmp_stack;
|
||||
SslAssociation *tmp_assoc;
|
||||
guint i;
|
||||
gchar **old_keys, **parts, *err;
|
||||
GString *uat_entry = g_string_new("");
|
||||
|
||||
if (dtls_key_hash)
|
||||
{
|
||||
|
@ -228,13 +249,37 @@ dtls_parse(void)
|
|||
ssl_association_remove(dtls_associations, tmp_assoc);
|
||||
}
|
||||
|
||||
/* Import old-style keys */
|
||||
if (dtlsdecrypt_uat && dtls_keys_list && dtls_keys_list[0]) {
|
||||
old_keys = g_strsplit(dtls_keys_list, ";", 0);
|
||||
for (i = 0; old_keys[i] != NULL; i++) {
|
||||
parts = g_strsplit(old_keys[i], ",", 4);
|
||||
if (parts[0] && parts[1] && parts[2] && parts[3]) {
|
||||
g_string_printf(uat_entry, "\"%s\",\"%s\",\"%s\",\"%s\",\"\"",
|
||||
parts[0], parts[1], parts[2], parts[3]);
|
||||
if (!uat_load_str(dtlsdecrypt_uat, uat_entry->str, &err)) {
|
||||
ssl_debug_printf("dtls_parse: Can't load UAT string %s: %s\n",
|
||||
uat_entry->str, err);
|
||||
}
|
||||
}
|
||||
g_strfreev(parts);
|
||||
}
|
||||
g_strfreev(old_keys);
|
||||
}
|
||||
g_string_free(uat_entry, TRUE);
|
||||
|
||||
|
||||
/* 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);
|
||||
|
||||
if (dtls_keys_list && (dtls_keys_list[0] != 0))
|
||||
{
|
||||
ssl_parse_key_list(dtls_keys_list,dtls_key_hash,dtls_associations,dtls_handle,FALSE);
|
||||
}
|
||||
if (ndtlsdecrypt > 0)
|
||||
{
|
||||
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_set_debug(dtls_debug_file_name);
|
||||
|
||||
|
@ -1908,6 +1953,49 @@ looks_like_dtls(tvbuff_t *tvb, guint32 offset)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* UAT */
|
||||
|
||||
static void
|
||||
dtlsdecrypt_free_cb(void* r)
|
||||
{
|
||||
ssldecrypt_assoc_t* h = r;
|
||||
|
||||
g_free(h->ipaddr);
|
||||
g_free(h->port);
|
||||
g_free(h->protocol);
|
||||
g_free(h->keyfile);
|
||||
g_free(h->password);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
dtlsdecrypt_update_cb(void* r _U_, const char** err _U_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *
|
||||
dtlsdecrypt_copy_cb(void* dest, const void* orig, size_t len _U_)
|
||||
{
|
||||
const ssldecrypt_assoc_t* o = orig;
|
||||
ssldecrypt_assoc_t* d = dest;
|
||||
|
||||
d->ipaddr = g_strdup(o->ipaddr);
|
||||
d->port = g_strdup(o->port);
|
||||
d->protocol = g_strdup(o->protocol);
|
||||
d->keyfile = g_strdup(o->keyfile);
|
||||
d->password = g_strdup(o->password);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
UAT_CSTRING_CB_DEF(sslkeylist_uats,ipaddr,ssldecrypt_assoc_t)
|
||||
UAT_CSTRING_CB_DEF(sslkeylist_uats,port,ssldecrypt_assoc_t)
|
||||
UAT_CSTRING_CB_DEF(sslkeylist_uats,protocol,ssldecrypt_assoc_t)
|
||||
UAT_CSTRING_CB_DEF(sslkeylist_uats,keyfile,ssldecrypt_assoc_t)
|
||||
UAT_CSTRING_CB_DEF(sslkeylist_uats,password,ssldecrypt_assoc_t)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Standard Wireshark Protocol Registration and housekeeping
|
||||
|
@ -2236,15 +2324,45 @@ proto_register_dtls(void)
|
|||
#ifdef HAVE_LIBGNUTLS
|
||||
{
|
||||
module_t *dtls_module = prefs_register_protocol(proto_dtls, dtls_parse);
|
||||
prefs_register_string_preference(dtls_module, "keys_list", "RSA keys list",
|
||||
"semicolon separated list of private RSA keys used for DTLS decryption; "
|
||||
"each list entry must be in the form of <ip>,<port>,<protocol>,<key_file_name>"
|
||||
"<key_file_name> is the local file name of the RSA private key used by the specified server\n",
|
||||
(const gchar **)&dtls_keys_list);
|
||||
prefs_register_string_preference(dtls_module, "debug_file", "DTLS debug file",
|
||||
|
||||
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, 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
|
||||
};
|
||||
|
||||
dtlsdecrypt_uat = uat_new("DTLS RSA Keylist",
|
||||
sizeof(ssldecrypt_assoc_t),
|
||||
"dtlsdecrypttablefile", /* filename */
|
||||
TRUE, /* from_profile */
|
||||
(void*) &dtlskeylist_uats, /* data_ptr */
|
||||
&ndtlsdecrypt, /* numitems_ptr */
|
||||
UAT_CAT_FFMT, /* category */
|
||||
"ChK12ProtocolsSection", /* TODO, need revision - help */
|
||||
dtlsdecrypt_copy_cb,
|
||||
NULL, /* dtlsdecrypt_update_cb? */
|
||||
dtlsdecrypt_free_cb,
|
||||
NULL,
|
||||
dtlskeylist_uats_flds);
|
||||
|
||||
prefs_register_uat_preference(dtls_module, "cfg",
|
||||
"RSA keys list",
|
||||
"A table of RSA keys for DTLS decryption",
|
||||
dtlsdecrypt_uat);
|
||||
|
||||
prefs_register_string_preference(dtls_module, "debug_file", "DTLS debug file",
|
||||
"redirect dtls debug to file name; leave empty to disable debug, "
|
||||
"use \"" SSL_DEBUG_USE_STDERR "\" to redirect output to stderr\n",
|
||||
(const gchar **)&dtls_debug_file_name);
|
||||
|
||||
prefs_register_string_preference(dtls_module, "keys_list", "RSA keys list (deprecated)",
|
||||
"Semicolon-separated list of private RSA keys used for DTLS decryption. "
|
||||
"Used by versions of Wireshark prior to 1.6",
|
||||
(const gchar **)&dtls_keys_list);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -30,13 +30,17 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#include "packet-ssl-utils.h"
|
||||
|
||||
#include <epan/emem.h>
|
||||
#include <epan/strutil.h>
|
||||
#include <epan/addr_resolv.h>
|
||||
#include <epan/ipv6-utils.h>
|
||||
#include <wsutil/file_util.h>
|
||||
|
||||
/*
|
||||
|
@ -166,7 +170,7 @@ static const value_string ssl_20_cipher_suites[] = {
|
|||
{ 0x00006B, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" },
|
||||
{ 0x00006C, "TLS_DH_anon_WITH_AES_128_CBC_SHA256" },
|
||||
{ 0x00006D, "TLS_DH_anon_WITH_AES_256_CBC_SHA256" },
|
||||
/* 0x00,0x6E-83 Unassigned */
|
||||
/* 0x00,0x6E-83 Unassigned */
|
||||
{ 0x000084, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA" },
|
||||
{ 0x000085, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA" },
|
||||
{ 0x000086, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA" },
|
||||
|
@ -238,9 +242,9 @@ static const value_string ssl_20_cipher_suites[] = {
|
|||
{ 0x0000C3, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256" },
|
||||
{ 0x0000C4, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256" },
|
||||
{ 0x0000C5, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256" },
|
||||
/* 0x00,0xC6-FE Unassigned */
|
||||
{ 0x0000FF, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" },
|
||||
/* 0x01-BF,* Unassigned */
|
||||
/* 0x00,0xC6-FE Unassigned */
|
||||
{ 0x0000FF, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" },
|
||||
/* 0x01-BF,* Unassigned */
|
||||
/* From RFC 4492 */
|
||||
{ 0x00c001, "TLS_ECDH_ECDSA_WITH_NULL_SHA" },
|
||||
{ 0x00c002, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA" },
|
||||
|
@ -304,12 +308,12 @@ static const value_string ssl_20_cipher_suites[] = {
|
|||
{ 0x00C039, "TLS_ECDHE_PSK_WITH_NULL_SHA" },
|
||||
{ 0x00C03A, "TLS_ECDHE_PSK_WITH_NULL_SHA256" },
|
||||
{ 0x00C03B, "TLS_ECDHE_PSK_WITH_NULL_SHA384" },
|
||||
/* 0xC0,0x3C-FF Unassigned
|
||||
0xC1-FD,* Unassigned
|
||||
0xFE,0x00-FD Unassigned
|
||||
0xFE,0xFE-FF Reserved to avoid conflicts with widely deployed implementations [Pasi_Eronen]
|
||||
0xFF,0x00-FF Reserved for Private Use [RFC5246]
|
||||
*/
|
||||
/* 0xC0,0x3C-FF Unassigned
|
||||
0xC1-FD,* Unassigned
|
||||
0xFE,0x00-FD Unassigned
|
||||
0xFE,0xFE-FF Reserved to avoid conflicts with widely deployed implementations [Pasi_Eronen]
|
||||
0xFF,0x00-FF Reserved for Private Use [RFC5246]
|
||||
*/
|
||||
|
||||
/* these from http://www.mozilla.org/projects/
|
||||
security/pki/nss/ssl/fips-ssl-ciphersuites.html */
|
||||
|
@ -709,10 +713,10 @@ static const value_string ssl_31_ciphersuite[] = {
|
|||
{ 0x00C3, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256" },
|
||||
{ 0x00C4, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256" },
|
||||
{ 0x00C5, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256" },
|
||||
/* 0x00,0xC6-FE Unassigned */
|
||||
/* 0x00,0xC6-FE Unassigned */
|
||||
/* From RFC 5746 */
|
||||
{ 0x0000FF, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" },
|
||||
/* 0x01-BF,* Unassigned */
|
||||
/* 0x01-BF,* Unassigned */
|
||||
/* From RFC 4492 */
|
||||
{ 0xc001, "TLS_ECDH_ECDSA_WITH_NULL_SHA" },
|
||||
{ 0xc002, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA" },
|
||||
|
@ -2935,8 +2939,10 @@ ssl_private_key_hash (gconstpointer v)
|
|||
void
|
||||
ssl_private_key_free(gpointer id, gpointer key, gpointer dummy _U_)
|
||||
{
|
||||
g_free(id);
|
||||
ssl_free_key((Ssl_private_key_t*) key);
|
||||
if (id != NULL) {
|
||||
g_free(id);
|
||||
ssl_free_key((Ssl_private_key_t*) key);
|
||||
}
|
||||
}
|
||||
|
||||
/* handling of association between tls/dtls ports and clear text protocol */
|
||||
|
@ -3147,137 +3153,76 @@ ssl_common_init(GHashTable **session_hash, StringInfo *decrypted_data, StringInf
|
|||
|
||||
/* parse ssl related preferences (private keys and ports association strings) */
|
||||
void
|
||||
ssl_parse_key_list(const gchar * keys_list, GHashTable *key_hash, GTree* associations, dissector_handle_t handle, gboolean tcp)
|
||||
ssl_parse_key_list(const ssldecrypt_assoc_t * uats, GHashTable *key_hash, GTree* associations, dissector_handle_t handle, gboolean tcp)
|
||||
{
|
||||
gchar* end;
|
||||
gchar* start;
|
||||
gchar* tmp;
|
||||
guchar* ip;
|
||||
SslService* service;
|
||||
Ssl_private_key_t * private_key, *tmp_private_key;
|
||||
FILE* fp;
|
||||
FILE* fp = NULL;
|
||||
guint32 addr_data[4];
|
||||
int addr_len, at;
|
||||
address_type addr_type[2] = { AT_IPv4, AT_IPv6 };
|
||||
|
||||
start = g_strdup(keys_list);
|
||||
tmp = start;
|
||||
ssl_debug_printf("ssl_init keys string:\n%s\n", start);
|
||||
do {
|
||||
int read_index, write_index;
|
||||
gchar* addr, *port, *protocol, *filename, *cert_passwd;
|
||||
/* try to load keys file first */
|
||||
fp = ws_fopen(uats->keyfile, "rb");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "Can't open file %s\n",uats->keyfile);
|
||||
return;
|
||||
}
|
||||
|
||||
addr = start;
|
||||
/* split ip/file couple with ';' separator*/
|
||||
end = strpbrk(start, ";\n\r");
|
||||
if (end) {
|
||||
*end = 0;
|
||||
start = end+1;
|
||||
}
|
||||
if ((gint)strlen(uats->password) == 0) {
|
||||
private_key = ssl_load_key(fp);
|
||||
} else {
|
||||
private_key = ssl_load_pkcs12(fp, uats->password);
|
||||
}
|
||||
|
||||
/* skip comments (in file) */
|
||||
if (addr[0] == '#') continue;
|
||||
if (!private_key) {
|
||||
fprintf(stderr,"Can't load private key from %s\n", uats->keyfile);
|
||||
return;
|
||||
}
|
||||
|
||||
/* for each entry split ip, port, protocol, filename with ',' separator */
|
||||
ssl_debug_printf("ssl_init found host entry %s\n", addr);
|
||||
port = strchr(addr, ',');
|
||||
if (!port)
|
||||
{
|
||||
ssl_debug_printf("ssl_init entry malformed can't find port in '%s'\n", addr);
|
||||
continue;
|
||||
}
|
||||
*port = 0;
|
||||
port++;
|
||||
fclose(fp);
|
||||
|
||||
protocol = strchr(port,',');
|
||||
if (!protocol)
|
||||
{
|
||||
ssl_debug_printf("ssl_init entry malformed can't find protocol in %s\n", port);
|
||||
continue;
|
||||
}
|
||||
*protocol=0;
|
||||
protocol++;
|
||||
for (at = 0; at < 2; at++) {
|
||||
memset(addr_data, 0, sizeof(addr_data));
|
||||
addr_len = 0;
|
||||
|
||||
filename = strchr(protocol,',');
|
||||
if (!filename)
|
||||
{
|
||||
ssl_debug_printf("ssl_init entry malformed can't find filename in %s\n", protocol);
|
||||
continue;
|
||||
}
|
||||
*filename=0;
|
||||
filename++;
|
||||
/* any: IPv4 or IPv6 wildcard */
|
||||
/* anyipv4: IPv4 wildcard */
|
||||
/* anyipv6: IPv6 wildcard */
|
||||
|
||||
cert_passwd = strchr(filename,',');
|
||||
if (cert_passwd)
|
||||
{
|
||||
*cert_passwd=0;
|
||||
cert_passwd++;
|
||||
}
|
||||
|
||||
/* convert ip and port string to network rappresentation*/
|
||||
service = g_malloc(sizeof(SslService) + 4);
|
||||
service->addr.type = AT_IPv4;
|
||||
service->addr.len = 4;
|
||||
service->addr.data = ip = ((guchar*)service) + sizeof(SslService);
|
||||
|
||||
/* remove all spaces in addr */
|
||||
read_index = 0;
|
||||
write_index = 0;
|
||||
|
||||
while(addr[read_index]) {
|
||||
if (addr[read_index] != ' ') {
|
||||
addr[write_index] = addr[read_index];
|
||||
write_index++;
|
||||
if(addr_type[at] == AT_IPv4) {
|
||||
if (strcmp(uats->ipaddr, "any") == 0 || strcmp(uats->ipaddr, "anyipv4") == 0 ||
|
||||
get_host_ipaddr(uats->ipaddr, &addr_data[0])) {
|
||||
addr_len = 4;
|
||||
}
|
||||
} else { /* AT_IPv6 */
|
||||
if(strcmp(uats->ipaddr, "any") == 0 || strcmp(uats->ipaddr, "anyipv6") == 0 ||
|
||||
get_host_ipaddr6(uats->ipaddr, (struct e_in6_addr *) addr_data)) {
|
||||
addr_len = 16;
|
||||
}
|
||||
read_index++;
|
||||
}
|
||||
addr[write_index] = 0;
|
||||
|
||||
if ( !strcmp("any", addr) || !strcmp("ANY", addr) ) {
|
||||
ip[0] = 0;
|
||||
ip[1] = 0;
|
||||
ip[2] = 0;
|
||||
ip[3] = 0;
|
||||
} else {
|
||||
guint tmp0, tmp1, tmp2, tmp3;
|
||||
|
||||
sscanf(addr, "%u.%u.%u.%u", &tmp0, &tmp1, &tmp2, &tmp3);
|
||||
ip[0] = (guchar)tmp0;
|
||||
ip[1] = (guchar)tmp1;
|
||||
ip[2] = (guchar)tmp2;
|
||||
ip[3] = (guchar)tmp3;
|
||||
}
|
||||
|
||||
if(!strcmp("start_tls", port)) {
|
||||
if (! addr_len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
service = g_malloc(sizeof(SslService) + addr_len);
|
||||
service->addr.type = addr_type[at];
|
||||
service->addr.len = addr_len;
|
||||
service->addr.data = ((guchar*)service) + sizeof(SslService);
|
||||
memcpy((void*)service->addr.data, addr_data, addr_len);
|
||||
|
||||
if(strcmp(uats->port,"start_tls")==0) {
|
||||
service->port = 0;
|
||||
} else {
|
||||
service->port = atoi(port);
|
||||
}
|
||||
ssl_debug_printf("ssl_init addr '%u.%u.%u.%u' port '%d' filename '%s' password(only for p12 file) '%s'\n",
|
||||
ip[0], ip[1], ip[2], ip[3], service->port, filename, cert_passwd ? cert_passwd : "(null)");
|
||||
|
||||
/* try to load pen or p12 file*/
|
||||
fp = ws_fopen(filename, "rb");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "can't open file %s \n",filename);
|
||||
continue;
|
||||
service->port = atoi(uats->port);
|
||||
}
|
||||
|
||||
if (!cert_passwd) {
|
||||
private_key = ssl_load_key(fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
private_key = ssl_load_pkcs12(fp,cert_passwd);
|
||||
}
|
||||
/* !!! */
|
||||
if (!private_key) {
|
||||
fprintf(stderr,"can't load private key from %s\n",
|
||||
filename);
|
||||
fclose(fp);
|
||||
continue;
|
||||
}
|
||||
ssl_debug_printf("ssl_init %s addr '%s' (%s) port '%d' filename '%s' password(only for p12 file) '%s'\n",
|
||||
(addr_type[at] == AT_IPv4) ? "IPv4" : "IPv6", uats->ipaddr, ep_address_to_str(&service->addr),
|
||||
service->port, uats->keyfile, uats->password);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
ssl_debug_printf("ssl_init private key file %s successfully loaded\n",filename);
|
||||
ssl_debug_printf("ssl_init private key file %s successfully loaded.\n", uats->keyfile);
|
||||
|
||||
/* if item exists, remove first */
|
||||
tmp_private_key = g_hash_table_lookup(key_hash, service);
|
||||
|
@ -3285,12 +3230,11 @@ ssl_parse_key_list(const gchar * keys_list, GHashTable *key_hash, GTree* associa
|
|||
g_hash_table_remove(key_hash, service);
|
||||
ssl_free_key(tmp_private_key);
|
||||
}
|
||||
|
||||
g_hash_table_insert(key_hash, service, private_key);
|
||||
|
||||
ssl_association_add(associations, handle, service->port, protocol, tcp, TRUE);
|
||||
|
||||
} while (end != NULL);
|
||||
g_free(tmp);
|
||||
ssl_association_add(associations, handle, service->port, uats->protocol, tcp, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/* store master secret into session data cache */
|
||||
|
@ -3423,3 +3367,114 @@ ssl_print_string(const gchar* name, const StringInfo* data)
|
|||
ssl_print_data(name, data->data, data->data_len);
|
||||
}
|
||||
#endif /* SSL_DECRYPT_DEBUG */
|
||||
|
||||
/* checks for SSL and DTLS UAT key list fields */
|
||||
|
||||
gboolean
|
||||
ssldecrypt_uat_fld_ip_chk_cb(void* r _U_, const char* p, unsigned len _U_, const void* u1 _U_, const void* u2 _U_, const char** err)
|
||||
{
|
||||
|
||||
if ((gint)strlen(p) == 0) {
|
||||
*err = ep_strdup_printf("No IP address given.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*err = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ssldecrypt_uat_fld_port_chk_cb(void* r _U_, const char* p, unsigned len _U_, const void* u1 _U_, const void* u2 _U_, const char** err)
|
||||
{
|
||||
guint i;
|
||||
|
||||
if ((gint)strlen(p) == 0) {
|
||||
*err = ep_strdup_printf("No Port given.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (strcmp(p, "start_tls") != 0){
|
||||
i = atoi(p);
|
||||
if (i <= 0) {
|
||||
*err = ep_strdup_printf("Invalid port given.");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
*err = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ssldecrypt_uat_fld_protocol_chk_cb(void* r _U_, const char* p, unsigned len _U_, const void* u1 _U_, const void* u2 _U_, const char** err)
|
||||
{
|
||||
if ((gint)strlen(p) == 0) {
|
||||
*err = ep_strdup_printf("No protocol given.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!find_dissector(p)) {
|
||||
*err = ep_strdup_printf("Could not find dissector for: '%s'", p);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*err = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ssldecrypt_uat_fld_fileopen_chk_cb(void* r _U_, const char* p, unsigned len _U_, const void* u1 _U_, const void* u2 _U_, const char** err)
|
||||
{
|
||||
ws_statb64 st;
|
||||
|
||||
if ((gint)strlen(p) == 0) {
|
||||
*err = ep_strdup_printf("No filename given.");
|
||||
return FALSE;
|
||||
} else {
|
||||
if (ws_stat64(p, &st) != 0) {
|
||||
*err = ep_strdup_printf("File '%s' does not exist or access is denied.", p);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
*err = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ssldecrypt_uat_fld_password_chk_cb(void* r _U_, const char* p, unsigned len _U_, const void* u1 _U_, const void* u2 _U_, const char** err)
|
||||
{
|
||||
ssldecrypt_assoc_t* f = r;
|
||||
FILE *fp = NULL;
|
||||
|
||||
if ((gint)strlen(p) > 0) {
|
||||
fp = ws_fopen(f->keyfile, "rb");
|
||||
if (fp) {
|
||||
if (!ssl_load_pkcs12(fp, p)) {
|
||||
fclose(fp);
|
||||
*err = ep_strdup_printf("Invalid. Password is necessary only if you use PKCS#12 key file.");
|
||||
return FALSE;
|
||||
}
|
||||
fclose(fp);
|
||||
} else {
|
||||
*err = ep_strdup_printf("Leave this field blank if the keyfile is not PKCS#12.");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
*err = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=4 tabstop=8 expandtab
|
||||
* :indentSize=4:tabSize=8:noTabs=true:
|
||||
*/
|
||||
|
|
|
@ -346,6 +346,21 @@ typedef struct _Ssl_private_key {
|
|||
SSL_PRIVATE_KEY *sexp_pkey;
|
||||
} Ssl_private_key_t;
|
||||
|
||||
/* User Access Table */
|
||||
typedef struct _ssldecrypt_assoc_t {
|
||||
char* ipaddr;
|
||||
char* port;
|
||||
char* protocol;
|
||||
char* keyfile;
|
||||
char* password;
|
||||
} ssldecrypt_assoc_t;
|
||||
|
||||
gboolean ssldecrypt_uat_fld_ip_chk_cb(void*, const char*, unsigned, const void*, const void*, const char** err);
|
||||
gboolean ssldecrypt_uat_fld_port_chk_cb(void*, const char*, unsigned, const void*, const void*, const char** err);
|
||||
gboolean ssldecrypt_uat_fld_protocol_chk_cb(void*, const char*, unsigned, const void*, const void*, const char** err);
|
||||
gboolean ssldecrypt_uat_fld_fileopen_chk_cb(void*, const char*, unsigned, const void*, const void*, const char** err);
|
||||
gboolean ssldecrypt_uat_fld_password_chk_cb(void*, const char*, unsigned, const void*, const void*, const char** err);
|
||||
|
||||
/** Initialize decryption engine/ssl layer. To be called once per execution */
|
||||
extern void
|
||||
ssl_lib_init(void);
|
||||
|
@ -487,7 +502,7 @@ ssl_common_init(GHashTable **session_hash, StringInfo *decrypted_data, StringInf
|
|||
|
||||
/* parse ssl related preferences (private keys and ports association strings) */
|
||||
extern void
|
||||
ssl_parse_key_list(const gchar * keys_list, GHashTable *key_hash, GTree* associations, dissector_handle_t handle, gboolean tcp);
|
||||
ssl_parse_key_list(const ssldecrypt_assoc_t * uats, GHashTable *key_hash, GTree* associations, dissector_handle_t handle, gboolean tcp);
|
||||
|
||||
/* store master secret into session data cache */
|
||||
extern void
|
||||
|
@ -525,6 +540,19 @@ ssl_debug_printf(const gchar* fmt _U_,...)
|
|||
#define ssl_set_debug(name)
|
||||
#define ssl_debug_flush()
|
||||
|
||||
#endif
|
||||
#endif /* SSL_DECRYPT_DEBUG */
|
||||
|
||||
#endif
|
||||
#endif /* SSL_UTILS_H */
|
||||
|
||||
/*
|
||||
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=4 tabstop=8 expandtab
|
||||
* :indentSize=4:tabSize=8:noTabs=true:
|
||||
*/
|
||||
|
|
|
@ -129,7 +129,10 @@
|
|||
#include "packet-ssl.h"
|
||||
#include "packet-ssl-utils.h"
|
||||
#include <wsutil/file_util.h>
|
||||
#include <epan/uat.h>
|
||||
|
||||
static ssldecrypt_assoc_t *sslkeylist_uats = NULL;
|
||||
static guint nssldecrypt = 0;
|
||||
|
||||
static gboolean ssl_desegment = TRUE;
|
||||
static gboolean ssl_desegment_app_data = TRUE;
|
||||
|
@ -294,6 +297,7 @@ static StringInfo ssl_compressed_data = {NULL, 0};
|
|||
static StringInfo ssl_decrypted_data = {NULL, 0};
|
||||
static gint ssl_decrypted_data_avail = 0;
|
||||
|
||||
static uat_t *ssldecrypt_uat = NULL;
|
||||
static gchar* ssl_keys_list = NULL;
|
||||
static gchar* ssl_psk = NULL;
|
||||
|
||||
|
@ -318,9 +322,20 @@ ssl_fragment_init(void)
|
|||
static void
|
||||
ssl_init(void)
|
||||
{
|
||||
module_t *ssl_module = prefs_find_module("ssl");
|
||||
pref_t *keys_list_pref;
|
||||
|
||||
ssl_common_init(&ssl_session_hash, &ssl_decrypted_data, &ssl_compressed_data);
|
||||
ssl_fragment_init();
|
||||
ssl_debug_flush();
|
||||
|
||||
/* We should have loaded "keys_list" by now. Mark it obsolete */
|
||||
if (ssl_module) {
|
||||
keys_list_pref = prefs_find_preference(ssl_module, "keys_list");
|
||||
if (! prefs_get_preference_obsolete(keys_list_pref)) {
|
||||
prefs_set_preference_obsolete(keys_list_pref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* parse ssl related preferences (private keys and ports association strings) */
|
||||
|
@ -329,12 +344,9 @@ ssl_parse(void)
|
|||
{
|
||||
ep_stack_t tmp_stack;
|
||||
SslAssociation *tmp_assoc;
|
||||
FILE *ssl_keys_file;
|
||||
struct stat statb;
|
||||
size_t size;
|
||||
gchar *tmp_buf;
|
||||
size_t nbytes;
|
||||
gboolean read_failed;
|
||||
guint i;
|
||||
gchar **old_keys, **parts, *err;
|
||||
GString *uat_entry = g_string_new("");
|
||||
|
||||
ssl_set_debug(ssl_debug_file_name);
|
||||
|
||||
|
@ -354,30 +366,32 @@ ssl_parse(void)
|
|||
/* 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);
|
||||
|
||||
if (ssl_keys_list && (ssl_keys_list[0] != 0))
|
||||
{
|
||||
if (file_exists(ssl_keys_list)) {
|
||||
if ((ssl_keys_file = ws_fopen(ssl_keys_list, "r"))) {
|
||||
read_failed = FALSE;
|
||||
fstat(fileno(ssl_keys_file), &statb);
|
||||
size = (size_t)statb.st_size;
|
||||
tmp_buf = ep_alloc0(size + 1);
|
||||
nbytes = fread(tmp_buf, 1, size, ssl_keys_file);
|
||||
if (ferror(ssl_keys_file)) {
|
||||
report_read_failure(ssl_keys_list, errno);
|
||||
read_failed = TRUE;
|
||||
/* Import old-style keys */
|
||||
if (ssldecrypt_uat && ssl_keys_list && ssl_keys_list[0]) {
|
||||
old_keys = g_strsplit(ssl_keys_list, ";", 0);
|
||||
for (i = 0; old_keys[i] != NULL; i++) {
|
||||
parts = g_strsplit(old_keys[i], ",", 4);
|
||||
if (parts[0] && parts[1] && parts[2] && parts[3]) {
|
||||
g_string_printf(uat_entry, "\"%s\",\"%s\",\"%s\",\"%s\",\"\"",
|
||||
parts[0], parts[1], parts[2], parts[3]);
|
||||
if (!uat_load_str(ssldecrypt_uat, uat_entry->str, &err)) {
|
||||
ssl_debug_printf("ssl_parse: Can't load UAT string %s: %s\n",
|
||||
uat_entry->str, err);
|
||||
}
|
||||
fclose(ssl_keys_file);
|
||||
tmp_buf[nbytes] = '\0';
|
||||
if (!read_failed)
|
||||
ssl_parse_key_list(tmp_buf,ssl_key_hash,ssl_associations,ssl_handle,TRUE);
|
||||
} else {
|
||||
report_open_failure(ssl_keys_list, errno, FALSE);
|
||||
}
|
||||
} else {
|
||||
ssl_parse_key_list(ssl_keys_list,ssl_key_hash,ssl_associations,ssl_handle,TRUE);
|
||||
g_strfreev(parts);
|
||||
}
|
||||
g_strfreev(old_keys);
|
||||
}
|
||||
g_string_free(uat_entry, TRUE);
|
||||
|
||||
if (nssldecrypt > 0) {
|
||||
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_debug_flush();
|
||||
}
|
||||
|
||||
|
@ -832,20 +846,20 @@ again:
|
|||
* the pdu).
|
||||
*/
|
||||
if ((msp = se_tree_lookup32(flow->multisegment_pdus, seq))) {
|
||||
const char* str;
|
||||
const char* str;
|
||||
|
||||
if (msp->first_frame == PINFO_FD_NUM(pinfo)) {
|
||||
str = "";
|
||||
col_set_str(pinfo->cinfo, COL_INFO, "[SSL segment of a reassembled PDU]");
|
||||
} else {
|
||||
str = "Retransmitted ";
|
||||
}
|
||||
if (msp->first_frame == PINFO_FD_NUM(pinfo)) {
|
||||
str = "";
|
||||
col_set_str(pinfo->cinfo, COL_INFO, "[SSL segment of a reassembled PDU]");
|
||||
} else {
|
||||
str = "Retransmitted ";
|
||||
}
|
||||
|
||||
nbytes = tvb_reported_length_remaining(tvb, offset);
|
||||
proto_tree_add_text(tree, tvb, offset, nbytes,
|
||||
"%sSSL segment data (%u byte%s)",
|
||||
str, nbytes, plurality(nbytes, "", "s"));
|
||||
return;
|
||||
nbytes = tvb_reported_length_remaining(tvb, offset);
|
||||
proto_tree_add_text(tree, tvb, offset, nbytes,
|
||||
"%sSSL segment data (%u byte%s)",
|
||||
str, nbytes, plurality(nbytes, "", "s"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Else, find the most previous PDU starting before this sequence number */
|
||||
|
@ -946,7 +960,7 @@ again:
|
|||
/* create a new TVB structure for desegmented data */
|
||||
next_tvb = tvb_new_child_real_data(tvb, ipfd_head->data,
|
||||
ipfd_head->datalen,
|
||||
ipfd_head->datalen);
|
||||
ipfd_head->datalen);
|
||||
|
||||
/* add desegmented data to the data source list */
|
||||
add_new_data_source(pinfo, next_tvb, "Reassembled SSL");
|
||||
|
@ -1030,7 +1044,7 @@ again:
|
|||
* a higher-level PDU, but the data at the
|
||||
* end of this segment started a higher-level
|
||||
* PDU but didn't complete it.
|
||||
*
|
||||
*
|
||||
* If so, we have to create some structures
|
||||
* in our table, but this is something we
|
||||
* only do the first time we see this packet.
|
||||
|
@ -1042,12 +1056,12 @@ again:
|
|||
/* The stuff we couldn't dissect
|
||||
* must have come from this segment,
|
||||
* so it's all in "tvb".
|
||||
*
|
||||
*
|
||||
* "pinfo->desegment_offset" is
|
||||
* relative to the beginning of
|
||||
* "next_tvb"; we want an offset
|
||||
* relative to the beginning of "tvb".
|
||||
*
|
||||
*
|
||||
* First, compute the offset relative
|
||||
* to the *end* of "next_tvb" - i.e.,
|
||||
* the number of bytes before the end
|
||||
|
@ -1067,7 +1081,7 @@ again:
|
|||
* is also the offset relative to
|
||||
* the end of "tvb" of the byte at
|
||||
* which we stopped.
|
||||
*
|
||||
*
|
||||
* Convert that back into an offset
|
||||
* relative to the beginninng of
|
||||
* "tvb", by taking the length of
|
||||
|
@ -1104,19 +1118,19 @@ again:
|
|||
|
||||
if (((nxtseq - deseg_seq) <= 1024*1024)
|
||||
&& (!PINFO_FD_VISITED(pinfo))) {
|
||||
if(pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT) {
|
||||
/* The subdissector asked to reassemble using the
|
||||
if(pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT) {
|
||||
/* The subdissector asked to reassemble using the
|
||||
* entire next segment.
|
||||
* Just ask reassembly for one more byte
|
||||
* but set this msp flag so we can pick it up
|
||||
* above.
|
||||
*/
|
||||
msp = pdu_store_sequencenumber_of_next_pdu(pinfo,
|
||||
deseg_seq, nxtseq+1, flow->multisegment_pdus);
|
||||
msp = pdu_store_sequencenumber_of_next_pdu(pinfo,
|
||||
deseg_seq, nxtseq+1, flow->multisegment_pdus);
|
||||
msp->flags |= MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT;
|
||||
} else {
|
||||
msp = pdu_store_sequencenumber_of_next_pdu(pinfo,
|
||||
deseg_seq, nxtseq+pinfo->desegment_len, flow->multisegment_pdus);
|
||||
deseg_seq, nxtseq+pinfo->desegment_len, flow->multisegment_pdus);
|
||||
}
|
||||
|
||||
/* add this segment as the first one for this new pdu */
|
||||
|
@ -2828,7 +2842,7 @@ dissect_ssl2_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
* that will break reassembly.
|
||||
*/
|
||||
pinfo->desegment_offset = offset;
|
||||
pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
|
||||
pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
|
||||
*need_desegmentation = TRUE;
|
||||
return offset;
|
||||
}
|
||||
|
@ -4191,6 +4205,48 @@ ssl_looks_like_valid_pct_handshake(tvbuff_t *tvb, const guint32 offset,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* UAT */
|
||||
|
||||
static void
|
||||
ssldecrypt_free_cb(void* r)
|
||||
{
|
||||
ssldecrypt_assoc_t* h = r;
|
||||
|
||||
g_free(h->ipaddr);
|
||||
g_free(h->port);
|
||||
g_free(h->protocol);
|
||||
g_free(h->keyfile);
|
||||
g_free(h->password);
|
||||
}
|
||||
|
||||
static void
|
||||
ssldecrypt_update_cb(void* r _U_, const char** err)
|
||||
{
|
||||
if (err)
|
||||
*err = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
static void*
|
||||
ssldecrypt_copy_cb(void* dest, const void* orig, size_t len _U_)
|
||||
{
|
||||
const ssldecrypt_assoc_t* o = orig;
|
||||
ssldecrypt_assoc_t* d = dest;
|
||||
|
||||
d->ipaddr = g_strdup(o->ipaddr);
|
||||
d->port = g_strdup(o->port);
|
||||
d->protocol = g_strdup(o->protocol);
|
||||
d->keyfile = g_strdup(o->keyfile);
|
||||
d->password = g_strdup(o->password);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
UAT_CSTRING_CB_DEF(sslkeylist_uats,ipaddr,ssldecrypt_assoc_t)
|
||||
UAT_CSTRING_CB_DEF(sslkeylist_uats,port,ssldecrypt_assoc_t)
|
||||
UAT_CSTRING_CB_DEF(sslkeylist_uats,protocol,ssldecrypt_assoc_t)
|
||||
UAT_CSTRING_CB_DEF(sslkeylist_uats,keyfile,ssldecrypt_assoc_t)
|
||||
UAT_CSTRING_CB_DEF(sslkeylist_uats,password,ssldecrypt_assoc_t)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
|
@ -4723,6 +4779,48 @@ proto_register_ssl(void)
|
|||
|
||||
{
|
||||
module_t *ssl_module = prefs_register_protocol(proto_ssl, proto_reg_handoff_ssl);
|
||||
|
||||
#ifdef HAVE_LIBGNUTLS
|
||||
|
||||
static uat_field_t sslkeylist_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, keyfile, "Key File", ssldecrypt_uat_fld_fileopen_chk_cb, "Private keyfile."),
|
||||
UAT_FLD_CSTRING_OTHER(sslkeylist_uats, password,"Password", ssldecrypt_uat_fld_password_chk_cb, "Password (for PCKS#12 keyfile)"),
|
||||
UAT_END_FIELDS
|
||||
};
|
||||
|
||||
ssldecrypt_uat = uat_new("SSL Decrypt",
|
||||
sizeof(ssldecrypt_assoc_t),
|
||||
"ssl_keys", /* filename */
|
||||
TRUE, /* from_profile */
|
||||
(void*) &sslkeylist_uats, /* data_ptr */
|
||||
&nssldecrypt, /* numitems_ptr */
|
||||
UAT_CAT_FFMT, /* category */
|
||||
NULL, /* Help section (currently a wiki page) */
|
||||
ssldecrypt_copy_cb,
|
||||
ssldecrypt_update_cb,
|
||||
ssldecrypt_free_cb,
|
||||
NULL,
|
||||
sslkeylist_uats_flds);
|
||||
|
||||
prefs_register_uat_preference(ssl_module, "key_table",
|
||||
"RSA keys list",
|
||||
"A table of RSA keys for SSL decryption",
|
||||
ssldecrypt_uat);
|
||||
|
||||
prefs_register_string_preference(ssl_module, "debug_file", "SSL debug file",
|
||||
"Redirect SSL debug to file name; leave empty to disable debugging, "
|
||||
"or use \"" SSL_DEBUG_USE_STDERR "\" to redirect output to stderr\n",
|
||||
(const gchar **)&ssl_debug_file_name);
|
||||
|
||||
prefs_register_string_preference(ssl_module, "keys_list", "RSA keys list (deprecated)",
|
||||
"Semicolon-separated list of private RSA keys used for SSL decryption. "
|
||||
"Used by versions of Wireshark prior to 1.6",
|
||||
(const gchar **)&ssl_keys_list);
|
||||
#endif
|
||||
|
||||
prefs_register_bool_preference(ssl_module,
|
||||
"desegment_ssl_records",
|
||||
"Reassemble SSL records spanning multiple TCP segments",
|
||||
|
@ -4735,22 +4833,13 @@ proto_register_ssl(void)
|
|||
"Whether the SSL dissector should reassemble SSL Application Data spanning multiple SSL records. ",
|
||||
&ssl_desegment_app_data);
|
||||
#ifdef HAVE_LIBGNUTLS
|
||||
prefs_register_string_preference(ssl_module, "keys_list", "RSA keys list",
|
||||
"Semicolon-separated list of private RSA keys used for SSL decryption; "
|
||||
"each list entry must be in the form of <ip>,<port>,<protocol>,<key_file_name>. "
|
||||
"<key_file_name> is the local file name of the RSA private key used by the specified server "
|
||||
"(or name of the file containing such a list)",
|
||||
(const gchar **)&ssl_keys_list);
|
||||
prefs_register_string_preference(ssl_module, "debug_file", "SSL debug file",
|
||||
"Redirect SSL debug to file name; leave empty to disable debugging, "
|
||||
"or use \"" SSL_DEBUG_USE_STDERR "\" to redirect output to stderr\n",
|
||||
(const gchar **)&ssl_debug_file_name);
|
||||
prefs_register_string_preference(ssl_module, "psk", "Pre-Shared-Key",
|
||||
"Pre-Shared-Key as HEX string, should be 0 to 16 bytes",
|
||||
(const gchar **)&ssl_psk);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
register_dissector("ssl", dissect_ssl, proto_ssl);
|
||||
ssl_handle = find_dissector("ssl");
|
||||
|
||||
|
@ -4798,3 +4887,16 @@ ssl_dissector_delete(guint port, const gchar *protocol, gboolean tcp)
|
|||
ssl_association_remove(ssl_associations, assoc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=4 tabstop=8 expandtab
|
||||
* :indentSize=4:tabSize=8:noTabs=true:
|
||||
*/
|
||||
|
|
25
epan/prefs.c
25
epan/prefs.c
|
@ -828,6 +828,31 @@ prefs_register_obsolete_preference(module_t *module, const char *name)
|
|||
register_preference(module, name, NULL, NULL, PREF_OBSOLETE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if a preference is obsolete.
|
||||
*/
|
||||
extern gboolean
|
||||
prefs_get_preference_obsolete(pref_t *pref)
|
||||
{
|
||||
if (pref) {
|
||||
return pref->type == PREF_OBSOLETE ? TRUE : FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a preference obsolete.
|
||||
*/
|
||||
extern prefs_set_pref_e
|
||||
prefs_set_preference_obsolete(pref_t *pref)
|
||||
{
|
||||
if (pref) {
|
||||
pref->type = PREF_OBSOLETE;
|
||||
return PREFS_SET_OK;
|
||||
}
|
||||
return PREFS_SET_NO_SUCH_PREF;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call a callback function, with a specified argument, for each preference
|
||||
* in a given module.
|
||||
|
|
10
epan/prefs.h
10
epan/prefs.h
|
@ -373,6 +373,7 @@ extern void prefs_register_uat_preference(module_t *module,
|
|||
extern void prefs_register_obsolete_preference(module_t *module,
|
||||
const char *name);
|
||||
|
||||
|
||||
typedef guint (*pref_cb)(pref_t *pref, gpointer user_data);
|
||||
|
||||
/*
|
||||
|
@ -443,6 +444,15 @@ typedef enum {
|
|||
|
||||
extern prefs_set_pref_e prefs_set_pref(char *prefarg);
|
||||
|
||||
/*
|
||||
* Get or set a preference's obsolete status. These can be used to make a
|
||||
* preference obsolete after startup so that we can fetch its value but
|
||||
* keep it from showing up in the prefrences dialog.
|
||||
*/
|
||||
extern gboolean prefs_get_preference_obsolete(pref_t *pref);
|
||||
extern prefs_set_pref_e prefs_set_preference_obsolete(pref_t *pref);
|
||||
|
||||
|
||||
/*
|
||||
* Returns TRUE if the given device is hidden
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue