ucb/source/ucp/webdav-curl/CurlSession.cxx   |   38 +++++++++++++++++----------
 ucb/source/ucp/webdav-curl/ImportCookies.cxx |   19 +++++++++----
 2 files changed, 38 insertions(+), 19 deletions(-)

New commits:
commit 23ff13457247e4457817b3e2dc24d99fc8703f9d
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Fri Sep 16 21:25:50 2022 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Fri Sep 16 21:25:50 2022 +0200

    ucb: webdav-curl: tweak cookie import
    
    Improve error handling/logging, and do it only if the error code
    0x000E0098 is received.
    
    Change-Id: I47dada2ef08b21a43cdfa3db9eb2fcdb4043a04f

diff --git a/ucb/source/ucp/webdav-curl/CurlSession.cxx 
b/ucb/source/ucp/webdav-curl/CurlSession.cxx
index 066ad2d2feb9..cc0a2368784f 100644
--- a/ucb/source/ucp/webdav-curl/CurlSession.cxx
+++ b/ucb/source/ucp/webdav-curl/CurlSession.cxx
@@ -707,19 +707,6 @@ 
CurlSession::CurlSession(uno::Reference<uno::XComponentContext> const& xContext,
         rc = curl_easy_setopt(m_pCurl.get(), CURLOPT_FORBID_REUSE, 1L);
         assert(rc == CURLE_OK);
     }
-#ifdef _WIN32
-    if (m_URI.GetScheme() == "https")
-    {
-        OString const cookies(TryImportCookies(m_xContext, m_URI.GetHost()));
-        if (!cookies.isEmpty())
-        {
-            rc = curl_easy_setopt(m_pCurl.get(), CURLOPT_COOKIEFILE, "");
-            assert(rc == CURLE_OK);
-            rc = curl_easy_setopt(m_pCurl.get(), CURLOPT_COOKIE, 
cookies.getStr());
-            assert(rc == CURLE_OK);
-        }
-    }
-#endif
 }
 
 CurlSession::~CurlSession() {}
@@ -1247,6 +1234,7 @@ auto CurlProcessor::ProcessRequest(
     bool isRetry(false);
     int nAuthRequests(0);
     int nAuthRequestsProxy(0);
+    OString cookies;
 
     // libcurl does not have an authentication callback so handle auth
     // related status codes and requesting credentials via this loop
@@ -1386,6 +1374,30 @@ auto CurlProcessor::ProcessRequest(
                         }
                         break;
                     }
+                    case SC_FORBIDDEN:
+                    {
+                        ::std::map<OUString, OUString> const headerMap(
+                            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 (cookies.isEmpty() // retry only once - could be 
expired...
+                            && rSession.m_URI.GetScheme() == "https" // only 
encrypted
+                            && it != headerMap.end()
+                            && it->second.startsWith("917656;"))
+                        {
+                            cookies = TryImportCookies(rSession.m_xContext, 
rSession.m_URI.GetHost());
+                            if (!cookies.isEmpty())
+                            {
+                                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());
+                                assert(rc == CURLE_OK);
+                                (void)rc;
+                                isRetry = true;
+                            }
+                        }
+                        break;
+                    }
                     case SC_UNAUTHORIZED:
                     case SC_PROXY_AUTHENTICATION_REQUIRED:
                     {
diff --git a/ucb/source/ucp/webdav-curl/ImportCookies.cxx 
b/ucb/source/ucp/webdav-curl/ImportCookies.cxx
index 897299da3c0a..4df885e4efc7 100644
--- a/ucb/source/ucp/webdav-curl/ImportCookies.cxx
+++ b/ucb/source/ucp/webdav-curl/ImportCookies.cxx
@@ -24,6 +24,8 @@
 #include <rtl/ustring.hxx>
 
 #ifdef _WIN32
+#include <comphelper/windowserrorstring.hxx>
+
 #include <boost/property_tree/json_parser.hpp>
 
 #include <sqlite3.h>
@@ -98,7 +100,7 @@ OString 
TryImportCookies(uno::Reference<uno::XComponentContext> const& xContext[
     char* err(nullptr);
     Value value;
     OString const statement("SELECT value, LENGTH(encrypted_value), 
encrypted_value FROM cookies "
-                            "WHERE name = \"FedAuth\"  and host_key = \""
+                            "WHERE name = \"FedAuth\" AND host_key = \""
                             + ::rtl::OUStringToOString(rHost, 
RTL_TEXTENCODING_ASCII_US) + "\";");
     rc = sqlite3_exec(db, statement.getStr(), callback, &value, &err);
     if (rc != SQLITE_OK)
@@ -113,7 +115,7 @@ OString 
TryImportCookies(uno::Reference<uno::XComponentContext> const& xContext[
     }
     if (value.encryptedValue.getLength() < 3 + 12 + 16)
     {
-        SAL_INFO("ucb.ucp.webdav.curl", "encrypted_value too short");
+        SAL_INFO("ucb.ucp.webdav.curl", "encrypted_value too short: " << 
value.encryptedValue.getLength());
         return OString();
     }
 
@@ -125,7 +127,7 @@ OString 
TryImportCookies(uno::Reference<uno::XComponentContext> const& xContext[
     OUString const stateUrl = localAppDirUrl + "/Microsoft/Edge/User 
Data/Local State";
     OUString statePathU;
     ::osl::File::getSystemPathFromFileURL(stateUrl, statePathU);
-    OString statePath(::rtl::OUStringToOString(statePathU, 
RTL_TEXTENCODING_UTF8));
+    OString const statePath(::rtl::OUStringToOString(statePathU, 
RTL_TEXTENCODING_UTF8));
     ::std::string sEncryptedKey;
     try
     {
@@ -142,6 +144,11 @@ OString 
TryImportCookies(uno::Reference<uno::XComponentContext> const& xContext[
                                        RTL_TEXTENCODING_UTF8);
     uno::Sequence<sal_Int8> decodedEncryptedKey;
     ::comphelper::Base64::decode(decodedEncryptedKey, encodedEncryptedKey);
+    if (decodedEncryptedKey.getLength() < 5)
+    {
+        SAL_INFO("ucb.ucp.webdav.curl", "decoded key too short: " << 
decodedEncryptedKey.getLength());
+        return OString();
+    }
     DATA_BLOB protectedKey;
     protectedKey.cbData = decodedEncryptedKey.getLength() - 5;
     protectedKey.pbData
@@ -151,7 +158,7 @@ OString 
TryImportCookies(uno::Reference<uno::XComponentContext> const& xContext[
                            CRYPTPROTECT_UI_FORBIDDEN, &unprotectedKey)
         == FALSE)
     {
-        SAL_INFO("ucb.ucp.webdav.curl", "CryptUnprotectData failed");
+        SAL_INFO("ucb.ucp.webdav.curl", "CryptUnprotectData failed: " << 
WindowsErrorString(GetLastError()));
         assert(false);
         return OString();
     }
@@ -161,7 +168,7 @@ OString 
TryImportCookies(uno::Reference<uno::XComponentContext> const& xContext[
     });
     if (unprotectedKey.cbData < 16)
     {
-        SAL_WARN("ucb.ucp.webdav.curl", "CryptUnprotectData result too small");
+        SAL_WARN("ucb.ucp.webdav.curl", "CryptUnprotectData result too short: 
" << unprotectedKey.cbData);
         return OString();
     }
 
@@ -212,7 +219,7 @@ OString 
TryImportCookies(uno::Reference<uno::XComponentContext> const& xContext[
         encryptedValue.getLength());
     if (rv != SECSuccess)
     {
-        SAL_WARN("ucb.ucp.webdav.curl", "PK11_AEADOp failed");
+        SAL_WARN("ucb.ucp.webdav.curl", "PK11_AEADOp failed: " << rv);
         return OString();
     }
     if (outLength != encryptedValue.getLength())

Reply via email to