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