summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCédric Bosdonnat <cedric.bosdonnat.ooo@free.fr>2013-07-25 15:40:02 +0200
committerCédric Bosdonnat <cedric.bosdonnat.ooo@free.fr>2013-07-25 16:17:09 +0200
commit16eb296df0ce4755f3cd7176a62da42bedbecce4 (patch)
treefc60899caf9ab0256e08b0a01996ce5f7c1e7852
parenta5846f3fe77912cba30abbc3aaaba634b04d5f8a (diff)
fdo#61589: ask what to do with invalid SSL certificates in CMIS UCP
Change-Id: I3cf688f7070e3e8cb2db532d8e034961504a8160
-rw-r--r--ucb/Library_ucpcmis1.mk1
-rw-r--r--ucb/source/ucp/cmis/certvalidation_handler.cxx101
-rw-r--r--ucb/source/ucp/cmis/certvalidation_handler.hxx42
-rw-r--r--ucb/source/ucp/cmis/cmis_content.cxx6
-rw-r--r--ucb/source/ucp/cmis/cmis_repo_content.cxx41
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 43f355444e08..cd0fb011642a 100644
--- a/ucb/source/ucp/cmis/cmis_content.cxx
+++ b/ucb/source/ucp/cmis/cmis_content.cxx
@@ -46,6 +46,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"
@@ -320,6 +321,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 2cd46685149d..d9a623213a80 100644
--- a/ucb/source/ucp/cmis/cmis_repo_content.cxx
+++ b/ucb/source/ucp/cmis/cmis_repo_content.cxx
@@ -28,6 +28,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"
@@ -135,6 +136,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( ) );
@@ -142,20 +148,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
{