stun: Tighten heuristic by rejecting restricted values

Reject the previous reserved and unassigned TURN channels and
STUN methods restricted by RFC 5764 and RFC 7983 to allow
multiplexing of STUN with DTLS-SRTP (and ZRTP) on the same
addresses and ports. (As an exception, allow the special MS
Multiplex TURN channel value.) Earlier versions of the specs
had these as unassigned (or did not support TURN Channels), and
no implementation has used them.

This prevents the STUN dissector from claiming RTP packets
going to the same port as set for STUN by Decode As, and should
allow us to set the STUN dissector as the dissector for a conversation
on UDP if we see any STUN message, not just a TURN message type.
This commit is contained in:
John Thacker 2022-06-27 08:38:35 -04:00
parent 1433104479
commit 26b0a0a8d3
1 changed files with 38 additions and 12 deletions

View File

@ -66,6 +66,7 @@ void proto_reg_handoff_stun(void);
* ===============================================================================================
* Message | 0b00+14-bit | 16-bit | 0b00+14-bit, type= | |
* Type | No class or method | No class or method | class+method | |
* | | | Method: 0x000-0xFFF| Method: 0x000-0x0FF|
* -----------------------------------------------------------------------------------------------
* Transac- | 128 bits, seen | 128 bits | 32 bit Magic + | |
* tion ID | with MAGIC as well | | 96 bit Trans ID | |
@ -291,6 +292,9 @@ typedef struct _stun_conv_info_t {
#define GOOG_PING 0x0080 /* Google undocumented */
/* 0x080-0x0FF Expert Review */
/* 0x100-0xFFF Reserved (for DTLS-SRTP multiplexing collision avoidance,
* see RFC7983. Cannot be made available for assignment without IETF Review.)
*/
/* Attribute Types */
/* 0x0000-0x3FFF IETF Review comprehension-required range */
@ -418,6 +422,8 @@ typedef struct _stun_conv_info_t {
#define GOOG_LOGGING_ID 0xff05
/* 0xff06-0xffff Unassigned */
#define MS_MULTIPLEX_TURN 0xFF10
/* Initialize the subtree pointers */
static gint ett_stun = -1;
static gint ett_stun_type = -1;
@ -766,11 +772,11 @@ dissect_stun_message_channel_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree
proto_tree_add_item(stun_tree, hf_stun_channel, tvb, 0, 2, ENC_BIG_ENDIAN);
proto_tree_add_item(stun_tree, hf_stun_length, tvb, 2, 2, ENC_BIG_ENDIAN);
/* MS-TURN Multiplexed TURN Channel */
if (msg_type == 0xFF10 && msg_length >= 8) {
if (msg_type == MS_MULTIPLEX_TURN && msg_length >= 8) {
proto_tree_add_item(stun_tree, hf_stun_att_ms_turn_session_id, tvb, 4, 8, ENC_NA);
}
}
if (msg_type == 0xFF10 && msg_length >= 8) {
if (msg_type == MS_MULTIPLEX_TURN && msg_length >= 8) {
msg_length -= 8;
offset += 8;
}
@ -849,14 +855,25 @@ dissect_stun_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboole
if (msg_type & 0xC000) {
/* two first bits not NULL => should be a channel-data message */
/* XXX: As of RFC 8656, Channel numbers outside the range 0x4000-0x4FFF
* MUST be dropped, whereas in RFC 5766 implementations MUST NOT drop
* reserved channel numbers. Rejecting such channel numbers (in particular
* the range 0x8000-0xBFFF) allows multiplexing with DTLS-SRTP on the
* same 5-tuple by preventing collisions. That would also allow us to
* set the conversation for non-heuristic STUN dissection on UDP if we
* see any STUN message, not just a TURN message type.
/* RFC 5764 defined a demultiplexing scheme to allow STUN to co-exist
* on the same 5-tuple as DTLS-SRTP (and ZRTP) by rejecting previously
* reserved channel numbers and method types, implicitly restricting
* channel numbers to 0x4000-0x7FFF. RFC 5766 did not incorporate this
* restriction, instead indicating that reserved numbers MUST NOT be
* dropped.
* RFCs 7983, 8489, and 8656 reconciled this and formally indicated
* that channel numbers in the reserved range MUST be dropped, while
* further restricting the channel numbers to 0x4000-0x4FFF.
* Reject the range 0x8000-0xFFFF, except for the special
* MS-TURN multiplex channel number, since no implementation has
* used any other value in that range.
* This allows us to set the conversation for non-heuristic STUN
* dissection on UDP if we see any STUN message, not just a TURN
* message type.
*/
if (msg_type & 0x8000 && msg_type != MS_MULTIPLEX_TURN) {
return 0;
}
/*
* If the packet is being dissected through heuristics, we never match
@ -889,6 +906,18 @@ dissect_stun_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboole
if (captured_length < STUN_HDR_LEN)
return 0;
msg_type_class = ((msg_type & 0x0010) >> 4) | ((msg_type & 0x0100) >> 7) ;
msg_type_method = (msg_type & 0x000F) | ((msg_type & 0x00E0) >> 1) | ((msg_type & 0x3E00) >> 2);
if (msg_type_method > 0xFF) {
/* "Reserved for DTLS-SRTP multiplexing collision avoidance, see RFC
* 7983. Cannot be made available for assignment without IETF Review."
* Even though not reserved until RFC 7983, these have never been
* assigned or used, including by MS-TURN.
*/
return 0;
}
/* Check if it is really a STUN message - reject messages without the
* RFC 5389 Magic and let the classicstun dissector handle those.
*/
@ -914,9 +943,6 @@ dissect_stun_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboole
transaction_id_key[1].length = 0;
transaction_id_key[1].key = NULL;
msg_type_class = ((msg_type & 0x0010) >> 4) | ((msg_type & 0x0100) >> 7) ;
msg_type_method = (msg_type & 0x000F) | ((msg_type & 0x00E0) >> 1) | ((msg_type & 0x3E00) >> 2);
switch (msg_type_method) {
/* if it's a TURN method, remember that */
case ALLOCATE: