From 5e32b7136ecd8feca26c5d73479439db22310d64 Mon Sep 17 00:00:00 2001 From: Stefan Becker Date: Fri, 15 Nov 2013 08:57:08 +0200 Subject: [PATCH] http: ignore superfluous WWW-Authenticate headers Some buggy HTTP servers return more than one WWW-Authenticate headers during an authentication handshake. If we have an active security context then we only look for its header now. --- src/core/sipe-http-request.c | 46 ++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/src/core/sipe-http-request.c b/src/core/sipe-http-request.c index 21ed191d..ae3b865b 100644 --- a/src/core/sipe-http-request.c +++ b/src/core/sipe-http-request.c @@ -262,36 +262,48 @@ static gboolean sipe_http_request_response_unauthorized(struct sipe_core_private struct sipe_http_request *req, struct sipmsg *msg) { + struct sipe_http_connection_public *conn_public = req->connection; const gchar *header = NULL; guint type; gboolean failed = TRUE; + /* + * There are some buggy HTTP servers out there that add superfluous + * WWW-Authenticate: headers during the authentication handshake. + * Look only for the header of the active security context. + */ + if (conn_public->context && + ((header = sipmsg_find_auth_header(msg, + sip_sec_context_name(conn_public->context))) + != NULL)) { + type = sip_sec_context_type(conn_public->context); + + } else { #if defined(HAVE_GSSAPI_GSSAPI_H) || defined(HAVE_SSPI) #define DEBUG_STRING ", NTLM and Negotiate" - /* Use "Negotiate" unless the user requested "NTLM" */ - if (sipe_private->authentication_type != SIPE_AUTHENTICATION_TYPE_NTLM) - header = sipmsg_find_auth_header(msg, "Negotiate"); - if (header) { - type = SIPE_AUTHENTICATION_TYPE_NEGOTIATE; - } else + /* Use "Negotiate" unless the user requested "NTLM" */ + if (sipe_private->authentication_type != SIPE_AUTHENTICATION_TYPE_NTLM) + header = sipmsg_find_auth_header(msg, "Negotiate"); + if (header) { + type = SIPE_AUTHENTICATION_TYPE_NEGOTIATE; + } else #else #define DEBUG_STRING " and NTLM" - (void) sipe_private; /* keep compiler happy */ + (void) sipe_private; /* keep compiler happy */ #endif - { - header = sipmsg_find_auth_header(msg, "NTLM"); - type = SIPE_AUTHENTICATION_TYPE_NTLM; - } + { + header = sipmsg_find_auth_header(msg, "NTLM"); + type = SIPE_AUTHENTICATION_TYPE_NTLM; + } - /* only fall back to "Basic" after everything else fails */ - if (!header) { - header = sipmsg_find_auth_header(msg, "Basic"); - type = SIPE_AUTHENTICATION_TYPE_BASIC; + /* only fall back to "Basic" after everything else fails */ + if (!header) { + header = sipmsg_find_auth_header(msg, "Basic"); + type = SIPE_AUTHENTICATION_TYPE_BASIC; + } } if (header) { - struct sipe_http_connection_public *conn_public = req->connection; - if (!conn_public->context) { gboolean valid = req->flags & SIPE_HTTP_REQUEST_FLAG_AUTHDATA; conn_public->context = sip_sec_create_context(type, -- 2.11.4.GIT