diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2024-06-18 18:14:22 +0200 |
---|---|---|
committer | Michael Stahl <michael.stahl@allotropia.de> | 2024-06-24 12:37:02 +0200 |
commit | 62529d1eee91f3a781a4ef9117f23aa65ec82e86 (patch) | |
tree | 34e733860f354cce3e47c2550133a10f454244a1 | |
parent | e598cfd1d84b9eb4144e36cba0e514ea6c31f118 (diff) |
libcmis,ucb: cmis: improve AllowInsecureProtocols implementation
1. in libcmis, pass the CurlInitProtocolsFunction to all subclasses of
HttpSession that need it, and add 2 upstream fixes to pass it around
2. Arrange for InitCurl_easy to be called in UCP RepoContent as well
3. If AllowInsecureProtocols is disabled, automatically upgrade
http connections to https, as is already done in webdav-curl.
Do this in Content and RepoContent; hopefully should work
to convert when m_aURL member is initialised;
the m_xIdentifier on the other hand should have the original
URL because ContentProviderImplHelper::queryExistingContents()
caching likely relies on that.
Change-Id: I20d36ed03ba7ce221d6946b1c996071f4130ec7e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169114
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
-rw-r--r-- | external/libcmis/0001-Take-into-account-m_CurlInitProtocolsFunction-in-cop.patch | 25 | ||||
-rw-r--r-- | external/libcmis/0001-cppcheck-operatorEqVarError-in-src-libcmis-http-sess.patch | 24 | ||||
-rw-r--r-- | external/libcmis/UnpackedTarball_libcmis.mk | 3 | ||||
-rw-r--r-- | external/libcmis/initprotocols.patch.1 | 147 | ||||
-rw-r--r-- | ucb/source/ucp/cmis/cmis_content.cxx | 4 | ||||
-rw-r--r-- | ucb/source/ucp/cmis/cmis_repo_content.cxx | 4 | ||||
-rw-r--r-- | ucb/source/ucp/cmis/cmis_url.cxx | 20 |
7 files changed, 224 insertions, 3 deletions
diff --git a/external/libcmis/0001-Take-into-account-m_CurlInitProtocolsFunction-in-cop.patch b/external/libcmis/0001-Take-into-account-m_CurlInitProtocolsFunction-in-cop.patch new file mode 100644 index 000000000000..235adbe38252 --- /dev/null +++ b/external/libcmis/0001-Take-into-account-m_CurlInitProtocolsFunction-in-cop.patch @@ -0,0 +1,25 @@ +From 98e7e9f15449e0c8eaa12776c6c126ea0411002e Mon Sep 17 00:00:00 2001 +From: Julien Nabet <serval2412@yahoo.fr> +Date: Fri, 23 Feb 2024 21:59:12 +0100 +Subject: [PATCH] Take into account m_CurlInitProtocolsFunction in copy + constructor HttpSession + +--- + src/libcmis/http-session.cxx | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/libcmis/http-session.cxx b/src/libcmis/http-session.cxx +index 8d427a4..79bcc08 100644 +--- a/src/libcmis/http-session.cxx ++++ b/src/libcmis/http-session.cxx +@@ -183,6 +183,7 @@ HttpSession::HttpSession( string username, string password, bool noSslCheck, + + HttpSession::HttpSession( const HttpSession& copy ) : + m_curlHandle( NULL ), ++ m_CurlInitProtocolsFunction( copy.m_CurlInitProtocolsFunction ), + m_no100Continue( copy.m_no100Continue ), + m_oauth2Handler( copy.m_oauth2Handler ), + m_username( copy.m_username ), +-- +2.45.1 + diff --git a/external/libcmis/0001-cppcheck-operatorEqVarError-in-src-libcmis-http-sess.patch b/external/libcmis/0001-cppcheck-operatorEqVarError-in-src-libcmis-http-sess.patch new file mode 100644 index 000000000000..fc1acef60fab --- /dev/null +++ b/external/libcmis/0001-cppcheck-operatorEqVarError-in-src-libcmis-http-sess.patch @@ -0,0 +1,24 @@ +From 308a5352bab44157ba13962b9aa4becefb6e3817 Mon Sep 17 00:00:00 2001 +From: Julien Nabet <serval2412@yahoo.fr> +Date: Fri, 23 Feb 2024 17:56:17 +0100 +Subject: [PATCH] cppcheck: operatorEqVarError in src/libcmis/http-session.cxx + +--- + src/libcmis/http-session.cxx | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/libcmis/http-session.cxx b/src/libcmis/http-session.cxx +index f690914..8d427a4 100644 +--- a/src/libcmis/http-session.cxx ++++ b/src/libcmis/http-session.cxx +@@ -224,6 +224,7 @@ HttpSession& HttpSession::operator=( const HttpSession& copy ) + { + curl_easy_cleanup( m_curlHandle ); + m_curlHandle = NULL; ++ m_CurlInitProtocolsFunction = copy.m_CurlInitProtocolsFunction; + m_no100Continue = copy.m_no100Continue; + m_oauth2Handler = copy.m_oauth2Handler; + m_username = copy.m_username; +-- +2.45.1 + diff --git a/external/libcmis/UnpackedTarball_libcmis.mk b/external/libcmis/UnpackedTarball_libcmis.mk index af5feed5e96a..d0b8e2b5c7bc 100644 --- a/external/libcmis/UnpackedTarball_libcmis.mk +++ b/external/libcmis/UnpackedTarball_libcmis.mk @@ -22,6 +22,9 @@ $(eval $(call gb_UnpackedTarball_add_patches,libcmis,\ external/libcmis/factory-no-retry-ssl.patch.1 \ external/libcmis/sharepoint-auth.patch.1 \ external/libcmis/exceptions.patch.1 \ + external/libcmis/0001-cppcheck-operatorEqVarError-in-src-libcmis-http-sess.patch \ + external/libcmis/0001-Take-into-account-m_CurlInitProtocolsFunction-in-cop.patch \ + external/libcmis/initprotocols.patch.1 \ )) # vim: set noet sw=4 ts=4: diff --git a/external/libcmis/initprotocols.patch.1 b/external/libcmis/initprotocols.patch.1 new file mode 100644 index 000000000000..5e1d8943c699 --- /dev/null +++ b/external/libcmis/initprotocols.patch.1 @@ -0,0 +1,147 @@ +--- libcmis/src/libcmis/session-factory.cxx.orig 2024-06-21 17:40:02.696092806 +0200 ++++ libcmis/src/libcmis/session-factory.cxx 2024-06-21 17:32:21.759833389 +0200 +@@ -75,12 +75,15 @@ + if ( bindingUrl == "https://www.googleapis.com/drive/v3" ) + { + session = new GDriveSession( bindingUrl, username, password, +- oauth2, verbose ); ++ oauth2, verbose, ++ g_CurlInitProtocolsFunction); ++ + } + else if ( bindingUrl == "https://graph.microsoft.com/v1.0" ) + { + session = new OneDriveSession( bindingUrl, username, password, +- oauth2, verbose); ++ oauth2, verbose, ++ g_CurlInitProtocolsFunction); + } + else + { +@@ -103,7 +106,7 @@ + } + // Could be SharePoint - needs NTLM authentication + session = new SharePointSession( bindingUrl, username, +- password, verbose ); ++ password, verbose, g_CurlInitProtocolsFunction); + } + + // Try the CMIS cases: we need to autodetect the binding type +--- libcmis/src/libcmis/base-session.hxx.orig 2024-06-21 17:41:56.737651815 +0200 ++++ libcmis/src/libcmis/base-session.hxx 2024-06-21 17:42:08.466709308 +0200 +@@ -59,7 +59,8 @@ + BaseSession( std::string sBindingUrl, std::string repository, + std::string username, std::string password, + bool noSslCheck = false, +- libcmis::OAuth2DataPtr oauth2 = libcmis::OAuth2DataPtr(), bool verbose = false ); ++ libcmis::OAuth2DataPtr oauth2 = libcmis::OAuth2DataPtr(), bool verbose = false, ++ libcmis::CurlInitProtocolsFunction = nullptr); + + /** This constructor copies an existing http session. + This has been mostly designed for SessionFactory to save +--- libcmis/src/libcmis/base-session.cxx.orig 2024-06-21 17:42:28.593807967 +0200 ++++ libcmis/src/libcmis/base-session.cxx 2024-06-21 17:43:37.051143529 +0200 +@@ -43,9 +43,10 @@ + using namespace std; + + BaseSession::BaseSession( string bindingUrl, string repositoryId, string username, +- string password, bool noSslCheck, libcmis::OAuth2DataPtr oauth2, bool verbose ) : ++ string password, bool noSslCheck, libcmis::OAuth2DataPtr oauth2, bool verbose, ++ libcmis::CurlInitProtocolsFunction initProtocolsFunction) : + Session( ), +- HttpSession( username, password, noSslCheck, oauth2, verbose ), ++ HttpSession( username, password, noSslCheck, oauth2, verbose, initProtocolsFunction ), + m_bindingUrl( bindingUrl ), + m_repositoryId( repositoryId ), + m_repositories( ) +--- libcmis/src/libcmis/gdrive-session.hxx.orig 2024-06-21 17:44:32.721416413 +0200 ++++ libcmis/src/libcmis/gdrive-session.hxx 2024-06-21 17:39:01.143791090 +0200 +@@ -39,7 +39,8 @@ + std::string username, + std::string password, + libcmis::OAuth2DataPtr oauth2, +- bool verbose = false ); ++ bool verbose = false, ++ libcmis::CurlInitProtocolsFunction = nullptr); + + ~GDriveSession ( ); + +--- libcmis/src/libcmis/gdrive-session.cxx.orig 2024-06-21 17:44:59.947549870 +0200 ++++ libcmis/src/libcmis/gdrive-session.cxx 2024-06-21 17:45:26.666680841 +0200 +@@ -43,9 +43,10 @@ + string username, + string password, + libcmis::OAuth2DataPtr oauth2, +- bool verbose ) : ++ bool verbose, ++ libcmis::CurlInitProtocolsFunction initProtocolsFunction) : + BaseSession( baseUrl, string(), username, password, false, +- libcmis::OAuth2DataPtr(), verbose ) ++ libcmis::OAuth2DataPtr(), verbose, initProtocolsFunction ) + + { + // Add the dummy repository, even if we don't have OAuth2 +--- libcmis/src/libcmis/onedrive-session.hxx.orig 2024-06-21 17:46:39.857039605 +0200 ++++ libcmis/src/libcmis/onedrive-session.hxx 2024-06-21 17:46:59.045133662 +0200 +@@ -40,7 +40,8 @@ + std::string username, + std::string password, + libcmis::OAuth2DataPtr oauth2, +- bool verbose = false ); ++ bool verbose = false, ++ libcmis::CurlInitProtocolsFunction = nullptr); + + ~OneDriveSession ( ); + +--- libcmis/src/libcmis/onedrive-session.cxx.orig 2024-06-21 17:47:35.187310824 +0200 ++++ libcmis/src/libcmis/onedrive-session.cxx 2024-06-21 17:48:02.068442589 +0200 +@@ -41,9 +41,10 @@ + string username, + string password, + libcmis::OAuth2DataPtr oauth2, +- bool verbose ) : ++ bool verbose, ++ libcmis::CurlInitProtocolsFunction initProtocolsFunction) : + BaseSession( baseUrl, string(), username, password, false, +- libcmis::OAuth2DataPtr(), verbose ) ++ libcmis::OAuth2DataPtr(), verbose, initProtocolsFunction) + + { + // Add the dummy repository +--- libcmis/src/libcmis/sharepoint-session.hxx.orig 2024-06-21 18:02:35.120719197 +0200 ++++ libcmis/src/libcmis/sharepoint-session.hxx 2024-06-21 18:02:54.288813088 +0200 +@@ -39,7 +39,8 @@ + SharePointSession( std::string baseUrl, + std::string username, + std::string password, +- bool verbose = false ); ++ bool verbose = false, ++ libcmis::CurlInitProtocolsFunction = nullptr); + + SharePointSession( std::string baseUrl, + const HttpSession& httpSession, +--- libcmis/src/libcmis/sharepoint-session.cxx.orig 2024-06-21 16:02:24.597237776 +0200 ++++ libcmis/src/libcmis/sharepoint-session.cxx 2024-06-21 18:03:48.109076715 +0200 +@@ -42,9 +42,10 @@ + SharePointSession::SharePointSession ( string baseUrl, + string username, + string password, +- bool verbose ) : ++ bool verbose, ++ libcmis::CurlInitProtocolsFunction initProtocolsFunction) : + BaseSession( baseUrl, string(), username, password, false, +- libcmis::OAuth2DataPtr(), verbose ), ++ libcmis::OAuth2DataPtr(), verbose, initProtocolsFunction ), + m_digestCode( string( ) ) + + { +--- libcmis/src/libcmis/http-session.cxx.orig 2024-06-21 18:24:44.192002619 +0200 ++++ libcmis/src/libcmis/http-session.cxx 2024-06-21 18:24:46.329012530 +0200 +@@ -981,6 +981,7 @@ + case CURLE_COULDNT_RESOLVE_HOST: + type = "dnsFailed"; + break; ++ case CURLE_UNSUPPORTED_PROTOCOL: + case CURLE_COULDNT_CONNECT: + case CURLE_SSL_CONNECT_ERROR: + case CURLE_SSL_CERTPROBLEM: diff --git a/ucb/source/ucp/cmis/cmis_content.cxx b/ucb/source/ucp/cmis/cmis_content.cxx index c5ff2886e981..c1808f8bc492 100644 --- a/ucb/source/ucp/cmis/cmis_content.cxx +++ b/ucb/source/ucp/cmis/cmis_content.cxx @@ -268,7 +268,7 @@ namespace cmis m_pSession( nullptr ), m_pObject(std::move( pObject )), m_sURL( Identifier->getContentIdentifier( ) ), - m_aURL( Identifier->getContentIdentifier( ) ), + m_aURL( m_sURL ), m_bTransient( false ), m_bIsFolder( false ) { @@ -285,7 +285,7 @@ namespace cmis m_pProvider( pProvider ), m_pSession( nullptr ), m_sURL( Identifier->getContentIdentifier( ) ), - m_aURL( Identifier->getContentIdentifier( ) ), + m_aURL( m_sURL ), m_bTransient( true ), m_bIsFolder( bIsFolder ) { diff --git a/ucb/source/ucp/cmis/cmis_repo_content.cxx b/ucb/source/ucp/cmis/cmis_repo_content.cxx index caba10826ee7..38c261cdf3b8 100644 --- a/ucb/source/ucp/cmis/cmis_repo_content.cxx +++ b/ucb/source/ucp/cmis/cmis_repo_content.cxx @@ -24,6 +24,7 @@ #include <config_oauth2.h> #include <rtl/uri.hxx> #include <sal/log.hxx> +#include <systools/curlinit.hxx> #include <tools/urlobj.hxx> #include <ucbhelper/cancelcommandexecution.hxx> #include <ucbhelper/contentidentifier.hxx> @@ -132,6 +133,9 @@ namespace cmis new CertValidationHandler( xEnv, m_xContext, aBindingUrl.GetHost( ) ) ); libcmis::SessionFactory::setCertificateValidationHandler( certHandler ); + // init libcurl callback + libcmis::SessionFactory::setCurlInitProtocolsFunction(&::InitCurl_easy); + // Get the auth credentials AuthProvider authProvider( xEnv, m_xIdentifier->getContentIdentifier( ), m_aURL.getBindingUrl( ) ); AuthProvider::setXEnv( xEnv ); diff --git a/ucb/source/ucp/cmis/cmis_url.cxx b/ucb/source/ucp/cmis/cmis_url.cxx index 86fde73b94bb..43f5ce004e56 100644 --- a/ucb/source/ucp/cmis/cmis_url.cxx +++ b/ucb/source/ucp/cmis/cmis_url.cxx @@ -10,12 +10,30 @@ #include <sal/config.h> #include <rtl/uri.hxx> +#include <officecfg/Office/Security.hxx> #include <tools/urlobj.hxx> #include "cmis_url.hxx" namespace cmis { + + static OUString CheckInsecureProtocol(OUString const& rURL) + { + OUString rest; + if (rURL.startsWithIgnoreAsciiCase("http://", &rest)) + { + if (!officecfg::Office::Security::Net::AllowInsecureProtocols::get()) + { + // "http" not allowed -> immediately redirect to "https", + // better than showing confusing error to user + return "https://" + rest; + } + } + return rURL; + } + + URL::URL( std::u16string_view urlStr ) { INetURLObject aUrl( urlStr ); @@ -23,7 +41,7 @@ namespace cmis // Decode the authority to get the binding URL and repository id OUString sDecodedHost = aUrl.GetHost( INetURLObject::DecodeMechanism::WithCharset ); INetURLObject aHostUrl( sDecodedHost ); - m_sBindingUrl = aHostUrl.GetURLNoMark( ); + m_sBindingUrl = CheckInsecureProtocol(aHostUrl.GetURLNoMark()); m_sRepositoryId = aHostUrl.GetMark( ); m_sUser = aUrl.GetUser( INetURLObject::DecodeMechanism::WithCharset ); |