1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ManifestImport.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * ( a copy is included in the LICENSE file that accompanied this code ).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER( update_precomp.py ): autogen include statement, do not remove
32 #include "precompiled_package.hxx"
33 #include <ManifestImport.hxx>
34 #include <ManifestDefines.hxx>
35 #ifndef _BASE64_CODEC_HXX_
36 #include <Base64Codec.hxx>
38 #include <com/sun/star/xml/sax/XAttributeList.hpp>
39 #include <com/sun/star/beans/PropertyValue.hpp>
41 using namespace com::sun::star::uno
;
42 using namespace com::sun::star::beans
;
43 using namespace com::sun::star
;
47 // ---------------------------------------------------
48 ManifestImport::ManifestImport( vector
< Sequence
< PropertyValue
> > & rNewManVector
)
50 , bIgnoreEncryptData ( sal_False
)
51 , rManVector ( rNewManVector
)
53 , sFileEntryElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_FILE_ENTRY
) )
54 , sManifestElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_MANIFEST
) )
55 , sEncryptionDataElement( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_ENCRYPTION_DATA
) )
56 , sAlgorithmElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_ALGORITHM
) )
57 , sKeyDerivationElement( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_KEY_DERIVATION
) )
59 , sCdataAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CDATA
) )
60 , sMediaTypeAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_MEDIA_TYPE
) )
61 , sVersionAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_VERSION
) )
62 , sFullPathAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_FULL_PATH
) )
63 , sSizeAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_SIZE
) )
64 , sSaltAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_SALT
) )
65 , sInitialisationVectorAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_INITIALISATION_VECTOR
) )
66 , sIterationCountAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_ITERATION_COUNT
) )
67 , sAlgorithmNameAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_ALGORITHM_NAME
) )
68 , sKeyDerivationNameAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_KEY_DERIVATION_NAME
) )
69 , sChecksumAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CHECKSUM
) )
70 , sChecksumTypeAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CHECKSUM_TYPE
) )
72 , sFullPathProperty ( RTL_CONSTASCII_USTRINGPARAM ( "FullPath" ) )
73 , sMediaTypeProperty ( RTL_CONSTASCII_USTRINGPARAM ( "MediaType" ) )
74 , sVersionProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Version" ) )
75 , sIterationCountProperty ( RTL_CONSTASCII_USTRINGPARAM ( "IterationCount" ) )
76 , sSaltProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Salt" ) )
77 , sInitialisationVectorProperty ( RTL_CONSTASCII_USTRINGPARAM ( "InitialisationVector" ) )
78 , sSizeProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Size" ) )
79 , sDigestProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Digest" ) )
81 , sWhiteSpace ( RTL_CONSTASCII_USTRINGPARAM ( " " ) )
82 , sBlowfish ( RTL_CONSTASCII_USTRINGPARAM ( "Blowfish CFB" ) )
83 , sPBKDF2 ( RTL_CONSTASCII_USTRINGPARAM ( "PBKDF2" ) )
84 , sChecksumType ( RTL_CONSTASCII_USTRINGPARAM ( CHECKSUM_TYPE
) )
89 // ---------------------------------------------------
90 ManifestImport::~ManifestImport ( void )
94 // ---------------------------------------------------
95 void SAL_CALL
ManifestImport::startDocument( )
96 throw( xml::sax::SAXException
, uno::RuntimeException
)
100 // ---------------------------------------------------
101 void SAL_CALL
ManifestImport::endDocument( )
102 throw( xml::sax::SAXException
, uno::RuntimeException
)
106 // ---------------------------------------------------
107 void SAL_CALL
ManifestImport::startElement( const OUString
& aName
, const uno::Reference
< xml::sax::XAttributeList
>& xAttribs
)
108 throw( xml::sax::SAXException
, uno::RuntimeException
)
110 StringHashMap aConvertedAttribs
;
111 ::rtl::OUString aConvertedName
= PushNameAndNamespaces( aName
, xAttribs
, aConvertedAttribs
);
113 if ( aConvertedName
== sFileEntryElement
)
115 aSequence
.realloc ( PKG_SIZE_ENCR_MNFST
);
117 // Put full-path property first for MBA
118 aSequence
[nNumProperty
].Name
= sFullPathProperty
;
119 aSequence
[nNumProperty
++].Value
<<= aConvertedAttribs
[sFullPathAttribute
];
120 aSequence
[nNumProperty
].Name
= sMediaTypeProperty
;
121 aSequence
[nNumProperty
++].Value
<<= aConvertedAttribs
[sMediaTypeAttribute
];
123 OUString sVersion
= aConvertedAttribs
[sVersionAttribute
];
124 if ( sVersion
.getLength() )
126 aSequence
[nNumProperty
].Name
= sVersionProperty
;
127 aSequence
[nNumProperty
++].Value
<<= sVersion
;
130 OUString sSize
= aConvertedAttribs
[sSizeAttribute
];
131 if ( sSize
.getLength() )
134 nSize
= sSize
.toInt32();
135 aSequence
[nNumProperty
].Name
= sSizeProperty
;
136 aSequence
[nNumProperty
++].Value
<<= nSize
;
139 else if ( aStack
.size() > 1 )
141 ManifestStack::reverse_iterator aIter
= aStack
.rbegin();
144 if ( aIter
->m_aConvertedName
.equals( sFileEntryElement
) )
146 if ( aConvertedName
.equals( sEncryptionDataElement
) )
148 // If this element exists, then this stream is encrypted and we need
149 // to store the initialisation vector, salt and iteration count used
150 OUString aString
= aConvertedAttribs
[sChecksumTypeAttribute
];
151 if ( aString
== sChecksumType
&& !bIgnoreEncryptData
)
153 aString
= aConvertedAttribs
[sChecksumAttribute
];
154 Sequence
< sal_uInt8
> aDecodeBuffer
;
155 Base64Codec::decodeBase64 ( aDecodeBuffer
, aString
);
156 aSequence
[nNumProperty
].Name
= sDigestProperty
;
157 aSequence
[nNumProperty
++].Value
<<= aDecodeBuffer
;
161 else if ( aIter
->m_aConvertedName
.equals( sEncryptionDataElement
) )
163 if ( aConvertedName
== sAlgorithmElement
)
165 OUString aString
= aConvertedAttribs
[sAlgorithmNameAttribute
];
166 if ( aString
== sBlowfish
&& !bIgnoreEncryptData
)
168 aString
= aConvertedAttribs
[sInitialisationVectorAttribute
];
169 Sequence
< sal_uInt8
> aDecodeBuffer
;
170 Base64Codec::decodeBase64 ( aDecodeBuffer
, aString
);
171 aSequence
[nNumProperty
].Name
= sInitialisationVectorProperty
;
172 aSequence
[nNumProperty
++].Value
<<= aDecodeBuffer
;
175 // If we don't recognise the algorithm, then the key derivation info
177 bIgnoreEncryptData
= sal_True
;
179 else if ( aConvertedName
== sKeyDerivationElement
)
181 OUString aString
= aConvertedAttribs
[sKeyDerivationNameAttribute
];
182 if ( aString
== sPBKDF2
&& !bIgnoreEncryptData
)
184 aString
= aConvertedAttribs
[sSaltAttribute
];
185 Sequence
< sal_uInt8
> aDecodeBuffer
;
186 Base64Codec::decodeBase64 ( aDecodeBuffer
, aString
);
187 aSequence
[nNumProperty
].Name
= sSaltProperty
;
188 aSequence
[nNumProperty
++].Value
<<= aDecodeBuffer
;
190 aString
= aConvertedAttribs
[sIterationCountAttribute
];
191 aSequence
[nNumProperty
].Name
= sIterationCountProperty
;
192 aSequence
[nNumProperty
++].Value
<<= aString
.toInt32();
195 // If we don't recognise the key derivation technique, then the
196 // algorithm info is useless to us
197 bIgnoreEncryptData
= sal_True
;
203 // ---------------------------------------------------
204 void SAL_CALL
ManifestImport::endElement( const OUString
& aName
)
205 throw( xml::sax::SAXException
, uno::RuntimeException
)
207 ::rtl::OUString aConvertedName
= ConvertName( aName
);
208 if ( !aStack
.empty() && aStack
.rbegin()->m_aConvertedName
.equals( aConvertedName
) )
210 if ( aConvertedName
.equals( sFileEntryElement
) )
212 aSequence
.realloc ( nNumProperty
);
213 bIgnoreEncryptData
= sal_False
;
214 rManVector
.push_back ( aSequence
);
222 // ---------------------------------------------------
223 void SAL_CALL
ManifestImport::characters( const OUString
& /*aChars*/ )
224 throw( xml::sax::SAXException
, uno::RuntimeException
)
228 // ---------------------------------------------------
229 void SAL_CALL
ManifestImport::ignorableWhitespace( const OUString
& /*aWhitespaces*/ )
230 throw( xml::sax::SAXException
, uno::RuntimeException
)
234 // ---------------------------------------------------
235 void SAL_CALL
ManifestImport::processingInstruction( const OUString
& /*aTarget*/, const OUString
& /*aData*/ )
236 throw( xml::sax::SAXException
, uno::RuntimeException
)
240 // ---------------------------------------------------
241 void SAL_CALL
ManifestImport::setDocumentLocator( const uno::Reference
< xml::sax::XLocator
>& /*xLocator*/ )
242 throw( xml::sax::SAXException
, uno::RuntimeException
)
246 // ---------------------------------------------------
247 ::rtl::OUString
ManifestImport::PushNameAndNamespaces( const ::rtl::OUString
& aName
, const uno::Reference
< xml::sax::XAttributeList
>& xAttribs
, StringHashMap
& o_aConvertedAttribs
)
249 StringHashMap aNamespaces
;
250 ::std::vector
< ::std::pair
< ::rtl::OUString
, ::rtl::OUString
> > aAttribsStrs
;
254 sal_Int16 nAttrCount
= xAttribs
.is() ? xAttribs
->getLength() : 0;
255 aAttribsStrs
.reserve( nAttrCount
);
257 for( sal_Int16 nInd
= 0; nInd
< nAttrCount
; nInd
++ )
259 ::rtl::OUString aAttrName
= xAttribs
->getNameByIndex( nInd
);
260 ::rtl::OUString aAttrValue
= xAttribs
->getValueByIndex( nInd
);
261 if ( aAttrName
.getLength() >= 5
262 && aAttrName
.compareToAscii( "xmlns", 5 ) == 0
263 && ( aAttrName
.getLength() == 5 || aAttrName
.getStr()[5] == ( sal_Unicode
)':' ) )
265 // this is a namespace declaration
266 ::rtl::OUString
aNsName( ( aAttrName
.getLength() == 5 ) ? ::rtl::OUString() : aAttrName
.copy( 6 ) );
267 aNamespaces
[aNsName
] = aAttrValue
;
271 // this is no namespace declaration
272 aAttribsStrs
.push_back( pair
< ::rtl::OUString
, ::rtl::OUString
>( aAttrName
, aAttrValue
) );
277 ::rtl::OUString aConvertedName
= ConvertNameWithNamespace( aName
, aNamespaces
);
278 if ( !aConvertedName
.getLength() )
279 aConvertedName
= ConvertName( aName
);
281 aStack
.push_back( ManifestScopeEntry( aConvertedName
, aNamespaces
) );
283 for ( sal_uInt16 nInd
= 0; nInd
< aAttribsStrs
.size(); nInd
++ )
285 // convert the attribute names on filling
286 o_aConvertedAttribs
[ConvertName( aAttribsStrs
[nInd
].first
)] = aAttribsStrs
[nInd
].second
;
289 return aConvertedName
;
292 // ---------------------------------------------------
293 ::rtl::OUString
ManifestImport::ConvertNameWithNamespace( const ::rtl::OUString
& aName
, const StringHashMap
& aNamespaces
)
295 ::rtl::OUString aNsAlias
;
296 ::rtl::OUString aPureName
= aName
;
298 sal_Int32 nInd
= aName
.indexOf( ( sal_Unicode
)':' );
299 if ( nInd
!= -1 && nInd
< aName
.getLength() )
301 aNsAlias
= aName
.copy( 0, nInd
);
302 aPureName
= aName
.copy( nInd
+ 1 );
305 ::rtl::OUString aResult
;
307 StringHashMap::const_iterator aIter
= aNamespaces
.find( aNsAlias
);
308 if ( aIter
!= aNamespaces
.end()
309 && ( aIter
->second
.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MANIFEST_NAMESPACE
) ) )
310 || aIter
->second
.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MANIFEST_OASIS_NAMESPACE
) ) ) ) )
312 // no check for manifest.xml consistency currently since the old versions have supported inconsistent documents as well
313 aResult
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MANIFEST_NSPREFIX
) );
314 aResult
+= aPureName
;
320 // ---------------------------------------------------
321 ::rtl::OUString
ManifestImport::ConvertName( const ::rtl::OUString
& aName
)
323 ::rtl::OUString aConvertedName
;
324 for ( ManifestStack::reverse_iterator aIter
= aStack
.rbegin(); !aConvertedName
.getLength() && aIter
!= aStack
.rend(); aIter
++ )
326 if ( !aIter
->m_aNamespaces
.empty() )
327 aConvertedName
= ConvertNameWithNamespace( aName
, aIter
->m_aNamespaces
);
330 if ( !aConvertedName
.getLength() )
331 aConvertedName
= aName
;
333 return aConvertedName
;