1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_xmlsecurity.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir /* 32*cdf0e10cSrcweir * Implementation of the I/O interfaces based on stream and URI binding 33*cdf0e10cSrcweir */ 34*cdf0e10cSrcweir #include "xmlstreamio.hxx" 35*cdf0e10cSrcweir #include <rtl/ustring.hxx> 36*cdf0e10cSrcweir #include "rtl/uri.hxx" 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir #include <libxml/uri.h> 39*cdf0e10cSrcweir #include <sal/types.h> 40*cdf0e10cSrcweir //For reasons that escape me, this is what xmlsec does when size_t is not 4 41*cdf0e10cSrcweir #if SAL_TYPES_SIZEOFPOINTER != 4 42*cdf0e10cSrcweir # define XMLSEC_NO_SIZE_T 43*cdf0e10cSrcweir #endif 44*cdf0e10cSrcweir #include <xmlsec/io.h> 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir #define XMLSTREAMIO_INITIALIZED 0x01 47*cdf0e10cSrcweir #define XMLSTREAMIO_REGISTERED 0x02 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir /* Global variables */ 50*cdf0e10cSrcweir /*- 51*cdf0e10cSrcweir * Enable stream I/O or not. 52*cdf0e10cSrcweir */ 53*cdf0e10cSrcweir static char enableXmlStreamIO = 0x00 ; 54*cdf0e10cSrcweir 55*cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XUriBinding > m_xUriBinding ; 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir extern "C" 58*cdf0e10cSrcweir int xmlStreamMatch( const char* uri ) 59*cdf0e10cSrcweir { 60*cdf0e10cSrcweir ::com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInputStream ; 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir if( ( enableXmlStreamIO & XMLSTREAMIO_INITIALIZED ) && 63*cdf0e10cSrcweir ( enableXmlStreamIO & XMLSTREAMIO_REGISTERED ) ) { 64*cdf0e10cSrcweir if( uri == NULL || !m_xUriBinding.is() ) 65*cdf0e10cSrcweir return 0 ; 66*cdf0e10cSrcweir //XMLSec first unescapes the uri and calls this function. For example, we pass the Uri 67*cdf0e10cSrcweir //ObjectReplacements/Object%201 then XMLSec passes ObjectReplacements/Object 1 68*cdf0e10cSrcweir //first. If this failed it would try this 69*cdf0e10cSrcweir //again with the original escaped string. However, it does not get this far, because there 70*cdf0e10cSrcweir //is another callback registered by libxml which claims to be able to handle this uri. 71*cdf0e10cSrcweir ::rtl::OUString sUri = 72*cdf0e10cSrcweir ::rtl::Uri::encode( ::rtl::OUString::createFromAscii( uri ), 73*cdf0e10cSrcweir rtl_UriCharClassUric, rtl_UriEncodeKeepEscapes, RTL_TEXTENCODING_UTF8); 74*cdf0e10cSrcweir xInputStream = m_xUriBinding->getUriBinding( sUri ) ; 75*cdf0e10cSrcweir if (!xInputStream.is()) 76*cdf0e10cSrcweir { 77*cdf0e10cSrcweir //Try the the passed in uri directly. 78*cdf0e10cSrcweir //For old documents prior OOo 3.0. We did not use URIs then. 79*cdf0e10cSrcweir xInputStream = m_xUriBinding->getUriBinding( 80*cdf0e10cSrcweir ::rtl::OUString::createFromAscii(uri)); 81*cdf0e10cSrcweir } 82*cdf0e10cSrcweir } 83*cdf0e10cSrcweir if (xInputStream.is()) 84*cdf0e10cSrcweir return 1; 85*cdf0e10cSrcweir else 86*cdf0e10cSrcweir return 0 ; 87*cdf0e10cSrcweir } 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir extern "C" 90*cdf0e10cSrcweir void* xmlStreamOpen( const char* uri ) 91*cdf0e10cSrcweir { 92*cdf0e10cSrcweir ::com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInputStream ; 93*cdf0e10cSrcweir ::com::sun::star::io::XInputStream* pInputStream ; 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir if( ( enableXmlStreamIO & XMLSTREAMIO_INITIALIZED ) && 96*cdf0e10cSrcweir ( enableXmlStreamIO & XMLSTREAMIO_REGISTERED ) ) { 97*cdf0e10cSrcweir if( uri == NULL || !m_xUriBinding.is() ) 98*cdf0e10cSrcweir return NULL ; 99*cdf0e10cSrcweir 100*cdf0e10cSrcweir //see xmlStreamMatch 101*cdf0e10cSrcweir ::rtl::OUString sUri = 102*cdf0e10cSrcweir ::rtl::Uri::encode( ::rtl::OUString::createFromAscii( uri ), 103*cdf0e10cSrcweir rtl_UriCharClassUric, rtl_UriEncodeKeepEscapes, RTL_TEXTENCODING_UTF8); 104*cdf0e10cSrcweir xInputStream = m_xUriBinding->getUriBinding( sUri ) ; 105*cdf0e10cSrcweir if (!xInputStream.is()) 106*cdf0e10cSrcweir { 107*cdf0e10cSrcweir //For old documents. 108*cdf0e10cSrcweir //try the the passed in uri directly. 109*cdf0e10cSrcweir xInputStream = m_xUriBinding->getUriBinding( 110*cdf0e10cSrcweir ::rtl::OUString::createFromAscii(uri)); 111*cdf0e10cSrcweir } 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir if( xInputStream.is() ) { 114*cdf0e10cSrcweir pInputStream = xInputStream.get() ; 115*cdf0e10cSrcweir pInputStream->acquire() ; 116*cdf0e10cSrcweir return ( void* )pInputStream ; 117*cdf0e10cSrcweir } 118*cdf0e10cSrcweir } 119*cdf0e10cSrcweir 120*cdf0e10cSrcweir return NULL ; 121*cdf0e10cSrcweir } 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir extern "C" 124*cdf0e10cSrcweir int xmlStreamRead( void* context, char* buffer, int len ) 125*cdf0e10cSrcweir { 126*cdf0e10cSrcweir int numbers ; 127*cdf0e10cSrcweir ::com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInputStream ; 128*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< sal_Int8 > outSeqs( len ) ; 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir numbers = 0 ; 131*cdf0e10cSrcweir if( ( enableXmlStreamIO & XMLSTREAMIO_INITIALIZED ) && 132*cdf0e10cSrcweir ( enableXmlStreamIO & XMLSTREAMIO_REGISTERED ) ) { 133*cdf0e10cSrcweir if( context != NULL ) { 134*cdf0e10cSrcweir xInputStream = ( com::sun::star::io::XInputStream* )context ; 135*cdf0e10cSrcweir if( !xInputStream.is() ) 136*cdf0e10cSrcweir return 0 ; 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir numbers = xInputStream->readBytes( outSeqs, len ) ; 139*cdf0e10cSrcweir const sal_Int8* readBytes = ( const sal_Int8* )outSeqs.getArray() ; 140*cdf0e10cSrcweir for( int i = 0 ; i < numbers ; i ++ ) 141*cdf0e10cSrcweir *( buffer + i ) = *( readBytes + i ) ; 142*cdf0e10cSrcweir } 143*cdf0e10cSrcweir } 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir return numbers ; 146*cdf0e10cSrcweir } 147*cdf0e10cSrcweir 148*cdf0e10cSrcweir extern "C" 149*cdf0e10cSrcweir int xmlStreamClose( void * context ) 150*cdf0e10cSrcweir { 151*cdf0e10cSrcweir ::com::sun::star::io::XInputStream* pInputStream ; 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir if( ( enableXmlStreamIO & XMLSTREAMIO_INITIALIZED ) && 154*cdf0e10cSrcweir ( enableXmlStreamIO & XMLSTREAMIO_REGISTERED ) ) { 155*cdf0e10cSrcweir if( context != NULL ) { 156*cdf0e10cSrcweir pInputStream = ( ::com::sun::star::io::XInputStream* )context ; 157*cdf0e10cSrcweir pInputStream->release() ; 158*cdf0e10cSrcweir } 159*cdf0e10cSrcweir } 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir return 0 ; 162*cdf0e10cSrcweir } 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir int xmlEnableStreamInputCallbacks() 165*cdf0e10cSrcweir { 166*cdf0e10cSrcweir int cbs = 0 ; 167*cdf0e10cSrcweir 168*cdf0e10cSrcweir if( !( enableXmlStreamIO & XMLSTREAMIO_INITIALIZED ) ) { 169*cdf0e10cSrcweir //Register the callbacks into libxml2 170*cdf0e10cSrcweir //cbs = xmlRegisterInputCallbacks( 171*cdf0e10cSrcweir // xmlStreamMatch, 172*cdf0e10cSrcweir // xmlStreamOpen, 173*cdf0e10cSrcweir // xmlStreamRead, 174*cdf0e10cSrcweir // xmlStreamClose ) ; 175*cdf0e10cSrcweir //if( cbs < 0 ) { 176*cdf0e10cSrcweir // return -1 ; 177*cdf0e10cSrcweir //} 178*cdf0e10cSrcweir 179*cdf0e10cSrcweir //Register the callbacks into xmlSec 180*cdf0e10cSrcweir //In order to make the xmlsec io finding the callbacks firstly, 181*cdf0e10cSrcweir //I put the callbacks at the very begining. 182*cdf0e10cSrcweir 183*cdf0e10cSrcweir //Cleanup the older callbacks. 184*cdf0e10cSrcweir //Notes: all none default callbacks will lose. 185*cdf0e10cSrcweir xmlSecIOCleanupCallbacks() ; 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir //Register my classbacks. 188*cdf0e10cSrcweir cbs = xmlSecIORegisterCallbacks( 189*cdf0e10cSrcweir xmlStreamMatch, 190*cdf0e10cSrcweir xmlStreamOpen, 191*cdf0e10cSrcweir xmlStreamRead, 192*cdf0e10cSrcweir xmlStreamClose ) ; 193*cdf0e10cSrcweir if( cbs < 0 ) { 194*cdf0e10cSrcweir return -1 ; 195*cdf0e10cSrcweir } 196*cdf0e10cSrcweir 197*cdf0e10cSrcweir //Register the default callbacks. 198*cdf0e10cSrcweir //Notes: the error will cause xmlsec working problems. 199*cdf0e10cSrcweir cbs = xmlSecIORegisterDefaultCallbacks() ; 200*cdf0e10cSrcweir if( cbs < 0 ) { 201*cdf0e10cSrcweir return -1 ; 202*cdf0e10cSrcweir } 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir enableXmlStreamIO |= XMLSTREAMIO_INITIALIZED ; 205*cdf0e10cSrcweir } 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir return 0 ; 208*cdf0e10cSrcweir } 209*cdf0e10cSrcweir 210*cdf0e10cSrcweir int xmlRegisterStreamInputCallbacks( 211*cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XUriBinding >& aUriBinding 212*cdf0e10cSrcweir ) { 213*cdf0e10cSrcweir if( !( enableXmlStreamIO & XMLSTREAMIO_INITIALIZED ) ) { 214*cdf0e10cSrcweir if( xmlEnableStreamInputCallbacks() < 0 ) 215*cdf0e10cSrcweir return -1 ; 216*cdf0e10cSrcweir } 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir if( !( enableXmlStreamIO & XMLSTREAMIO_REGISTERED ) ) { 219*cdf0e10cSrcweir enableXmlStreamIO |= XMLSTREAMIO_REGISTERED ; 220*cdf0e10cSrcweir } 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir m_xUriBinding = aUriBinding ; 223*cdf0e10cSrcweir 224*cdf0e10cSrcweir return 0 ; 225*cdf0e10cSrcweir } 226*cdf0e10cSrcweir 227*cdf0e10cSrcweir int xmlUnregisterStreamInputCallbacks( void ) 228*cdf0e10cSrcweir { 229*cdf0e10cSrcweir if( ( enableXmlStreamIO & XMLSTREAMIO_REGISTERED ) ) { 230*cdf0e10cSrcweir //Clear the uir-stream binding 231*cdf0e10cSrcweir m_xUriBinding.clear() ; 232*cdf0e10cSrcweir 233*cdf0e10cSrcweir //disable the registered flag 234*cdf0e10cSrcweir enableXmlStreamIO &= ~XMLSTREAMIO_REGISTERED ; 235*cdf0e10cSrcweir } 236*cdf0e10cSrcweir 237*cdf0e10cSrcweir return 0 ; 238*cdf0e10cSrcweir } 239*cdf0e10cSrcweir 240*cdf0e10cSrcweir void xmlDisableStreamInputCallbacks() { 241*cdf0e10cSrcweir xmlUnregisterStreamInputCallbacks() ; 242*cdf0e10cSrcweir enableXmlStreamIO &= ~XMLSTREAMIO_INITIALIZED ; 243*cdf0e10cSrcweir } 244*cdf0e10cSrcweir 245