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