diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2022-10-07 12:41:29 +0200 |
---|---|---|
committer | Michael Stahl <michael.stahl@allotropia.de> | 2022-10-07 13:34:48 +0200 |
commit | cc77bc0e5273c6cf404851624ce5b127cdd839f4 (patch) | |
tree | 1fbb4e8b7ce1acca4cb0963d58f99624780b49e4 | |
parent | 40461c2dbb47f7432f538c7fd05da0e6916cc64e (diff) |
ucb: webdav-curl: try fallback authentication on 403 error
Sharepoint reports lack of authentication with 403 status and additional
X-MSDAVEXT_ERROR header value 0x000E0098.
Try to fallback to NTLM auth in this case, if a first attempt with
imported cookie didn't work.
Change-Id: I0d6dca2989d276262547a61784a3d0ed8bff9abd
-rw-r--r-- | ucb/source/ucp/webdav-curl/CurlSession.cxx | 58 |
1 files changed, 38 insertions, 20 deletions
diff --git a/ucb/source/ucp/webdav-curl/CurlSession.cxx b/ucb/source/ucp/webdav-curl/CurlSession.cxx index cc0a2368784f..5b2479fb1f88 100644 --- a/ucb/source/ucp/webdav-curl/CurlSession.cxx +++ b/ucb/source/ucp/webdav-curl/CurlSession.cxx @@ -1380,29 +1380,38 @@ auto CurlProcessor::ProcessRequest( ProcessHeaders(headers.HeaderFields.back().first)); // X-MSDAVEXT_Error see [MS-WEBDAVE] 2.2.3.1.9 auto const it(headerMap.find("x-msdavext_error")); + if (it == headerMap.end() || !it->second.startsWith("917656;")) + { + break; + } if (cookies.isEmpty() // retry only once - could be expired... - && rSession.m_URI.GetScheme() == "https" // only encrypted - && it != headerMap.end() - && it->second.startsWith("917656;")) + && rSession.m_URI.GetScheme() == "https") // only encrypted { - cookies = TryImportCookies(rSession.m_xContext, rSession.m_URI.GetHost()); + cookies + = TryImportCookies(rSession.m_xContext, rSession.m_URI.GetHost()); if (!cookies.isEmpty()) { - CURLcode rc = curl_easy_setopt(rSession.m_pCurl.get(), CURLOPT_COOKIEFILE, ""); + CURLcode rc = curl_easy_setopt(rSession.m_pCurl.get(), + CURLOPT_COOKIEFILE, ""); assert(rc == CURLE_OK); - rc = curl_easy_setopt(rSession.m_pCurl.get(), CURLOPT_COOKIE, cookies.getStr()); + rc = curl_easy_setopt(rSession.m_pCurl.get(), CURLOPT_COOKIE, + cookies.getStr()); assert(rc == CURLE_OK); (void)rc; isRetry = true; + SAL_INFO("ucb.ucp.webdav.curl", "FedAuth cookie set"); + break; // try cookie once } } - break; + SAL_INFO("ucb.ucp.webdav.curl", "403 fallback authentication hack"); } + [[fallthrough]]; // SP, no cookie, or cookie failed: try NTLM case SC_UNAUTHORIZED: case SC_PROXY_AUTHENTICATION_REQUIRED: { - auto& rnAuthRequests(statusCode == SC_UNAUTHORIZED ? nAuthRequests - : nAuthRequestsProxy); + auto& rnAuthRequests(statusCode != SC_PROXY_AUTHENTICATION_REQUIRED + ? nAuthRequests + : nAuthRequestsProxy); if (rnAuthRequests == 10) { SAL_INFO("ucb.ucp.webdav.curl", "aborting authentication after " @@ -1410,22 +1419,30 @@ auto CurlProcessor::ProcessRequest( } else if (pEnv && pEnv->m_xAuthListener) { - ::std::optional<OUString> const oRealm(ExtractRealm( - headers, statusCode == SC_UNAUTHORIZED ? "WWW-Authenticate" - : "Proxy-Authenticate")); + ::std::optional<OUString> const oRealm( + ExtractRealm(headers, statusCode != SC_PROXY_AUTHENTICATION_REQUIRED + ? "WWW-Authenticate" + : "Proxy-Authenticate")); ::std::optional<Auth>& roAuth( - statusCode == SC_UNAUTHORIZED ? oAuth : oAuthProxy); + statusCode != SC_PROXY_AUTHENTICATION_REQUIRED ? oAuth + : oAuthProxy); OUString userName(roAuth ? roAuth->UserName : OUString()); OUString passWord(roAuth ? roAuth->PassWord : OUString()); long authAvail(0); - auto const rc = curl_easy_getinfo(rSession.m_pCurl.get(), - statusCode == SC_UNAUTHORIZED - ? CURLINFO_HTTPAUTH_AVAIL - : CURLINFO_PROXYAUTH_AVAIL, - &authAvail); + auto const rc + = curl_easy_getinfo(rSession.m_pCurl.get(), + statusCode != SC_PROXY_AUTHENTICATION_REQUIRED + ? CURLINFO_HTTPAUTH_AVAIL + : CURLINFO_PROXYAUTH_AVAIL, + &authAvail); assert(rc == CURLE_OK); (void)rc; + if (statusCode == SC_FORBIDDEN) + { // SharePoint hack: try NTLM auth + assert(authAvail == 0); + authAvail |= CURLAUTH_NTLM | CURLAUTH_NEGOTIATE; + } // only allow SystemCredentials once - the // PasswordContainer may have stored it in the // Config (TrySystemCredentialsFirst or @@ -1444,8 +1461,9 @@ auto CurlProcessor::ProcessRequest( auto const ret = pEnv->m_xAuthListener->authenticate( oRealm ? *oRealm : "", - statusCode == SC_UNAUTHORIZED ? rSession.m_URI.GetHost() - : rSession.m_Proxy.aName, + statusCode != SC_PROXY_AUTHENTICATION_REQUIRED + ? rSession.m_URI.GetHost() + : rSession.m_Proxy.aName, userName, passWord, isSystemCredSupported); if (ret == 0) |