From 23ff13457247e4457817b3e2dc24d99fc8703f9d Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Fri, 16 Sep 2022 21:25:50 +0200 Subject: ucb: webdav-curl: tweak cookie import Improve error handling/logging, and do it only if the error code 0x000E0098 is received. Change-Id: I47dada2ef08b21a43cdfa3db9eb2fcdb4043a04f --- ucb/source/ucp/webdav-curl/CurlSession.cxx | 38 ++++++++++++++++++---------- ucb/source/ucp/webdav-curl/ImportCookies.cxx | 19 +++++++++----- 2 files changed, 38 insertions(+), 19 deletions(-) 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 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 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 #ifdef _WIN32 +#include + #include #include @@ -98,7 +100,7 @@ OString TryImportCookies(uno::Reference 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 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 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 const& xContext[ RTL_TEXTENCODING_UTF8); uno::Sequence 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 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 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 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()) -- cgit v1.2.3