external/libcmis/0001-Take-into-account-m_CurlInitProtocolsFunction-in-cop.patch
 |   25 +
 
external/libcmis/0001-cppcheck-operatorEqVarError-in-src-libcmis-http-sess.patch
 |   24 +
 external/libcmis/UnpackedTarball_libcmis.mk                                    
  |    3 
 external/libcmis/initprotocols.patch.1                                         
  |  147 ++++++++++
 ucb/source/ucp/cmis/cmis_content.cxx                                           
  |    4 
 ucb/source/ucp/cmis/cmis_repo_content.cxx                                      
  |    4 
 ucb/source/ucp/cmis/cmis_url.cxx                                               
  |   20 +
 7 files changed, 224 insertions(+), 3 deletions(-)

New commits:
commit 62529d1eee91f3a781a4ef9117f23aa65ec82e86
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Tue Jun 18 18:14:22 2024 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Mon Jun 24 12:37:02 2024 +0200

    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.st...@allotropia.de>

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 <serval2...@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 <serval2...@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 );

Reply via email to