diff options
author | Rüdiger Timm <rt@openoffice.org> | 2007-11-07 09:32:37 +0000 |
---|---|---|
committer | Rüdiger Timm <rt@openoffice.org> | 2007-11-07 09:32:37 +0000 |
commit | f32a3112ddd2fb278d50cd569ccb1fcbe7d2d623 (patch) | |
tree | 8b894424c14e1feb5fb57c106b01cc2cc474888d /ucb/source | |
parent | 5ce5293877aeeb38be4cf5c9716c8bd54b0fd9f7 (diff) |
INTEGRATION: CWS tkr05_SRC680 (1.49.2); FILE MERGED
2007/11/02 12:40:57 tkr 1.49.2.5: #83234# host name mismatch
2007/11/02 09:48:58 tkr 1.49.2.4: #83234# host name mismatch
2007/10/11 14:22:51 tkr 1.49.2.3: #31053# WebDAV Https Support
2007/10/01 07:40:09 tkr 1.49.2.2: #31053#: HTTPS Support
2007/09/20 11:01:15 tkr 1.49.2.1: #i31053#: WebDAV HTTPS Support
Diffstat (limited to 'ucb/source')
-rw-r--r-- | ucb/source/ucp/webdav/NeonSession.cxx | 240 |
1 files changed, 237 insertions, 3 deletions
diff --git a/ucb/source/ucp/webdav/NeonSession.cxx b/ucb/source/ucp/webdav/NeonSession.cxx index a81cd2d2337c..adad26cf5119 100644 --- a/ucb/source/ucp/webdav/NeonSession.cxx +++ b/ucb/source/ucp/webdav/NeonSession.cxx @@ -4,9 +4,9 @@ * * $RCSfile: NeonSession.cxx,v $ * - * $Revision: 1.50 $ + * $Revision: 1.51 $ * - * last change: $Author: vg $ $Date: 2007-08-30 16:00:34 $ + * last change: $Author: rt $ $Date: 2007-11-07 10:32:37 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -38,7 +38,9 @@ #include <hash_map> #include <string.h> - +#ifndef _RTL_STRING_H_ +#include <rtl/string.h> +#endif #ifndef NE_SOCKET_H #include <ne_socket.h> #endif @@ -52,6 +54,10 @@ #include <ne_locks.h> #endif +#ifndef NE_SSL_H +#include <ne_ssl.h> +#endif + #ifndef __XML_PARSER_H__ #include "libxml/parser.h" #endif @@ -84,12 +90,47 @@ #ifndef _LINKSEQUENCE_HXX_ #include "LinkSequence.hxx" #endif + +#include <com/sun/star/xml/crypto/XSEInitializer.hpp> + #ifndef _UCBDEADPROPERTYVALUE_HXX_ #include "UCBDeadPropertyValue.hxx" #endif +#ifndef _COM_SUN_STAR_XML_CRYPTO_XSECURITYENVIRONMENT_HPP_ +#include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp> +#endif +#ifndef _COM_SUN_STAR_SECURITY_XCERTIFICATE_HPP_ +#include <com/sun/star/security/XCertificate.hpp> +#endif +#ifndef _COM_SUN_STAR_SECURITY_CERTIFICATEVALIDITY_HPP_ +#include <com/sun/star/security/CertificateValidity.hpp> +#endif + +#ifndef _COM_SUN_STAR_SECURITY_CERTIFICATECONTAINERSTATUS_HPP_ +#include <com/sun/star/security/CertificateContainerStatus.hpp> +#endif + +#ifndef _COM_SUN_STAR_SECURITY_CERTIFICATECONTAINER_HPP_ +#include <com/sun/star/security/CertificateContainer.hpp> +#endif + +#ifndef _COM_SUN_STAR_SECURITY_XCERTIFICATECONTAINER_HPP_ +#include <com/sun/star/security/XCertificateContainer.hpp> +#endif + + +#ifndef _SIMPLECERTIFICATIONVALIDATIONREQUEST_HXX_ +#include "ucbhelper/simplecertificatevalidationrequest.hxx" +#endif + +#include <cppuhelper/bootstrap.hxx> + using namespace com::sun::star; using namespace webdav_ucp; +using namespace com::sun::star::security; + +#define SEINITIALIZER_COMPONENT "com.sun.star.xml.crypto.SEInitializer" #ifndef EOL # define EOL "\r\n" @@ -364,6 +405,136 @@ extern "C" int NeonSession_NeonAuth( void * inUserData, } // ------------------------------------------------------------------- + +namespace { + // ------------------------------------------------------------------- + // Helper function + ::rtl::OUString GetHostnamePart( const ::rtl::OUString& _rRawString ) + { + ::rtl::OUString sPart; + ::rtl::OUString sPartId = ::rtl::OUString::createFromAscii( "CN=" ); + sal_Int32 nContStart = _rRawString.indexOf( sPartId ); + if ( nContStart != -1 ) + { + nContStart = nContStart + sPartId.getLength(); + sal_Int32 nContEnd = _rRawString.indexOf( sal_Unicode( ',' ), nContStart ); + sPart = _rRawString.copy( nContStart, nContEnd - nContStart ); + } + return sPart; + } +} +// ------------------------------------------------------------------- +extern "C" int NeonSession_CertificationNotify( void *userdata, + int failures, + const ne_ssl_certificate *cert ) +{ + NeonSession * pSession = static_cast< NeonSession * >( userdata ); + uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > xSecurityEnv; + uno::Reference< ::com::sun::star::security::XCertificateContainer > xCertificateContainer; + + + xCertificateContainer = uno::Reference< ::com::sun::star::security::XCertificateContainer >( + pSession->getMSF().get()->createInstance( rtl::OUString::createFromAscii( "com.sun.star.security.CertificateContainer" )), uno::UNO_QUERY ); + + char * dn; + + failures = 0; + + dn = ne_ssl_readable_dname( ne_ssl_cert_subject( cert ) ); + + rtl::OUString cert_subject( dn, strlen( dn ), RTL_TEXTENCODING_UTF8, 0 ); + + free( dn ); + + CertificateContainerStatus certificateContainer; + certificateContainer = xCertificateContainer.get()->hasCertificate( pSession->getHostName(), cert_subject ); + + if( certificateContainer != CertificateContainerStatus_NOCERT ) + { + if( certificateContainer == CertificateContainerStatus_TRUSTED ) + return 0; + else + return 1; + } + + rtl::OUString sSEInitializer; + ::com::sun::star::uno::Reference< com::sun::star::xml::crypto::XSEInitializer > mxSEInitializer; + ::com::sun::star::uno::Reference< com::sun::star::xml::crypto::XXMLSecurityContext > mxSecurityContext; + + sSEInitializer = rtl::OUString::createFromAscii( SEINITIALIZER_COMPONENT ); + mxSEInitializer = uno::Reference< com::sun::star::xml::crypto::XSEInitializer > ( + pSession->getMSF().get()->createInstance( sSEInitializer ), uno::UNO_QUERY ); + + if ( mxSEInitializer.is() ) + mxSecurityContext = mxSEInitializer->createSecurityContext( rtl::OUString::createFromAscii( "" ) ); + + xSecurityEnv = mxSecurityContext->getSecurityEnvironment(); + + + char * rawCert; + + rawCert = ne_ssl_cert_export( cert ); + + ::rtl::OString sRawCert( rawCert ); + + uno::Reference< com::sun::star::security::XCertificate> xCert = xSecurityEnv->createCertificateFromAscii( ::rtl::OStringToOUString( sRawCert, RTL_TEXTENCODING_ASCII_US ) ); + + sal_Int64 certValidity = xSecurityEnv->verifyCertificate( xCert ); + + + if ( pSession->isDomainMatch( GetHostnamePart( xCert.get()->getSubjectName())) ) + { + //if host name matched with certificate then look if the certificate was ok + if( certValidity == ::security::CertificateValidity::VALID ) + return 0; + } + + const uno::Reference< ucb::XCommandEnvironment > xEnv = + pSession->getRequestEnvironment().m_xEnv.get(); + + if ( xEnv.is() ) + { + failures = static_cast<int>(certValidity); + + uno::Reference< task::XInteractionHandler > xIH + = xEnv->getInteractionHandler(); + if ( xIH.is() ) + { + rtl::Reference< ucbhelper::SimpleCertificateValidationRequest > xRequest + = new ucbhelper::SimpleCertificateValidationRequest((sal_Int32)failures, xCert, pSession->getHostName() ); + xIH->handle( xRequest.get() ); + + rtl::Reference< ucbhelper::InteractionContinuation > xSelection + = xRequest->getSelection(); + + if ( xSelection.is() ) + { + uno::Reference< task::XInteractionApprove > xApprove( + xSelection.get(), uno::UNO_QUERY ); + if ( xApprove.is() ) + { + xCertificateContainer->addCertificate(pSession->getHostName(), cert_subject, sal_True ); + return 0; + } else { + // Dont trust Cert + xCertificateContainer->addCertificate(pSession->getHostName(), cert_subject, sal_False ); + return 1; + } + + } + } else + { + // Dont trust Cert + xCertificateContainer->addCertificate(pSession->getHostName(), cert_subject, sal_False ); + return 1; + } + + + } + + return 1; +} +// ------------------------------------------------------------------- extern "C" void NeonSession_PreSendRequest( ne_request * req, void * userdata, ne_buffer * headers ) @@ -552,6 +723,18 @@ void NeonSession::Init() NeonUri::makeConnectionEndPointString( m_aHostName, m_nPort ) ); + if (m_aScheme.equalsIgnoreAsciiCase( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "https" ) ) ) ) + { + + // Get all trusted certificates from key store + + + + // Set a failure callback for certificate check + ne_ssl_set_verify( m_pHttpSession, NeonSession_CertificationNotify, this); + } + // Add hooks (i.e. for adding additional headers to the request) #if 0 @@ -1664,5 +1847,56 @@ bool NeonSession::getDataFromInputStream( } return false; } +// ------------------------------------------------------------------- +//static + +NeonSession::Map NeonSession::certMap; + +bool NeonSession::isCertificate( const ::rtl::OUString & url, const ::rtl::OUString & certificate_name ) +{ + Map::iterator p = NeonSession::certMap.find(url); + + bool ret = false; + + while( p != NeonSession::certMap.end() ) + { + ret = (*p).second.equals(certificate_name); + if( ret ) + break; + p++; + } + + return ret; +} + +// ------------------------------------------------------------------- +//static +void NeonSession::rememberCertificate( const ::rtl::OUString & url, const ::rtl::OUString & certificate_name ) +{ + NeonSession::certMap.insert( Map::value_type( url, certificate_name ) ); +} + +// --------------------------------------------------------------------- +sal_Bool +NeonSession::isDomainMatch( rtl::OUString certHostName) +{ + rtl::OUString hostName = getHostName(); + + if (hostName.equalsIgnoreAsciiCase( certHostName )) + return sal_True; + + + + if ( 0 == certHostName.indexOf( rtl::OUString::createFromAscii( "*" ) ) && hostName.getLength() >= certHostName.getLength() ) + { + rtl::OUString cmpStr = certHostName.copy( 1 ); + + if ( hostName.matchIgnoreAsciiCase( cmpStr, hostName.getLength( ) - cmpStr.getLength()) ) + return sal_True; + + } + + return sal_False; +} |