summaryrefslogtreecommitdiff
path: root/socket
diff options
context:
space:
mode:
authorYouness Alaoui <kakaroto@kakaroto.(none)>2008-10-08 18:57:23 -0400
committerYouness Alaoui <kakaroto@kakaroto.(none)>2008-10-08 18:57:23 -0400
commit14ac040fb4ee5fce1fec2a516d0125f19b2e431f (patch)
treeeb19b88b98855742c3da4a941b6da159f3ac04ff /socket
parent2471c0e76a8ad29c89d5a2c5124f335e3263c885 (diff)
downloadlibnice-14ac040fb4ee5fce1fec2a516d0125f19b2e431f.tar.gz
check that we don't infinitely loop on authentication when channel bind error is received. Before resending the second request of the long term credentials, make sure we received a different nonce this time
Diffstat (limited to 'socket')
-rw-r--r--socket/udp-turn.c93
1 files changed, 71 insertions, 22 deletions
diff --git a/socket/udp-turn.c b/socket/udp-turn.c
index b195f4c..1d8cf43 100644
--- a/socket/udp-turn.c
+++ b/socket/udp-turn.c
@@ -404,31 +404,80 @@ nice_udp_turn_socket_parse_recv (
}
return 0;
} else if (stun_message_get_method (&msg) == STUN_OLD_SET_ACTIVE_DST) {
- g_free (priv->current_binding_msg);
- priv->current_binding_msg = NULL;
- if (stun_message_get_class (&msg) == STUN_RESPONSE &&
- priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_MSN)
- goto msn_google_lock;
-
- return 0;
- } else if (stun_message_get_class (&msg) == STUN_ERROR &&
- stun_message_get_method (&msg) == STUN_CHANNELBIND) {
- g_free (priv->current_binding_msg);
- priv->current_binding_msg = NULL;
- if (priv->current_binding) {
- priv_send_channel_bind (priv, &msg,
- priv->current_binding->channel, &priv->current_binding->peer);
+ stun_transid_t request_id;
+ stun_transid_t response_id;
+ if (priv->current_binding && priv->current_binding_msg) {
+ stun_message_id (&msg, response_id);
+ stun_message_id (&priv->current_binding_msg->message, request_id);
+ if (memcmp (request_id, response_id, sizeof(stun_transid_t)) == 0) {
+ g_free (priv->current_binding_msg);
+ priv->current_binding_msg = NULL;
+
+ if (stun_message_get_class (&msg) == STUN_RESPONSE &&
+ priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_MSN) {
+ goto msn_google_lock;
+ } else {
+ g_free (priv->current_binding);
+ priv->current_binding = NULL;
+ }
+ }
}
+
return 0;
- } else if (stun_message_get_class (&msg) == STUN_RESPONSE &&
- stun_message_get_method (&msg) == STUN_CHANNELBIND) {
- g_free (priv->current_binding_msg);
- priv->current_binding_msg = NULL;
- if (priv->current_binding) {
- priv->channels = g_list_append (priv->channels, priv->current_binding);
- priv->current_binding = NULL;
+ } else if (stun_message_get_method (&msg) == STUN_CHANNELBIND) {
+ stun_transid_t request_id;
+ stun_transid_t response_id;
+ if (priv->current_binding && priv->current_binding_msg) {
+ stun_message_id (&msg, response_id);
+ stun_message_id (&priv->current_binding_msg->message, request_id);
+ if (memcmp (request_id, response_id, sizeof(stun_transid_t)) == 0) {
+ if (stun_message_get_class (&msg) == STUN_ERROR) {
+ int code = -1;
+ uint8_t *sent_nonce = NULL;
+ uint8_t *recv_nonce = NULL;
+ uint16_t sent_nonce_len = 0;
+ uint16_t recv_nonce_len = 0;
+
+ sent_nonce = (uint8_t *) stun_message_find (
+ &priv->current_binding_msg->message,
+ STUN_ATTRIBUTE_NONCE, &sent_nonce_len);
+
+ recv_nonce = (uint8_t *) stun_message_find (&msg,
+ STUN_ATTRIBUTE_NONCE, &recv_nonce_len);
+
+ /* check for unauthorized error response */
+ if (stun_message_find_error (&msg, &code) == 0 &&
+ code == 401 && recv_nonce != NULL &&
+ recv_nonce_len > 0 &&
+ recv_nonce_len == sent_nonce_len &&
+ sent_nonce != NULL &&
+ memcmp (sent_nonce, recv_nonce, sent_nonce_len) == 0) {
+ g_free (priv->current_binding_msg);
+ priv->current_binding_msg = NULL;
+ if (priv->current_binding) {
+ priv_send_channel_bind (priv, &msg,
+ priv->current_binding->channel,
+ &priv->current_binding->peer);
+ }
+ } else {
+ g_free (priv->current_binding);
+ priv->current_binding = NULL;
+ g_free (priv->current_binding_msg);
+ priv->current_binding_msg = NULL;
+ priv_process_pending_bindings (priv);
+ }
+ } else if (stun_message_get_class (&msg) == STUN_RESPONSE) {
+ g_free (priv->current_binding_msg);
+ priv->current_binding_msg = NULL;
+ if (priv->current_binding) {
+ priv->channels = g_list_append (priv->channels,
+ priv->current_binding);
+ priv->current_binding = NULL;
+ }
+ priv_process_pending_bindings (priv);
+ }
+ }
}
- priv_process_pending_bindings (priv);
return 0;
} else if (stun_message_get_class (&msg) == STUN_INDICATION &&
stun_message_get_method (&msg) == STUN_IND_DATA) {