diff options
author | Cédric Bosdonnat <cedric.bosdonnat.ooo@free.fr> | 2013-07-25 15:40:02 +0200 |
---|---|---|
committer | Cédric Bosdonnat <cedric.bosdonnat.ooo@free.fr> | 2013-09-02 13:51:54 +0200 |
commit | 79c35f6169cff4bb8163d711873528ee438a891a (patch) | |
tree | 95448b4ec90911b6c44da4a5505ebfb6a6ddbb24 | |
parent | 0d8b97be3e6be58421b7990c54f80ceab7c3e00b (diff) |
fdo#61589: ask what to do with invalid SSL certificates in CMIS UCP
Change-Id: I3cf688f7070e3e8cb2db532d8e034961504a8160
-rw-r--r-- | ucb/Library_ucpcmis1.mk | 1 | ||||
-rw-r--r-- | ucb/source/ucp/cmis/certvalidation_handler.cxx | 101 | ||||
-rw-r--r-- | ucb/source/ucp/cmis/certvalidation_handler.hxx | 42 | ||||
-rw-r--r-- | ucb/source/ucp/cmis/cmis_content.cxx | 6 | ||||
-rw-r--r-- | ucb/source/ucp/cmis/cmis_repo_content.cxx | 41 |
5 files changed, 177 insertions, 14 deletions
diff --git a/ucb/Library_ucpcmis1.mk b/ucb/Library_ucpcmis1.mk index 219aafc83cfe..57c3719c7ca7 100644 --- a/ucb/Library_ucpcmis1.mk +++ b/ucb/Library_ucpcmis1.mk @@ -35,6 +35,7 @@ $(eval $(call gb_Library_use_externals,ucpcmis1,\ $(eval $(call gb_Library_add_exception_objects,ucpcmis1,\ ucb/source/ucp/cmis/auth_provider \ + ucb/source/ucp/cmis/certvalidation_handler \ ucb/source/ucp/cmis/cmis_content \ ucb/source/ucp/cmis/cmis_repo_content \ ucb/source/ucp/cmis/cmis_datasupplier \ diff --git a/ucb/source/ucp/cmis/certvalidation_handler.cxx b/ucb/source/ucp/cmis/certvalidation_handler.cxx new file mode 100644 index 000000000000..7ac8cda76dc9 --- /dev/null +++ b/ucb/source/ucp/cmis/certvalidation_handler.cxx @@ -0,0 +1,101 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + */ + +#include <com/sun/star/security/XCertificate.hpp> +#include <com/sun/star/security/CertificateValidity.hpp> +#include <com/sun/star/xml/crypto/SEInitializer.hpp> +#include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp> + +#include <comphelper/sequence.hxx> +#include <ucbhelper/simplecertificatevalidationrequest.hxx> + +#include "certvalidation_handler.hxx" + +#define STD_TO_OUSTR( str ) OUString( str.c_str(), str.length( ), RTL_TEXTENCODING_UTF8 ) + +using namespace std; +using namespace com::sun::star; + +namespace cmis +{ + bool CertValidationHandler::validateCertificate( vector< string > aCertificates ) + { + bool bValidate = false; + if ( !aCertificates.empty() && m_xEnv.is() ) + { + uno::Reference< xml::crypto::XSEInitializer > xSEInitializer; + try + { + xSEInitializer = xml::crypto::SEInitializer::create( m_xContext ); + } + catch ( uno::Exception const & ) + { + } + + if ( xSEInitializer.is() ) + { + uno::Reference< xml::crypto::XXMLSecurityContext > xSecurityContext( + xSEInitializer->createSecurityContext( OUString() ) ); + + uno::Reference< xml::crypto::XSecurityEnvironment > xSecurityEnv( + xSecurityContext->getSecurityEnvironment() ); + + vector< string >::iterator pIt = aCertificates.begin(); + string sCert = *pIt; + // We need to get rid of the PEM header/footer lines + OUString sCleanCert = STD_TO_OUSTR( sCert ); + sCleanCert = sCleanCert.replaceAll( "-----BEGIN CERTIFICATE-----", "" ); + sCleanCert = sCleanCert.replaceAll( "-----END CERTIFICATE-----", "" ); + uno::Reference< security::XCertificate > xCert( + xSecurityEnv->createCertificateFromAscii( + sCleanCert ) ); + + std::vector< uno::Reference< security::XCertificate > > vecCerts; + + for ( ++pIt; pIt != aCertificates.end(); ++pIt ) + { + sCert = *pIt; + uno::Reference< security::XCertificate> xImCert( + xSecurityEnv->createCertificateFromAscii( + STD_TO_OUSTR( sCert ) ) ); + if ( xImCert.is() ) + vecCerts.push_back( xImCert ); + } + + sal_Int64 certValidity = xSecurityEnv->verifyCertificate( xCert, + ::comphelper::containerToSequence( vecCerts ) ); + + uno::Reference< task::XInteractionHandler > xIH( + m_xEnv->getInteractionHandler() ); + if ( xIH.is() ) + { + rtl::Reference< ucbhelper::SimpleCertificateValidationRequest > + xRequest( new ucbhelper::SimpleCertificateValidationRequest( + sal_Int32( certValidity ), xCert, m_sHostname ) ); + xIH->handle( xRequest.get() ); + rtl::Reference< ucbhelper::InteractionContinuation > xSelection + = xRequest->getSelection(); + + if ( xSelection.is() ) + { + uno::Reference< task::XInteractionApprove > xApprove( + xSelection.get(), uno::UNO_QUERY ); + bValidate = xApprove.is(); + } + } + } + } + return bValidate; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/cmis/certvalidation_handler.hxx b/ucb/source/ucp/cmis/certvalidation_handler.hxx new file mode 100644 index 000000000000..43b74da01733 --- /dev/null +++ b/ucb/source/ucp/cmis/certvalidation_handler.hxx @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + */ +#ifndef CERTVALIDATION_HANDLER_HXX +#define CERTVALIDATION_HANDLER_HXX + +#include <libcmis/libcmis.hxx> + +#include <com/sun/star/ucb/XCommandEnvironment.hpp> + +namespace cmis +{ + class CertValidationHandler : public libcmis::CertValidationHandler + { + const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment>& m_xEnv; + const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >& m_xContext; + OUString m_sHostname; + + public: + CertValidationHandler ( + const com::sun::star::uno::Reference< + com::sun::star::ucb::XCommandEnvironment>& xEnv, + const com::sun::star::uno::Reference< + com::sun::star::uno::XComponentContext>& xContext, + OUString sHostname ): + m_xEnv( xEnv ), m_xContext( xContext ), m_sHostname( sHostname ) { } + + bool validateCertificate( std::vector< std::string > certificates ); + }; +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/cmis/cmis_content.cxx b/ucb/source/ucp/cmis/cmis_content.cxx index 6481555abfe1..f9a5a9a46f53 100644 --- a/ucb/source/ucp/cmis/cmis_content.cxx +++ b/ucb/source/ucp/cmis/cmis_content.cxx @@ -43,6 +43,7 @@ #include <ucbhelper/proxydecider.hxx> #include "auth_provider.hxx" +#include "certvalidation_handler.hxx" #include "cmis_content.hxx" #include "cmis_provider.hxx" #include "cmis_resultset.hxx" @@ -317,6 +318,11 @@ namespace cmis if ( NULL == m_pSession ) { + // Set the SSL Validation handler + libcmis::CertValidationHandlerPtr certHandler( + new CertValidationHandler( xEnv, m_xContext, aBindingUrl.GetHost( ) ) ); + libcmis::SessionFactory::setCertificateValidationHandler( certHandler ); + // Get the auth credentials AuthProvider authProvider( xEnv, m_xIdentifier->getContentIdentifier( ), m_aURL.getBindingUrl( ) ); diff --git a/ucb/source/ucp/cmis/cmis_repo_content.cxx b/ucb/source/ucp/cmis/cmis_repo_content.cxx index 95e91040fec7..c15d958841a0 100644 --- a/ucb/source/ucp/cmis/cmis_repo_content.cxx +++ b/ucb/source/ucp/cmis/cmis_repo_content.cxx @@ -25,6 +25,7 @@ #include <ucbhelper/proxydecider.hxx> #include "auth_provider.hxx" +#include "certvalidation_handler.hxx" #include "cmis_content.hxx" #include "cmis_provider.hxx" #include "cmis_repo_content.hxx" @@ -132,6 +133,11 @@ namespace cmis if ( m_aRepositories.empty() ) { + // Set the SSL Validation handler + libcmis::CertValidationHandlerPtr certHandler( + new CertValidationHandler( xEnv, m_xContext, aBindingUrl.GetHost( ) ) ); + libcmis::SessionFactory::setCertificateValidationHandler( certHandler ); + // Get the auth credentials AuthProvider authProvider( xEnv, m_xIdentifier->getContentIdentifier( ), m_aURL.getBindingUrl( ) ); @@ -139,20 +145,27 @@ namespace cmis string rPassword = OUSTR_TO_STDSTR( m_aURL.getPassword( ) ); if ( authProvider.authenticationQuery( rUsername, rPassword ) ) { - // Create a session to get repositories - libcmis::OAuth2DataPtr oauth2Data = NULL; - - libcmis::Session* session = libcmis::SessionFactory::createSession( - OUSTR_TO_STDSTR( m_aURL.getBindingUrl( ) ), - rUsername, rPassword, "", sal_False, oauth2Data ); - if (session == NULL ) - ucbhelper::cancelCommandExecution( - ucb::IOErrorCode_INVALID_DEVICE, - uno::Sequence< uno::Any >( 0 ), - xEnv, - OUString( ) ); - m_aRepositories = session->getRepositories( ); - delete session; + try + { + // Create a session to get repositories + libcmis::OAuth2DataPtr oauth2Data = NULL; + + libcmis::Session* session = libcmis::SessionFactory::createSession( + OUSTR_TO_STDSTR( m_aURL.getBindingUrl( ) ), + rUsername, rPassword, "", sal_False, oauth2Data ); + if (session == NULL ) + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_INVALID_DEVICE, + uno::Sequence< uno::Any >( 0 ), + xEnv, + OUString( ) ); + m_aRepositories = session->getRepositories( ); + delete session; + } + catch (const libcmis::Exception& e) + { + SAL_INFO( "cmisucp", "Error getting repositories: " << e.what() ); + } } else { |