diff options
author | Jakub Adam <jakub.adam@ktknet.cz> | 2016-06-29 06:40:12 +0000 |
---|---|---|
committer | Olivier CrĂȘte <olivier.crete@collabora.com> | 2016-10-26 17:50:37 -0400 |
commit | 7e5ab23cbb7b2d1e4023a8016abf4793e9606bbb (patch) | |
tree | a234c1795e53e596c66602e3fa3fffd6afd0aca6 /stun | |
parent | dab341608736327831720ac44df807ac669fbe7e (diff) | |
download | libnice-7e5ab23cbb7b2d1e4023a8016abf4793e9606bbb.tar.gz |
ms-ice: legacy FINGERPRINT mode
In order to preserve compatibility with clients which use custom CRC
lookup table from [MS-ICE2], whenever a connectivity check request or
reply is sent, an additional message is sent along. These two messages
differ only in FINGERPRINT attribute - one uses regular CRC lookup table
for calculation, the other uses the modified table.
When a message is received and FINGERPRINT doesn't pass validation using
regular CRC table, the receiver also tries to verify using the modified
table.
[MS-ICE2] 3.1.4.8.2 describes this procedure.
The commit fixes compatibility with older MSOC and Lync clients.
Differential Revision: https://phabricator.freedesktop.org/D1138
Diffstat (limited to 'stun')
-rw-r--r-- | stun/stunagent.c | 52 |
1 files changed, 38 insertions, 14 deletions
diff --git a/stun/stunagent.c b/stun/stunagent.c index 461a8e3..cd97684 100644 --- a/stun/stunagent.c +++ b/stun/stunagent.c @@ -98,13 +98,48 @@ bool stun_agent_default_validater (StunAgent *agent, } +static bool stun_agent_check_fingerprint(StunAgent *agent, StunMessage *msg) +{ + uint32_t fpr; + uint32_t crc32; + uint16_t msg_len; + + /* Looks for FINGERPRINT */ + if (stun_message_find32 (msg, STUN_ATTRIBUTE_FINGERPRINT, &fpr) != + STUN_MESSAGE_RETURN_SUCCESS) { + stun_debug ("STUN demux error: no FINGERPRINT attribute!"); + return FALSE; + } + + msg_len = stun_message_length (msg); + + /* Checks FINGERPRINT */ + crc32 = stun_fingerprint (msg->buffer, msg_len, FALSE); + fpr = ntohl (fpr); + if (fpr != crc32) { + uint16_t palen; + + /* [MS-ICE2] 3.1.4.8.2 Connectivity Checks Phase - legacy compatibility */ + if (agent->compatibility == STUN_COMPATIBILITY_MSICE2 && + stun_message_find (msg, STUN_ATTRIBUTE_MS_IMPLEMENTATION_VERSION, + &palen) == NULL && + fpr == stun_fingerprint (msg->buffer, msg_len, TRUE)) { + return TRUE; + } + + stun_debug ("STUN demux error: bad fingerprint: 0x%08x, expected: 0x%08x!", + fpr, crc32); + return FALSE; + } + + return TRUE; +} + StunValidationStatus stun_agent_validate (StunAgent *agent, StunMessage *msg, const uint8_t *buffer, size_t buffer_len, StunMessageIntegrityValidate validater, void * validater_data) { StunTransactionId msg_id; - uint32_t fpr; - uint32_t crc32; int len; uint8_t *username = NULL; uint16_t username_len; @@ -148,18 +183,7 @@ StunValidationStatus stun_agent_validate (StunAgent *agent, StunMessage *msg, if ((agent->compatibility == STUN_COMPATIBILITY_RFC5389 || agent->compatibility == STUN_COMPATIBILITY_MSICE2) && agent->usage_flags & STUN_AGENT_USAGE_USE_FINGERPRINT) { - /* Looks for FINGERPRINT */ - if (stun_message_find32 (msg, STUN_ATTRIBUTE_FINGERPRINT, &fpr) != - STUN_MESSAGE_RETURN_SUCCESS) { - stun_debug ("STUN demux error: no FINGERPRINT attribute!"); - return STUN_VALIDATION_BAD_REQUEST; - } - /* Checks FINGERPRINT */ - crc32 = stun_fingerprint (msg->buffer, stun_message_length (msg), FALSE); - fpr = ntohl (fpr); - if (fpr != crc32) { - stun_debug ("STUN demux error: bad fingerprint: 0x%08x," - " expected: 0x%08x!", fpr, crc32); + if (stun_agent_check_fingerprint(agent, msg) == FALSE) { return STUN_VALIDATION_BAD_REQUEST; } |