From 480fa42a000f46512adb6f6137dd71d741fcade4 Mon Sep 17 00:00:00 2001 From: Stefan Becker Date: Sun, 22 Mar 2015 15:04:59 +0200 Subject: [PATCH] transport: SIP SA always expires after 8 hours Triggered by the discussion of an endless 401 loop in https://sourceforge.net/p/sipe/discussion/688534/thread/1a259300/ The "expires" value for SIP was handled inconsistently: - NTLM: 8 hours - Kerberos: ticket expiry time, can be higher than 8 hours - TLS-DSK: certificate expiration time, max 8 hours But [MS-SIPAE] 3.2.2 "Timers" clearly states that the maximum validity of the SIP SA is 8 hours. Remove all special expires handling from other places and handle it only in process_register_response(). Also schedule the re-register event 30 seconds before the timeout. This is more in line with what we do for other timeouts already. (cherry picked from commit 80e0933b2bbd283c36efb0af43a5e7d8f45b1dc7) --- src/core/sip-sec-tls-dsk.c | 12 +----------- src/core/sip-transport.c | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/core/sip-sec-tls-dsk.c b/src/core/sip-sec-tls-dsk.c index 188c8943..70433eae 100644 --- a/src/core/sip-sec-tls-dsk.c +++ b/src/core/sip-sec-tls-dsk.c @@ -93,18 +93,8 @@ sip_sec_init_sec_context__tls_dsk(SipSecContext context, ctx->server_key = g_memdup(state->server_key, state->key_length); - /* [MS-SIPAE] Section 3.2.2 Timers - * - * ... For an SA established using the TLS-DSK - * authentication protocol, the client MUST - * retrieve the expiration time of its certificate. - * The expiration timer value is the lesser of the - * interval to the certificate expiration and eight - * hours, ... - */ + /* extract certicate expiration time */ ctx->common.expires = sipe_tls_expires(state); - if (ctx->common.expires > (8 * 60 * 60)) - ctx->common.expires = 8 * 60 * 60; SIPE_DEBUG_INFO("sip_sec_init_sec_context__tls_dsk: handshake completed, algorithm %d, key length %" G_GSIZE_FORMAT ", expires %d", ctx->algorithm, ctx->key_length, ctx->common.expires); diff --git a/src/core/sip-transport.c b/src/core/sip-transport.c index b0b05807..992b72ec 100644 --- a/src/core/sip-transport.c +++ b/src/core/sip-transport.c @@ -46,6 +46,9 @@ * this module (!) Like headers: Via, Route, Contact, Authorization, etc. * It's all irrelevant to higher layer responsibilities. * + * Specification references: + * + * - [MS-SIPAE]: http://msdn.microsoft.com/en-us/library/cc431510.aspx */ #ifdef HAVE_CONFIG_H @@ -1056,6 +1059,9 @@ static gboolean process_register_response(struct sipe_core_private *sipe_private const gchar *server_hdr = sipmsg_find_header(msg, "Server"); if (!transport->reregister_set) { + /* Schedule re-register 30 seconds before expiration */ + if (expires > 30) + expires -= 30; sip_transport_set_reregister(sipe_private, expires); transport->reregister_set = TRUE; @@ -1075,19 +1081,37 @@ static gboolean process_register_response(struct sipe_core_private *sipe_private } if (!transport->reauthenticate_set) { + /* [MS-SIPAE] Section 3.2.2 Timers + * + * When the ... authentication handshake completes + * and the SA enters the "established" state, the + * SIP protocol client MUST start an SA expiration + * timer. + * ... + * The expiration timer value is the lesser of + * + * - Kerberos: the service ticket expiry time + * - TLS-DSK: the certificate expiration time + * + * and eight hours, further reduced by some buffer + * time. + * ... + * The protocol client MUST choose a sufficient + * buffer time to allow for the ... authentication + * handshake that reestablishes the SA to complete + * ... This value SHOULD be five (5) minutes or + * longer. + */ guint reauth_timeout = transport->registrar.expires; SIPE_DEBUG_INFO_NOFORMAT("process_register_response: authentication handshake completed successfully"); - /* Does authentication scheme provide valid expiration time? */ - if (reauth_timeout == 0) { - SIPE_DEBUG_INFO_NOFORMAT("process_register_response: no expiration time - using default of 8 hours"); + if ((reauth_timeout == 0) || + (reauth_timeout > 8 * 60 * 60)) reauth_timeout = 8 * 60 * 60; - } - - /* schedule reauthentication 5 minutes before expiration */ if (reauth_timeout > 5 * 60) reauth_timeout -= 5 * 60; + sipe_schedule_seconds(sipe_private, "<+reauthentication>", NULL, -- 2.11.4.GIT