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

Reply via email to