1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * ( a copy is included in the LICENSE file that accompanied this code ). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER( update_precomp.py ): autogen include statement, do not remove 29 #include "precompiled_package.hxx" 30 #include <com/sun/star/packages/zip/ZipConstants.hpp> 31 #include <com/sun/star/embed/StorageFormats.hpp> 32 #include <com/sun/star/packages/zip/ZipIOException.hpp> 33 #include <com/sun/star/io/XInputStream.hpp> 34 #include <com/sun/star/io/XOutputStream.hpp> 35 #include <com/sun/star/io/XStream.hpp> 36 #include <com/sun/star/io/XSeekable.hpp> 37 #include <com/sun/star/xml/crypto/DigestID.hpp> 38 #include <com/sun/star/xml/crypto/CipherID.hpp> 39 40 41 #include <ZipPackageStream.hxx> 42 #include <ZipPackage.hxx> 43 #include <ZipFile.hxx> 44 #include <EncryptedDataHeader.hxx> 45 #include <vos/diagnose.hxx> 46 #include "wrapstreamforshare.hxx" 47 48 #include <comphelper/seekableinput.hxx> 49 #include <comphelper/storagehelper.hxx> 50 51 #include <rtl/instance.hxx> 52 53 #include <PackageConstants.hxx> 54 55 using namespace com::sun::star::packages::zip::ZipConstants; 56 using namespace com::sun::star::packages::zip; 57 using namespace com::sun::star::uno; 58 using namespace com::sun::star::lang; 59 using namespace com::sun::star; 60 using namespace cppu; 61 using namespace rtl; 62 63 namespace { struct lcl_CachedImplId : public rtl::Static< Sequence < sal_Int8 >, lcl_CachedImplId > {}; } 64 65 const ::com::sun::star::uno::Sequence < sal_Int8 >& ZipPackageStream::static_getImplementationId() 66 { 67 return lcl_CachedImplId::get(); 68 } 69 70 ZipPackageStream::ZipPackageStream ( ZipPackage & rNewPackage, 71 const uno::Reference< XMultiServiceFactory >& xFactory, 72 sal_Bool bAllowRemoveOnInsert ) 73 : m_xFactory( xFactory ) 74 , rZipPackage( rNewPackage ) 75 , bToBeCompressed ( sal_True ) 76 , bToBeEncrypted ( sal_False ) 77 , bHaveOwnKey ( sal_False ) 78 , bIsEncrypted ( sal_False ) 79 , m_nImportedStartKeyAlgorithm( 0 ) 80 , m_nImportedEncryptionAlgorithm( 0 ) 81 , m_nImportedChecksumAlgorithm( 0 ) 82 , m_nImportedDerivedKeySize( 0 ) 83 , m_nStreamMode( PACKAGE_STREAM_NOTSET ) 84 , m_nMagicalHackPos( 0 ) 85 , m_nMagicalHackSize( 0 ) 86 , m_bHasSeekable( sal_False ) 87 , m_bCompressedIsSetFromOutside( sal_False ) 88 , m_bFromManifest( sal_False ) 89 , m_bUseWinEncoding( false ) 90 { 91 OSL_ENSURE( m_xFactory.is(), "No factory is provided to ZipPackageStream!\n" ); 92 93 this->mbAllowRemoveOnInsert = bAllowRemoveOnInsert; 94 95 SetFolder ( sal_False ); 96 aEntry.nVersion = -1; 97 aEntry.nFlag = 0; 98 aEntry.nMethod = -1; 99 aEntry.nTime = -1; 100 aEntry.nCrc = -1; 101 aEntry.nCompressedSize = -1; 102 aEntry.nSize = -1; 103 aEntry.nOffset = -1; 104 aEntry.nPathLen = -1; 105 aEntry.nExtraLen = -1; 106 107 Sequence < sal_Int8 > &rCachedImplId = lcl_CachedImplId::get(); 108 if ( !rCachedImplId.getLength() ) 109 rCachedImplId = getImplementationId(); 110 } 111 112 ZipPackageStream::~ZipPackageStream( void ) 113 { 114 } 115 116 void ZipPackageStream::setZipEntryOnLoading( const ZipEntry &rInEntry ) 117 { 118 aEntry.nVersion = rInEntry.nVersion; 119 aEntry.nFlag = rInEntry.nFlag; 120 aEntry.nMethod = rInEntry.nMethod; 121 aEntry.nTime = rInEntry.nTime; 122 aEntry.nCrc = rInEntry.nCrc; 123 aEntry.nCompressedSize = rInEntry.nCompressedSize; 124 aEntry.nSize = rInEntry.nSize; 125 aEntry.nOffset = rInEntry.nOffset; 126 aEntry.sPath = rInEntry.sPath; 127 aEntry.nPathLen = rInEntry.nPathLen; 128 aEntry.nExtraLen = rInEntry.nExtraLen; 129 130 if ( aEntry.nMethod == STORED ) 131 bToBeCompressed = sal_False; 132 } 133 134 //-------------------------------------------------------------------------- 135 void ZipPackageStream::CloseOwnStreamIfAny() 136 { 137 if ( xStream.is() ) 138 { 139 xStream->closeInput(); 140 xStream = uno::Reference< io::XInputStream >(); 141 m_bHasSeekable = sal_False; 142 } 143 } 144 145 //-------------------------------------------------------------------------- 146 uno::Reference< io::XInputStream > ZipPackageStream::GetOwnSeekStream() 147 { 148 if ( !m_bHasSeekable && xStream.is() ) 149 { 150 // The package component requires that every stream either be FROM a package or it must support XSeekable! 151 // The only exception is a nonseekable stream that is provided only for storing, if such a stream 152 // is accessed before commit it MUST be wrapped. 153 // Wrap the stream in case it is not seekable 154 xStream = ::comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( xStream, m_xFactory ); 155 uno::Reference< io::XSeekable > xSeek( xStream, UNO_QUERY ); 156 if ( !xSeek.is() ) 157 throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "The stream must support XSeekable!" ) ), 158 uno::Reference< XInterface >() ); 159 160 m_bHasSeekable = sal_True; 161 } 162 163 return xStream; 164 } 165 166 //-------------------------------------------------------------------------- 167 uno::Reference< io::XInputStream > ZipPackageStream::GetRawEncrStreamNoHeaderCopy() 168 { 169 if ( m_nStreamMode != PACKAGE_STREAM_RAW || !GetOwnSeekStream().is() ) 170 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 171 172 if ( m_xBaseEncryptionData.is() ) 173 throw ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Encrypted stream without encryption data!\n" ) ), 174 uno::Reference< XInterface >() ); 175 176 uno::Reference< io::XSeekable > xSeek( GetOwnSeekStream(), UNO_QUERY ); 177 if ( !xSeek.is() ) 178 throw ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "The stream must be seekable!\n" ) ), 179 uno::Reference< XInterface >() ); 180 181 // skip header 182 xSeek->seek( n_ConstHeaderSize + getInitialisationVector().getLength() + 183 getSalt().getLength() + getDigest().getLength() ); 184 185 // create temporary stream 186 uno::Reference < io::XOutputStream > xTempOut( 187 m_xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ), 188 uno::UNO_QUERY ); 189 uno::Reference < io::XInputStream > xTempIn( xTempOut, UNO_QUERY ); 190 uno::Reference < io::XSeekable > xTempSeek( xTempOut, UNO_QUERY ); 191 if ( !xTempOut.is() || !xTempIn.is() || !xTempSeek.is() ) 192 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 193 194 // copy the raw stream to the temporary file starting from the current position 195 ::comphelper::OStorageHelper::CopyInputToOutput( GetOwnSeekStream(), xTempOut ); 196 xTempOut->closeOutput(); 197 xTempSeek->seek( 0 ); 198 199 return xTempIn; 200 } 201 202 //-------------------------------------------------------------------------- 203 sal_Int32 ZipPackageStream::GetEncryptionAlgorithm() const 204 { 205 return m_nImportedEncryptionAlgorithm ? m_nImportedEncryptionAlgorithm : rZipPackage.GetEncAlgID(); 206 } 207 208 //-------------------------------------------------------------------------- 209 sal_Int32 ZipPackageStream::GetBlockSize() const 210 { 211 return GetEncryptionAlgorithm() == ::com::sun::star::xml::crypto::CipherID::AES_CBC_W3C_PADDING ? 16 : 8; 212 } 213 214 //-------------------------------------------------------------------------- 215 ::rtl::Reference< EncryptionData > ZipPackageStream::GetEncryptionData( bool bUseWinEncoding ) 216 { 217 ::rtl::Reference< EncryptionData > xResult; 218 if ( m_xBaseEncryptionData.is() ) 219 xResult = new EncryptionData( 220 *m_xBaseEncryptionData, 221 GetEncryptionKey( bUseWinEncoding ), 222 GetEncryptionAlgorithm(), 223 m_nImportedChecksumAlgorithm ? m_nImportedChecksumAlgorithm : rZipPackage.GetChecksumAlgID(), 224 m_nImportedDerivedKeySize ? m_nImportedDerivedKeySize : rZipPackage.GetDefaultDerivedKeySize(), 225 GetStartKeyGenID() ); 226 227 return xResult; 228 } 229 230 //-------------------------------------------------------------------------- 231 void ZipPackageStream::SetBaseEncryptionData( const ::rtl::Reference< BaseEncryptionData >& xData ) 232 { 233 m_xBaseEncryptionData = xData; 234 } 235 236 //-------------------------------------------------------------------------- 237 uno::Sequence< sal_Int8 > ZipPackageStream::GetEncryptionKey( bool bUseWinEncoding ) 238 { 239 uno::Sequence< sal_Int8 > aResult; 240 sal_Int32 nKeyGenID = GetStartKeyGenID(); 241 bUseWinEncoding = ( bUseWinEncoding || m_bUseWinEncoding ); 242 243 if ( bHaveOwnKey && m_aStorageEncryptionKeys.getLength() ) 244 { 245 ::rtl::OUString aNameToFind; 246 if ( nKeyGenID == xml::crypto::DigestID::SHA256 ) 247 aNameToFind = PACKAGE_ENCRYPTIONDATA_SHA256UTF8; 248 else if ( nKeyGenID == xml::crypto::DigestID::SHA1 ) 249 { 250 aNameToFind = bUseWinEncoding ? PACKAGE_ENCRYPTIONDATA_SHA1MS1252 : PACKAGE_ENCRYPTIONDATA_SHA1UTF8; 251 } 252 else 253 throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No expected key is provided!" ) ), uno::Reference< uno::XInterface >() ); 254 255 for ( sal_Int32 nInd = 0; nInd < m_aStorageEncryptionKeys.getLength(); nInd++ ) 256 if ( m_aStorageEncryptionKeys[nInd].Name.equals( aNameToFind ) ) 257 m_aStorageEncryptionKeys[nInd].Value >>= aResult; 258 259 // empty keys are not allowed here 260 // so it is not important whether there is no key, or the key is empty, it is an error 261 if ( !aResult.getLength() ) 262 throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No expected key is provided!" ) ), uno::Reference< uno::XInterface >() ); 263 } 264 else 265 aResult = m_aEncryptionKey; 266 267 if ( !aResult.getLength() || !bHaveOwnKey ) 268 aResult = rZipPackage.GetEncryptionKey(); 269 270 return aResult; 271 } 272 273 //-------------------------------------------------------------------------- 274 sal_Int32 ZipPackageStream::GetStartKeyGenID() 275 { 276 // generally should all the streams use the same Start Key 277 // but if raw copy without password takes place, we should preserve the imported algorithm 278 return m_nImportedStartKeyAlgorithm ? m_nImportedStartKeyAlgorithm : rZipPackage.GetStartKeyGenID(); 279 } 280 281 //-------------------------------------------------------------------------- 282 uno::Reference< io::XInputStream > ZipPackageStream::TryToGetRawFromDataStream( sal_Bool bAddHeaderForEncr ) 283 { 284 if ( m_nStreamMode != PACKAGE_STREAM_DATA || !GetOwnSeekStream().is() || ( bAddHeaderForEncr && !bToBeEncrypted ) ) 285 throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 286 287 Sequence< sal_Int8 > aKey; 288 289 if ( bToBeEncrypted ) 290 { 291 aKey = GetEncryptionKey(); 292 if ( !aKey.getLength() ) 293 throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 294 } 295 296 try 297 { 298 // create temporary file 299 uno::Reference < io::XStream > xTempStream( 300 m_xFactory->createInstance ( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ), 301 uno::UNO_QUERY ); 302 if ( !xTempStream.is() ) 303 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 304 305 // create a package based on it 306 ZipPackage* pPackage = new ZipPackage( m_xFactory ); 307 uno::Reference< XSingleServiceFactory > xPackageAsFactory( static_cast< XSingleServiceFactory* >( pPackage ) ); 308 if ( !xPackageAsFactory.is() ) 309 throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 310 311 Sequence< Any > aArgs( 1 ); 312 aArgs[0] <<= xTempStream; 313 pPackage->initialize( aArgs ); 314 315 // create a new package stream 316 uno::Reference< XDataSinkEncrSupport > xNewPackStream( xPackageAsFactory->createInstance(), UNO_QUERY ); 317 if ( !xNewPackStream.is() ) 318 throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 319 320 xNewPackStream->setDataStream( static_cast< io::XInputStream* >( 321 new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() ) ) ); 322 323 uno::Reference< XPropertySet > xNewPSProps( xNewPackStream, UNO_QUERY ); 324 if ( !xNewPSProps.is() ) 325 throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 326 327 // copy all the properties of this stream to the new stream 328 xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ), makeAny( sMediaType ) ); 329 xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) ), makeAny( bToBeCompressed ) ); 330 if ( bToBeEncrypted ) 331 { 332 xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ENCRYPTION_KEY_PROPERTY ) ), makeAny( aKey ) ); 333 xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Encrypted" ) ), makeAny( sal_True ) ); 334 } 335 336 // insert a new stream in the package 337 uno::Reference< XUnoTunnel > xTunnel; 338 Any aRoot = pPackage->getByHierarchicalName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ) ); 339 aRoot >>= xTunnel; 340 uno::Reference< container::XNameContainer > xRootNameContainer( xTunnel, UNO_QUERY ); 341 if ( !xRootNameContainer.is() ) 342 throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 343 344 uno::Reference< XUnoTunnel > xNPSTunnel( xNewPackStream, UNO_QUERY ); 345 xRootNameContainer->insertByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "dummy" ) ), makeAny( xNPSTunnel ) ); 346 347 // commit the temporary package 348 pPackage->commitChanges(); 349 350 // get raw stream from the temporary package 351 uno::Reference< io::XInputStream > xInRaw; 352 if ( bAddHeaderForEncr ) 353 xInRaw = xNewPackStream->getRawStream(); 354 else 355 xInRaw = xNewPackStream->getPlainRawStream(); 356 357 // create another temporary file 358 uno::Reference < io::XOutputStream > xTempOut( 359 m_xFactory->createInstance ( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ), 360 uno::UNO_QUERY ); 361 uno::Reference < io::XInputStream > xTempIn( xTempOut, UNO_QUERY ); 362 uno::Reference < io::XSeekable > xTempSeek( xTempOut, UNO_QUERY ); 363 if ( !xTempOut.is() || !xTempIn.is() || !xTempSeek.is() ) 364 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 365 366 // copy the raw stream to the temporary file 367 ::comphelper::OStorageHelper::CopyInputToOutput( xInRaw, xTempOut ); 368 xTempOut->closeOutput(); 369 xTempSeek->seek( 0 ); 370 371 // close raw stream, package stream and folder 372 xInRaw = uno::Reference< io::XInputStream >(); 373 xNewPSProps = uno::Reference< XPropertySet >(); 374 xNPSTunnel = uno::Reference< XUnoTunnel >(); 375 xNewPackStream = uno::Reference< XDataSinkEncrSupport >(); 376 xTunnel = uno::Reference< XUnoTunnel >(); 377 xRootNameContainer = uno::Reference< container::XNameContainer >(); 378 379 // return the stream representing the first temporary file 380 return xTempIn; 381 } 382 catch ( RuntimeException& ) 383 { 384 throw; 385 } 386 catch ( Exception& ) 387 { 388 } 389 390 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 391 } 392 393 //-------------------------------------------------------------------------- 394 sal_Bool ZipPackageStream::ParsePackageRawStream() 395 { 396 OSL_ENSURE( GetOwnSeekStream().is(), "A stream must be provided!\n" ); 397 398 if ( !GetOwnSeekStream().is() ) 399 return sal_False; 400 401 sal_Bool bOk = sal_False; 402 403 ::rtl::Reference< BaseEncryptionData > xTempEncrData; 404 sal_Int32 nMagHackSize = 0; 405 Sequence < sal_Int8 > aHeader ( 4 ); 406 407 try 408 { 409 if ( GetOwnSeekStream()->readBytes ( aHeader, 4 ) == 4 ) 410 { 411 const sal_Int8 *pHeader = aHeader.getConstArray(); 412 sal_uInt32 nHeader = ( pHeader [0] & 0xFF ) | 413 ( pHeader [1] & 0xFF ) << 8 | 414 ( pHeader [2] & 0xFF ) << 16 | 415 ( pHeader [3] & 0xFF ) << 24; 416 if ( nHeader == n_ConstHeader ) 417 { 418 // this is one of our god-awful, but extremely devious hacks, everyone cheer 419 xTempEncrData = new BaseEncryptionData; 420 421 ::rtl::OUString aMediaType; 422 sal_Int32 nEncAlgorithm = 0; 423 sal_Int32 nChecksumAlgorithm = 0; 424 sal_Int32 nDerivedKeySize = 0; 425 sal_Int32 nStartKeyGenID = 0; 426 if ( ZipFile::StaticFillData( xTempEncrData, nEncAlgorithm, nChecksumAlgorithm, nDerivedKeySize, nStartKeyGenID, nMagHackSize, aMediaType, GetOwnSeekStream() ) ) 427 { 428 // We'll want to skip the data we've just read, so calculate how much we just read 429 // and remember it 430 m_nMagicalHackPos = n_ConstHeaderSize + xTempEncrData->m_aSalt.getLength() 431 + xTempEncrData->m_aInitVector.getLength() 432 + xTempEncrData->m_aDigest.getLength() 433 + aMediaType.getLength() * sizeof( sal_Unicode ); 434 m_nImportedEncryptionAlgorithm = nEncAlgorithm; 435 m_nImportedChecksumAlgorithm = nChecksumAlgorithm; 436 m_nImportedDerivedKeySize = nDerivedKeySize; 437 m_nImportedStartKeyAlgorithm = nStartKeyGenID; 438 m_nMagicalHackSize = nMagHackSize; 439 sMediaType = aMediaType; 440 441 bOk = sal_True; 442 } 443 } 444 } 445 } 446 catch( Exception& ) 447 { 448 } 449 450 if ( !bOk ) 451 { 452 // the provided stream is not a raw stream 453 return sal_False; 454 } 455 456 m_xBaseEncryptionData = xTempEncrData; 457 SetIsEncrypted ( sal_True ); 458 // it's already compressed and encrypted 459 bToBeEncrypted = bToBeCompressed = sal_False; 460 461 return sal_True; 462 } 463 464 void ZipPackageStream::SetPackageMember( sal_Bool bNewValue ) 465 { 466 if ( bNewValue ) 467 { 468 m_nStreamMode = PACKAGE_STREAM_PACKAGEMEMBER; 469 m_nMagicalHackPos = 0; 470 m_nMagicalHackSize = 0; 471 } 472 else if ( m_nStreamMode == PACKAGE_STREAM_PACKAGEMEMBER ) 473 m_nStreamMode = PACKAGE_STREAM_NOTSET; // must be reset 474 } 475 476 // XActiveDataSink 477 //-------------------------------------------------------------------------- 478 void SAL_CALL ZipPackageStream::setInputStream( const uno::Reference< io::XInputStream >& aStream ) 479 throw( RuntimeException ) 480 { 481 // if seekable access is required the wrapping will be done on demand 482 xStream = aStream; 483 m_nImportedEncryptionAlgorithm = 0; 484 m_bHasSeekable = sal_False; 485 SetPackageMember ( sal_False ); 486 aEntry.nTime = -1; 487 m_nStreamMode = PACKAGE_STREAM_DETECT; 488 } 489 490 //-------------------------------------------------------------------------- 491 uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getRawData() 492 throw( RuntimeException ) 493 { 494 try 495 { 496 if ( IsPackageMember() ) 497 { 498 return rZipPackage.getZipFile().getRawData( aEntry, GetEncryptionData(), bIsEncrypted, rZipPackage.GetSharedMutexRef() ); 499 } 500 else if ( GetOwnSeekStream().is() ) 501 { 502 return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() ); 503 } 504 else 505 return uno::Reference < io::XInputStream > (); 506 } 507 catch ( ZipException & )//rException ) 508 { 509 VOS_ENSURE( 0, "ZipException thrown" );//rException.Message ); 510 return uno::Reference < io::XInputStream > (); 511 } 512 catch ( Exception & ) 513 { 514 VOS_ENSURE( 0, "Exception is thrown during stream wrapping!\n" ); 515 return uno::Reference < io::XInputStream > (); 516 } 517 } 518 519 //-------------------------------------------------------------------------- 520 uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getInputStream() 521 throw( RuntimeException ) 522 { 523 try 524 { 525 if ( IsPackageMember() ) 526 { 527 return rZipPackage.getZipFile().getInputStream( aEntry, GetEncryptionData(), bIsEncrypted, rZipPackage.GetSharedMutexRef() ); 528 } 529 else if ( GetOwnSeekStream().is() ) 530 { 531 return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() ); 532 } 533 else 534 return uno::Reference < io::XInputStream > (); 535 } 536 catch ( ZipException & )//rException ) 537 { 538 VOS_ENSURE( 0,"ZipException thrown" );//rException.Message ); 539 return uno::Reference < io::XInputStream > (); 540 } 541 catch ( Exception & ) 542 { 543 VOS_ENSURE( 0, "Exception is thrown during stream wrapping!\n" ); 544 return uno::Reference < io::XInputStream > (); 545 } 546 } 547 548 // XDataSinkEncrSupport 549 //-------------------------------------------------------------------------- 550 uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getDataStream() 551 throw ( packages::WrongPasswordException, 552 io::IOException, 553 RuntimeException ) 554 { 555 // There is no stream attached to this object 556 if ( m_nStreamMode == PACKAGE_STREAM_NOTSET ) 557 return uno::Reference< io::XInputStream >(); 558 559 // this method can not be used together with old approach 560 if ( m_nStreamMode == PACKAGE_STREAM_DETECT ) 561 throw packages::zip::ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 562 563 if ( IsPackageMember() ) 564 { 565 uno::Reference< io::XInputStream > xResult; 566 try 567 { 568 xResult = rZipPackage.getZipFile().getDataStream( aEntry, GetEncryptionData(), bIsEncrypted, rZipPackage.GetSharedMutexRef() ); 569 } 570 catch( packages::WrongPasswordException& ) 571 { 572 // workaround for the encrypted documents generated with the old OOo1.x bug. 573 if ( rZipPackage.GetStartKeyGenID() == xml::crypto::DigestID::SHA1 && !m_bUseWinEncoding ) 574 { 575 xResult = rZipPackage.getZipFile().getDataStream( aEntry, GetEncryptionData( true ), bIsEncrypted, rZipPackage.GetSharedMutexRef() ); 576 m_bUseWinEncoding = true; 577 } 578 else 579 throw; 580 } 581 return xResult; 582 } 583 else if ( m_nStreamMode == PACKAGE_STREAM_RAW ) 584 return ZipFile::StaticGetDataFromRawStream( m_xFactory, GetOwnSeekStream(), GetEncryptionData() ); 585 else if ( GetOwnSeekStream().is() ) 586 { 587 return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() ); 588 } 589 else 590 return uno::Reference< io::XInputStream >(); 591 } 592 593 //-------------------------------------------------------------------------- 594 uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getRawStream() 595 throw ( packages::NoEncryptionException, 596 io::IOException, 597 uno::RuntimeException ) 598 { 599 // There is no stream attached to this object 600 if ( m_nStreamMode == PACKAGE_STREAM_NOTSET ) 601 return uno::Reference< io::XInputStream >(); 602 603 // this method can not be used together with old approach 604 if ( m_nStreamMode == PACKAGE_STREAM_DETECT ) 605 throw packages::zip::ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 606 607 if ( IsPackageMember() ) 608 { 609 if ( !bIsEncrypted || !GetEncryptionData().is() ) 610 throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 611 612 return rZipPackage.getZipFile().getWrappedRawStream( aEntry, GetEncryptionData(), sMediaType, rZipPackage.GetSharedMutexRef() ); 613 } 614 else if ( GetOwnSeekStream().is() ) 615 { 616 if ( m_nStreamMode == PACKAGE_STREAM_RAW ) 617 { 618 return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() ); 619 } 620 else if ( m_nStreamMode == PACKAGE_STREAM_DATA && bToBeEncrypted ) 621 return TryToGetRawFromDataStream( sal_True ); 622 } 623 624 throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 625 } 626 627 628 //-------------------------------------------------------------------------- 629 void SAL_CALL ZipPackageStream::setDataStream( const uno::Reference< io::XInputStream >& aStream ) 630 throw ( io::IOException, 631 RuntimeException ) 632 { 633 setInputStream( aStream ); 634 m_nStreamMode = PACKAGE_STREAM_DATA; 635 } 636 637 //-------------------------------------------------------------------------- 638 void SAL_CALL ZipPackageStream::setRawStream( const uno::Reference< io::XInputStream >& aStream ) 639 throw ( packages::EncryptionNotAllowedException, 640 packages::NoRawFormatException, 641 io::IOException, 642 RuntimeException ) 643 { 644 // wrap the stream in case it is not seekable 645 uno::Reference< io::XInputStream > xNewStream = ::comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( aStream, m_xFactory ); 646 uno::Reference< io::XSeekable > xSeek( xNewStream, UNO_QUERY ); 647 if ( !xSeek.is() ) 648 throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "The stream must support XSeekable!" ) ), 649 uno::Reference< XInterface >() ); 650 651 xSeek->seek( 0 ); 652 uno::Reference< io::XInputStream > xOldStream = xStream; 653 xStream = xNewStream; 654 if ( !ParsePackageRawStream() ) 655 { 656 xStream = xOldStream; 657 throw packages::NoRawFormatException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 658 } 659 660 // the raw stream MUST have seekable access 661 m_bHasSeekable = sal_True; 662 663 SetPackageMember ( sal_False ); 664 aEntry.nTime = -1; 665 m_nStreamMode = PACKAGE_STREAM_RAW; 666 } 667 668 //-------------------------------------------------------------------------- 669 uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getPlainRawStream() 670 throw ( io::IOException, 671 uno::RuntimeException ) 672 { 673 // There is no stream attached to this object 674 if ( m_nStreamMode == PACKAGE_STREAM_NOTSET ) 675 return uno::Reference< io::XInputStream >(); 676 677 // this method can not be used together with old approach 678 if ( m_nStreamMode == PACKAGE_STREAM_DETECT ) 679 throw packages::zip::ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 680 681 if ( IsPackageMember() ) 682 { 683 return rZipPackage.getZipFile().getRawData( aEntry, GetEncryptionData(), bIsEncrypted, rZipPackage.GetSharedMutexRef() ); 684 } 685 else if ( GetOwnSeekStream().is() ) 686 { 687 if ( m_nStreamMode == PACKAGE_STREAM_RAW ) 688 { 689 // the header should not be returned here 690 return GetRawEncrStreamNoHeaderCopy(); 691 } 692 else if ( m_nStreamMode == PACKAGE_STREAM_DATA ) 693 return TryToGetRawFromDataStream( sal_False ); 694 } 695 696 return uno::Reference< io::XInputStream >(); 697 } 698 699 // XUnoTunnel 700 701 //-------------------------------------------------------------------------- 702 sal_Int64 SAL_CALL ZipPackageStream::getSomething( const Sequence< sal_Int8 >& aIdentifier ) 703 throw( RuntimeException ) 704 { 705 sal_Int64 nMe = 0; 706 if ( aIdentifier.getLength() == 16 && 707 0 == rtl_compareMemory( static_getImplementationId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) 708 nMe = reinterpret_cast < sal_Int64 > ( this ); 709 return nMe; 710 } 711 712 // XPropertySet 713 //-------------------------------------------------------------------------- 714 void SAL_CALL ZipPackageStream::setPropertyValue( const OUString& aPropertyName, const Any& aValue ) 715 throw( beans::UnknownPropertyException, beans::PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException ) 716 { 717 if ( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" )) ) 718 { 719 if ( rZipPackage.getFormat() != embed::StorageFormats::PACKAGE && rZipPackage.getFormat() != embed::StorageFormats::OFOPXML ) 720 throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 721 722 if ( aValue >>= sMediaType ) 723 { 724 if ( sMediaType.getLength() > 0 ) 725 { 726 if ( sMediaType.indexOf ( OUString( RTL_CONSTASCII_USTRINGPARAM ( "text" ) ) ) != -1 727 || sMediaType.equals( OUString( RTL_CONSTASCII_USTRINGPARAM ( "application/vnd.sun.star.oleobject" ) ) ) ) 728 bToBeCompressed = sal_True; 729 else if ( !m_bCompressedIsSetFromOutside ) 730 bToBeCompressed = sal_False; 731 } 732 } 733 else 734 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "MediaType must be a string!\n" ) ), 735 uno::Reference< XInterface >(), 736 2 ); 737 738 } 739 else if ( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) ) 740 { 741 if ( !( aValue >>= aEntry.nSize ) ) 742 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for Size property!\n" ) ), 743 uno::Reference< XInterface >(), 744 2 ); 745 } 746 else if ( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Encrypted" ) ) ) 747 { 748 if ( rZipPackage.getFormat() != embed::StorageFormats::PACKAGE ) 749 throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 750 751 sal_Bool bEnc = sal_False; 752 if ( aValue >>= bEnc ) 753 { 754 // In case of new raw stream, the stream must not be encrypted on storing 755 if ( bEnc && m_nStreamMode == PACKAGE_STREAM_RAW ) 756 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Raw stream can not be encrypted on storing" ) ), 757 uno::Reference< XInterface >(), 758 2 ); 759 760 bToBeEncrypted = bEnc; 761 if ( bToBeEncrypted && !m_xBaseEncryptionData.is() ) 762 m_xBaseEncryptionData = new BaseEncryptionData; 763 } 764 else 765 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for Encrypted property!\n" ) ), 766 uno::Reference< XInterface >(), 767 2 ); 768 769 } 770 else if ( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ENCRYPTION_KEY_PROPERTY ) ) ) 771 { 772 if ( rZipPackage.getFormat() != embed::StorageFormats::PACKAGE ) 773 throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 774 775 uno::Sequence< sal_Int8 > aNewKey; 776 777 if ( !( aValue >>= aNewKey ) ) 778 { 779 OUString sTempString; 780 if ( ( aValue >>= sTempString ) ) 781 { 782 sal_Int32 nPathLength = sTempString.getLength(); 783 Sequence < sal_Int8 > aSequence ( nPathLength ); 784 sal_Int8 *pArray = aSequence.getArray(); 785 const sal_Unicode *pChar = sTempString.getStr(); 786 for ( sal_Int16 i = 0; i < nPathLength; i++ ) 787 pArray[i] = static_cast < const sal_Int8 > ( pChar[i] ); 788 aNewKey = aSequence; 789 } 790 else 791 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for EncryptionKey property!\n" ) ), 792 uno::Reference< XInterface >(), 793 2 ); 794 } 795 796 if ( aNewKey.getLength() ) 797 { 798 if ( !m_xBaseEncryptionData.is() ) 799 m_xBaseEncryptionData = new BaseEncryptionData; 800 801 m_aEncryptionKey = aNewKey; 802 // In case of new raw stream, the stream must not be encrypted on storing 803 bHaveOwnKey = sal_True; 804 if ( m_nStreamMode != PACKAGE_STREAM_RAW ) 805 bToBeEncrypted = sal_True; 806 } 807 else 808 { 809 bHaveOwnKey = sal_False; 810 m_aEncryptionKey.realloc( 0 ); 811 } 812 813 m_aStorageEncryptionKeys.realloc( 0 ); 814 } 815 else if ( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ) ) 816 { 817 if ( rZipPackage.getFormat() != embed::StorageFormats::PACKAGE ) 818 throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 819 820 uno::Sequence< beans::NamedValue > aKeys; 821 if ( !( aValue >>= aKeys ) ) 822 { 823 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for StorageEncryptionKeys property!\n" ) ), 824 uno::Reference< XInterface >(), 825 2 ); 826 } 827 828 if ( aKeys.getLength() ) 829 { 830 if ( !m_xBaseEncryptionData.is() ) 831 m_xBaseEncryptionData = new BaseEncryptionData; 832 833 m_aStorageEncryptionKeys = aKeys; 834 835 // In case of new raw stream, the stream must not be encrypted on storing 836 bHaveOwnKey = sal_True; 837 if ( m_nStreamMode != PACKAGE_STREAM_RAW ) 838 bToBeEncrypted = sal_True; 839 } 840 else 841 { 842 bHaveOwnKey = sal_False; 843 m_aStorageEncryptionKeys.realloc( 0 ); 844 } 845 846 m_aEncryptionKey.realloc( 0 ); 847 } 848 else if ( aPropertyName.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "Compressed" ) ) ) 849 { 850 sal_Bool bCompr = sal_False; 851 852 if ( aValue >>= bCompr ) 853 { 854 // In case of new raw stream, the stream must not be encrypted on storing 855 if ( bCompr && m_nStreamMode == PACKAGE_STREAM_RAW ) 856 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Raw stream can not be encrypted on storing" ) ), 857 uno::Reference< XInterface >(), 858 2 ); 859 860 bToBeCompressed = bCompr; 861 m_bCompressedIsSetFromOutside = sal_True; 862 } 863 else 864 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for Compressed property!\n" ) ), 865 uno::Reference< XInterface >(), 866 2 ); 867 } 868 else 869 throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 870 } 871 872 //-------------------------------------------------------------------------- 873 Any SAL_CALL ZipPackageStream::getPropertyValue( const OUString& PropertyName ) 874 throw( beans::UnknownPropertyException, WrappedTargetException, RuntimeException ) 875 { 876 Any aAny; 877 if ( PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ) 878 { 879 aAny <<= sMediaType; 880 return aAny; 881 } 882 else if ( PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Size" ) ) ) 883 { 884 aAny <<= aEntry.nSize; 885 return aAny; 886 } 887 else if ( PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Encrypted" ) ) ) 888 { 889 aAny <<= ( m_nStreamMode == PACKAGE_STREAM_RAW ) ? sal_True : bToBeEncrypted; 890 return aAny; 891 } 892 else if ( PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "WasEncrypted" ) ) ) 893 { 894 aAny <<= bIsEncrypted; 895 return aAny; 896 } 897 else if ( PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Compressed" ) ) ) 898 { 899 aAny <<= bToBeCompressed; 900 return aAny; 901 } 902 else if ( PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ENCRYPTION_KEY_PROPERTY ) ) ) 903 { 904 aAny <<= m_aEncryptionKey; 905 return aAny; 906 } 907 else if ( PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ) ) 908 { 909 aAny <<= m_aStorageEncryptionKeys; 910 return aAny; 911 } 912 else 913 throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 914 } 915 916 //-------------------------------------------------------------------------- 917 void ZipPackageStream::setSize ( const sal_Int32 nNewSize ) 918 { 919 if ( aEntry.nCompressedSize != nNewSize ) 920 aEntry.nMethod = DEFLATED; 921 aEntry.nSize = nNewSize; 922 } 923 //-------------------------------------------------------------------------- 924 OUString ZipPackageStream::getImplementationName() 925 throw ( RuntimeException ) 926 { 927 return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "ZipPackageStream" ) ); 928 } 929 930 //-------------------------------------------------------------------------- 931 Sequence< OUString > ZipPackageStream::getSupportedServiceNames() 932 throw ( RuntimeException ) 933 { 934 Sequence< OUString > aNames( 1 ); 935 aNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.PackageStream" ) ); 936 return aNames; 937 } 938 //-------------------------------------------------------------------------- 939 sal_Bool SAL_CALL ZipPackageStream::supportsService( OUString const & rServiceName ) 940 throw ( RuntimeException ) 941 { 942 return rServiceName == getSupportedServiceNames()[0]; 943 } 944 945