ucb/source/ucp/webdav-curl/CurlSession.cxx | 65 ++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 19 deletions(-)
New commits: commit 6d4b6d11b4b55e530315cb2e4bedc16be4dca3bc Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Thu Mar 14 15:47:28 2024 +0100 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Thu Mar 14 19:37:57 2024 +0100 ucb: webdav-curl: always set CURLOPT_NOBODY for HEAD Otherwise there will be timeout that depends on when the server will close the connection, which varies by server but can be several minutes; getting a potential error document from the server for this one request when logging is enabled is less important. Change-Id: I505b014b148ba009c400d37d826c9edb8c3a6da2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164838 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit c8400f5acc36d2cf0c007260bdc94534a53bba90) diff --git a/ucb/source/ucp/webdav-curl/CurlSession.cxx b/ucb/source/ucp/webdav-curl/CurlSession.cxx index 7fb981838e3e..0d384633d66a 100644 --- a/ucb/source/ucp/webdav-curl/CurlSession.cxx +++ b/ucb/source/ucp/webdav-curl/CurlSession.cxx @@ -209,15 +209,6 @@ struct CurlOption } }; -// NOBODY will prevent logging the response body in ProcessRequest() exception -// handler, so only use it if logging is disabled -const CurlOption g_NoBody{ CURLOPT_NOBODY, - sal_detail_log_report(SAL_DETAIL_LOG_LEVEL_INFO, "ucb.ucp.webdav.curl") - == SAL_DETAIL_LOG_ACTION_IGNORE - ? 1L - : 0L, - nullptr }; - /// combined guard class to ensure things are released in correct order, /// particularly in ProcessRequest() error handling class Guard @@ -1947,7 +1938,11 @@ auto CurlSession::HEAD(OUString const& rURIReference, ::std::vector<OUString> co CurlUri const uri(CurlProcessor::URIReferenceToURI(*this, rURIReference)); ::std::vector<CurlOption> const options{ - g_NoBody, { CURLOPT_CUSTOMREQUEST, "HEAD", "CURLOPT_CUSTOMREQUEST" } + // NOBODY will prevent logging the response body in ProcessRequest() + // exception, but omitting it here results in a long timeout until the + // server closes the connection, which is worse + { CURLOPT_NOBODY, 1L, nullptr }, + { CURLOPT_CUSTOMREQUEST, "HEAD", "CURLOPT_CUSTOMREQUEST" } }; ::std::pair<::std::vector<OUString> const&, DAVResource&> const headers(rHeaderNames, commit 602175e05f29921649f467df3f5e81a5a399737b Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Thu Mar 14 14:55:48 2024 +0100 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Thu Mar 14 17:41:50 2024 +0100 ucb: webdav-curl: improve fallback authentication The bundled curl on Linux doesn't support Negotiate, and a system curl may not support NTLM either. If setting the auth method fails with CURLE_NOT_BUILT_IN, abort. Change-Id: I7b7f7afd1ebedd665d9475fd40cac0e0641062a6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164837 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit 3d56fb36c47f5cfdf646e26d241b2bd7f1d68884) diff --git a/ucb/source/ucp/webdav-curl/CurlSession.cxx b/ucb/source/ucp/webdav-curl/CurlSession.cxx index 4bae872b1757..7fb981838e3e 100644 --- a/ucb/source/ucp/webdav-curl/CurlSession.cxx +++ b/ucb/source/ucp/webdav-curl/CurlSession.cxx @@ -1324,9 +1324,14 @@ auto CurlProcessor::ProcessRequest( throw DAVException(DAVException::DAV_INVALID_ARG); } rc = curl_easy_setopt(rSession.m_pCurl.get(), CURLOPT_HTTPAUTH, oAuth->AuthMask); - assert( - rc - == CURLE_OK); // it shouldn't be possible to reduce auth to 0 via the authSystem masks + if (rc != CURLE_OK) + { // NEGOTIATE typically disabled on Linux, NTLM is optional too + assert(rc == CURLE_NOT_BUILT_IN); + SAL_INFO("ucb.ucp.webdav.curl", "no auth method available"); + throw DAVException( + DAVException::DAV_HTTP_NOAUTH, + ConnectionEndPointString(rSession.m_URI.GetHost(), rSession.m_URI.GetPort())); + } } if (oAuthProxy && !rSession.m_isAuthenticatedProxy) @@ -1352,9 +1357,14 @@ auto CurlProcessor::ProcessRequest( throw DAVException(DAVException::DAV_INVALID_ARG); } rc = curl_easy_setopt(rSession.m_pCurl.get(), CURLOPT_PROXYAUTH, oAuthProxy->AuthMask); - assert( - rc - == CURLE_OK); // it shouldn't be possible to reduce auth to 0 via the authSystem masks + if (rc != CURLE_OK) + { // NEGOTIATE typically disabled on Linux, NTLM is optional too + assert(rc == CURLE_NOT_BUILT_IN); + SAL_INFO("ucb.ucp.webdav.curl", "no auth method available"); + throw DAVException( + DAVException::DAV_HTTP_NOAUTH, + ConnectionEndPointString(rSession.m_URI.GetHost(), rSession.m_URI.GetPort())); + } } ResponseHeaders headers(rSession.m_pCurl.get()); @@ -1504,20 +1514,42 @@ auto CurlProcessor::ProcessRequest( OUString userName(roAuth ? roAuth->UserName : OUString()); OUString passWord(roAuth ? roAuth->PassWord : OUString()); long authAvail(0); - auto const rc + auto 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); // note: this must be a single value! // would need 2 iterations to try CURLAUTH_NTLM too - authAvail = CURLAUTH_NEGOTIATE; + rc = curl_easy_setopt(rSession.m_pCurl.get(), CURLOPT_HTTPAUTH, + CURLAUTH_NEGOTIATE); + if (rc == CURLE_OK) + { + authAvail = CURLAUTH_NEGOTIATE; + } + else + { + rc = curl_easy_setopt(rSession.m_pCurl.get(), CURLOPT_HTTPAUTH, + CURLAUTH_NTLM); + if (rc == CURLE_OK) + { + authAvail = CURLAUTH_NTLM; + } + else + { // can't work + SAL_INFO("ucb.ucp.webdav.curl", + "no SP fallback auth method available"); + throw DAVException( + DAVException::DAV_HTTP_NOAUTH, + ConnectionEndPointString(rSession.m_URI.GetHost(), + rSession.m_URI.GetPort())); + } + } } // only allow SystemCredentials once - the // PasswordContainer may have stored it in the