aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2018-05-26 18:42:41 -0700
committerGuy Harris <guy@alum.mit.edu>2018-05-27 01:43:27 +0000
commit5b30d5c7675fd03a420257c334808549eddc6e7e (patch)
treee4622039f3a5da1e3690cd1416199e1b5a9e99c2 /epan/dissectors
parent53a373693ccc55b6475264bd8d1fc611930d1c0f (diff)
Have a dissector table for SSL/TLS/DTLS ALPN protocol IDs.
Have dissectors register with their protocol ID string in that table, rather than having a table in epan/dissectors/packet-ssl-utils.c that has to be updated for new protocols. Have a table of protocol ID string prefixes, to handle the case of protocols such as SPDY and HTTP2 drafts, where multiple protocol IDs are used for different versions. Change-Id: I363d04895a88e779fbbca7dc8e1f31aa1970a31a Reviewed-on: https://code.wireshark.org/review/27836 Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'epan/dissectors')
-rw-r--r--epan/dissectors/packet-dtls.c4
-rw-r--r--epan/dissectors/packet-http.c6
-rw-r--r--epan/dissectors/packet-http2.c6
-rw-r--r--epan/dissectors/packet-ssl-utils.c116
-rw-r--r--epan/dissectors/packet-ssl-utils.h8
-rw-r--r--epan/dissectors/packet-ssl.c4
-rw-r--r--epan/dissectors/packet-stun.c7
-rw-r--r--epan/dissectors/packet-turnchannel.c7
8 files changed, 104 insertions, 54 deletions
diff --git a/epan/dissectors/packet-dtls.c b/epan/dissectors/packet-dtls.c
index 8735f1abe1..b7bfdbe2a1 100644
--- a/epan/dissectors/packet-dtls.c
+++ b/epan/dissectors/packet-dtls.c
@@ -1955,6 +1955,10 @@ proto_register_dtls(void)
dtls_associations = register_dissector_table("dtls.port", "DTLS Port", proto_dtls, FT_UINT16, BASE_DEC);
+ ssl_common_register_dtls_alpn_dissector_table("dtls.handshake.extensions_alpn_str",
+ "DTLS Application-Layer Protocol Negotiation (ALPN) Protocol IDs",
+ proto_dtls);
+
/* Required function calls to register the header fields and
* subtrees used */
proto_register_field_array(proto_dtls, hf, array_length(hf));
diff --git a/epan/dissectors/packet-http.c b/epan/dissectors/packet-http.c
index 85bba25eff..afe8c1fd8f 100644
--- a/epan/dissectors/packet-http.c
+++ b/epan/dissectors/packet-http.c
@@ -4098,6 +4098,12 @@ proto_reg_handoff_http(void)
ssdp_handle = create_dissector_handle(dissect_ssdp, proto_ssdp);
dissector_add_uint_with_preference("udp.port", UDP_PORT_SSDP, ssdp_handle);
+ /*
+ * SSL/TLS Application-Layer Protocol Negotiation (ALPN) protocol
+ * ID.
+ */
+ dissector_add_string("ssl.handshake.extensions_alpn_str", "http/1.1", http_ssl_handle);
+
ntlmssp_handle = find_dissector_add_dependency("ntlmssp", proto_http);
gssapi_handle = find_dissector_add_dependency("gssapi", proto_http);
sstp_handle = find_dissector_add_dependency("sstp", proto_http);
diff --git a/epan/dissectors/packet-http2.c b/epan/dissectors/packet-http2.c
index d0ffdc39b4..fe3e7c3880 100644
--- a/epan/dissectors/packet-http2.c
+++ b/epan/dissectors/packet-http2.c
@@ -3326,6 +3326,12 @@ proto_reg_handoff_http2(void)
dissector_add_for_decode_as_with_preference("tcp.port", http2_handle);
+ /*
+ * SSL/TLS Application-Layer Protocol Negotiation (ALPN) protocol
+ * ID.
+ */
+ dissector_add_string("ssl.handshake.extensions_alpn_str", "h2", http2_handle);
+
heur_dissector_add("ssl", dissect_http2_heur_ssl, "HTTP2 over SSL", "http2_ssl", proto_http2, HEURISTIC_ENABLE);
heur_dissector_add("http", dissect_http2_heur, "HTTP2 over TCP", "http2_tcp", proto_http2, HEURISTIC_ENABLE);
diff --git a/epan/dissectors/packet-ssl-utils.c b/epan/dissectors/packet-ssl-utils.c
index a693a709a2..273a8a1d8b 100644
--- a/epan/dissectors/packet-ssl-utils.c
+++ b/epan/dissectors/packet-ssl-utils.c
@@ -1402,39 +1402,26 @@ static const bytes_string ct_logids[] = {
};
/*
- * http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
+ * Application-Layer Protocol Negotiation (ALPN) dissector tables.
*/
-/* string_string is inappropriate as it compares strings while
- * "byte strings MUST NOT be truncated" (RFC 7301) */
-typedef struct ssl_alpn_protocol {
- const char *proto_name;
- gboolean match_exact;
- const char *dissector_name;
-} ssl_alpn_protocol_t;
+static dissector_table_t ssl_alpn_dissector_table;
+static dissector_table_t dtls_alpn_dissector_table;
/*
- * For SSL/TLS; the dissectors should handle running atop a byte-stream
- * protocol such as TCP.
+ * Special cases for prefix matching of the ALPN, if the ALPN includes
+ * a version number for a draft or protocol revision.
*/
-static const ssl_alpn_protocol_t ssl_alpn_protocols[] = {
- { "http/1.1", TRUE, "http" },
+typedef struct ssl_alpn_prefix_match_protocol {
+ const char *proto_prefix;
+ const char *dissector_name;
+} ssl_alpn_prefix_match_protocol_t;
+
+static const ssl_alpn_prefix_match_protocol_t ssl_alpn_prefix_match_protocols[] = {
/* SPDY moves so fast, just 1, 2 and 3 are registered with IANA but there
* already exists 3.1 as of this writing... match the prefix. */
- { "spdy/", FALSE, "spdy" },
- { "stun.turn", TRUE, "turnchannel-tcp" }, /* RFC 7443 */
- { "stun.nat-discovery", TRUE, "stun-tcp" }, /* RFC 7443 */
+ { "spdy/", "spdy" },
/* draft-ietf-httpbis-http2-16 */
- { "h2-", FALSE, "http2" }, /* draft versions */
- { "h2", TRUE, "http2" }, /* final version */
-};
-
-/*
- * For DTLS; the dissectors should handle running atop a datagram
- * protocol such as UDP.
- */
-static const ssl_alpn_protocol_t dtls_alpn_protocols[] = {
- { "stun.turn", TRUE, "turnchannel" }, /* RFC 7443 */
- { "stun.nat-discovery", TRUE, "stun-udp" }, /* RFC 7443 */
+ { "h2-", "http2" }, /* draft versions */
};
const value_string quic_transport_parameter_id[] = {
@@ -5893,9 +5880,6 @@ ssl_dissect_hnd_hello_ext_alpn(ssl_common_dissect_t *hf, tvbuff_t *tvb,
proto_item *ti;
guint32 next_offset, alpn_length, name_length;
guint8 *proto_name = NULL;
- guint32 proto_name_length = 0;
- const ssl_alpn_protocol_t *alpn_protocols;
- size_t n_alpn_protocols;
/* ProtocolName protocol_name_list<2..2^16-1> */
if (!ssl_add_vector(hf, tvb, pinfo, tree, offset, offset_end, &alpn_length,
@@ -5923,9 +5907,10 @@ ssl_dissect_hnd_hello_ext_alpn(ssl_common_dissect_t *hf, tvbuff_t *tvb,
tvb, offset, name_length, ENC_ASCII|ENC_NA);
/* Remember first ALPN ProtocolName entry for server. */
if (hnd_type == SSL_HND_SERVER_HELLO || hnd_type == SSL_HND_ENCRYPTED_EXTENSIONS) {
- proto_name_length = name_length;
+ /* '\0'-terminated string for dissector table match and prefix
+ * comparison purposes. */
proto_name = tvb_get_string_enc(wmem_packet_scope(), tvb, offset,
- proto_name_length, ENC_ASCII);
+ name_length, ENC_ASCII);
}
offset += name_length;
}
@@ -5933,31 +5918,38 @@ ssl_dissect_hnd_hello_ext_alpn(ssl_common_dissect_t *hf, tvbuff_t *tvb,
/* If ALPN is given in ServerHello, then ProtocolNameList MUST contain
* exactly one "ProtocolName". */
if (proto_name) {
- alpn_protocols = is_dtls ? dtls_alpn_protocols : ssl_alpn_protocols;
- n_alpn_protocols = is_dtls ? G_N_ELEMENTS(dtls_alpn_protocols) : G_N_ELEMENTS(ssl_alpn_protocols);
- /* '\0'-terminated string for prefix/full string comparison purposes. */
- for (size_t i = 0; i < n_alpn_protocols; i++) {
- const ssl_alpn_protocol_t *alpn_proto = &alpn_protocols[i];
-
- if ((alpn_proto->match_exact &&
- proto_name_length == strlen(alpn_proto->proto_name) &&
- !strcmp(proto_name, alpn_proto->proto_name)) ||
- (!alpn_proto->match_exact && g_str_has_prefix(proto_name, alpn_proto->proto_name))) {
-
- dissector_handle_t handle;
- /* ProtocolName match, so set the App data dissector handle.
- * This may override protocols given via the UAT dialog, but
- * since the ALPN hint is precise, do it anyway. */
- handle = ssl_find_appdata_dissector(alpn_proto->dissector_name);
- ssl_debug_printf("%s: changing handle %p to %p (%s)", G_STRFUNC,
- (void *)session->app_handle,
- (void *)handle, alpn_proto->dissector_name);
- /* if dissector is disabled, do not overwrite previous one */
- if (handle)
- session->app_handle = handle;
- break;
+ dissector_handle_t handle;
+
+ if (is_dtls) {
+ handle = dissector_get_string_handle(dtls_alpn_dissector_table,
+ proto_name);
+ } else {
+ handle = dissector_get_string_handle(ssl_alpn_dissector_table,
+ proto_name);
+ if (handle == NULL) {
+ /* Try prefix matching */
+ for (size_t i = 0; i < G_N_ELEMENTS(ssl_alpn_prefix_match_protocols); i++) {
+ const ssl_alpn_prefix_match_protocol_t *alpn_proto = &ssl_alpn_prefix_match_protocols[i];
+
+ /* string_string is inappropriate as it compares strings
+ * while "byte strings MUST NOT be truncated" (RFC 7301) */
+ if (g_str_has_prefix(proto_name, alpn_proto->proto_prefix)) {
+ handle = find_dissector(alpn_proto->dissector_name);
+ break;
+ }
+ }
}
}
+ if (handle != NULL) {
+ /* ProtocolName match, so set the App data dissector handle.
+ * This may override protocols given via the UAT dialog, but
+ * since the ALPN hint is precise, do it anyway. */
+ ssl_debug_printf("%s: changing handle %p to %p (%s)", G_STRFUNC,
+ (void *)session->app_handle,
+ (void *)handle,
+ dissector_handle_get_dissector_name(handle));
+ session->app_handle = handle;
+ }
}
return offset;
@@ -8755,6 +8747,22 @@ tls13_dissect_hnd_key_update(ssl_common_dissect_t *hf, tvbuff_t *tvb,
}
void
+ssl_common_register_ssl_alpn_dissector_table(const char *name,
+ const char *ui_name, const int proto)
+{
+ ssl_alpn_dissector_table = register_dissector_table(name, ui_name,
+ proto, FT_STRING, FALSE);
+}
+
+void
+ssl_common_register_dtls_alpn_dissector_table(const char *name,
+ const char *ui_name, const int proto)
+{
+ dtls_alpn_dissector_table = register_dissector_table(name, ui_name,
+ proto, FT_STRING, FALSE);
+}
+
+void
ssl_common_register_options(module_t *module, ssl_common_options_t *options)
{
prefs_register_string_preference(module, "psk", "Pre-Shared-Key",
diff --git a/epan/dissectors/packet-ssl-utils.h b/epan/dissectors/packet-ssl-utils.h
index 24daf2749b..2595849cf9 100644
--- a/epan/dissectors/packet-ssl-utils.h
+++ b/epan/dissectors/packet-ssl-utils.h
@@ -1987,6 +1987,14 @@ ssl_common_dissect_t name = { \
/* }}} */
extern void
+ssl_common_register_ssl_alpn_dissector_table(const char *name,
+ const char *ui_name, const int proto);
+
+extern void
+ssl_common_register_dtls_alpn_dissector_table(const char *name,
+ const char *ui_name, const int proto);
+
+extern void
ssl_common_register_options(module_t *module, ssl_common_options_t *options);
#ifdef SSL_DECRYPT_DEBUG
diff --git a/epan/dissectors/packet-ssl.c b/epan/dissectors/packet-ssl.c
index 1714063938..ec98259155 100644
--- a/epan/dissectors/packet-ssl.c
+++ b/epan/dissectors/packet-ssl.c
@@ -4647,6 +4647,10 @@ proto_register_ssl(void)
/* heuristic dissectors for any premable e.g. CredSSP before RDP */
ssl_heur_subdissector_list = register_heur_dissector_list("ssl", proto_ssl);
+ ssl_common_register_ssl_alpn_dissector_table("ssl.handshake.extensions_alpn_str",
+ "SSL/TLS Application-Layer Protocol Negotiation (ALPN) Protocol IDs",
+ proto_ssl);
+
ssl_handle = register_dissector("ssl", dissect_ssl, proto_ssl);
register_init_routine(ssl_init);
diff --git a/epan/dissectors/packet-stun.c b/epan/dissectors/packet-stun.c
index 46e5a38234..6a8734cf00 100644
--- a/epan/dissectors/packet-stun.c
+++ b/epan/dissectors/packet-stun.c
@@ -1731,6 +1731,13 @@ proto_reg_handoff_stun(void)
dissector_add_uint_with_preference("tcp.port", TCP_PORT_STUN, stun_tcp_handle);
dissector_add_uint_with_preference("udp.port", UDP_PORT_STUN, stun_udp_handle);
+ /*
+ * SSL/TLS and DTLS Application-Layer Protocol Negotiation (ALPN)
+ * protocol ID.
+ */
+ dissector_add_string("ssl.handshake.extensions_alpn_str", "stun.nat-discovery", stun_tcp_handle);
+ dissector_add_string("dtls.handshake.extensions_alpn_str", "stun.nat-discovery", stun_udp_handle);
+
heur_dissector_add("udp", dissect_stun_heur, "STUN over UDP", "stun_udp", proto_stun, HEURISTIC_ENABLE);
data_handle = find_dissector("data");
diff --git a/epan/dissectors/packet-turnchannel.c b/epan/dissectors/packet-turnchannel.c
index 339db978f3..e3c2f364f4 100644
--- a/epan/dissectors/packet-turnchannel.c
+++ b/epan/dissectors/packet-turnchannel.c
@@ -202,6 +202,13 @@ proto_reg_handoff_turnchannel(void)
dissector_add_for_decode_as_with_preference("tcp.port", turnchannel_tcp_handle);
dissector_add_for_decode_as_with_preference("udp.port", turnchannel_udp_handle);
+ /*
+ * SSL/TLS and DTLS Application-Layer Protocol Negotiation (ALPN)
+ * protocol ID.
+ */
+ dissector_add_string("ssl.handshake.extensions_alpn_str", "stun.turn", turnchannel_tcp_handle);
+ dissector_add_string("dtls.handshake.extensions_alpn_str", "stun.turn", turnchannel_udp_handle);
+
/* TURN negotiation is handled through STUN2 dissector (packet-stun.c),
so only it should be able to determine if a packet is a TURN packet */
heur_dissector_add("stun", dissect_turnchannel_heur, "TURN Channel over STUN", "turnchannel_stun", proto_turnchannel, HEURISTIC_ENABLE);