From e216a9e69fb2900b4da60a720111d48ff995ebc3 Mon Sep 17 00:00:00 2001 From: Gabi Date: Thu, 24 Aug 2023 13:50:54 -0300 Subject: [PATCH] relay: fix stale nonce error code (#1942) In the gateway/client we were looking at an error that looked like: ``` firezone-client-1 | 2023-08-23T20:58:50.456400Z ERROR turn::client::relay_conn: fail to refresh permissions: CreatePermission error response (error 401: Unauthorized) firezone-client-1 | 2023-08-23T20:58:50.456413Z WARN turn::client::relay_conn: refresh permissions failed ``` This was due to a slightly non-compliant behavior on the relay part where it was responding with a 401 instead of a 438 when a nonce was stale which is the behavior described by [RFC 5389](https://datatracker.ietf.org/doc/html/rfc5389#section-10.2.2) This PR should fix this and we should no longer see that refresh permissions error. --- rust/relay/src/server.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/rust/relay/src/server.rs b/rust/relay/src/server.rs index c5ce273e2..9bbc4f25f 100644 --- a/rust/relay/src/server.rs +++ b/rust/relay/src/server.rs @@ -29,7 +29,7 @@ use std::time::{Duration, SystemTime}; use stun_codec::rfc5389::attributes::{ ErrorCode, MessageIntegrity, Nonce, Realm, Username, XorMappedAddress, }; -use stun_codec::rfc5389::errors::{BadRequest, Unauthorized}; +use stun_codec::rfc5389::errors::{BadRequest, StaleNonce, Unauthorized}; use stun_codec::rfc5389::methods::BINDING; use stun_codec::rfc5766::attributes::{ ChannelNumber, Lifetime, RequestedTransport, XorPeerAddress, XorRelayAddress, @@ -296,10 +296,12 @@ where } fn queue_error_response(&mut self, sender: SocketAddr, mut error_response: Message) { - // In case of a 401 response, attach a realm and nonce. + // In case of a 401 or 438 response, attach a realm and nonce. if error_response .get_attribute::() - .map_or(false, |error| error == &ErrorCode::from(Unauthorized)) + .map_or(false, |error| { + error == &ErrorCode::from(Unauthorized) || error == &ErrorCode::from(StaleNonce) + }) { let new_nonce = Uuid::from_u128(self.rng.gen()); @@ -760,7 +762,7 @@ where self.nonces .handle_nonce_used(nonce) - .map_err(|_| error_response(Unauthorized, request))?; + .map_err(|_| error_response(StaleNonce, request))?; message_integrity .verify(&self.auth_secret, username.name(), now)