diff options
author | Oliver Bolte <obo@openoffice.org> | 2009-09-07 14:41:16 +0000 |
---|---|---|
committer | Oliver Bolte <obo@openoffice.org> | 2009-09-07 14:41:16 +0000 |
commit | 9fa41b880dcfef94fa3b7b057f601d97f8a37763 (patch) | |
tree | e9fa09c313164699137f72e8350585a0c8571849 /oox/source/xls/biffcodec.cxx | |
parent | c2f366873f2a3b423265a1ebfdb5e1547d49f3e5 (diff) |
CWS-TOOLING: integrate CWS dr72
2009-08-26 10:24:00 +0200 dr r275402 : #i92645# CODEPAGE is encrypted...
2009-08-24 14:37:36 +0200 dr r275316 : #i10000# enable exceptions for xlroot.cxx
2009-08-24 14:33:15 +0200 dr r275313 : #i10000# link openssl under solaris correctly
2009-08-21 17:41:16 +0200 dr r275267 : #i10000# unxlngi6 warning
2009-08-21 15:35:56 +0200 dr r275265 : #i10000# remove files again, already deleted in previous milestone...
2009-08-21 11:24:57 +0200 dr r275227 : #160401# port to DEV300
2009-08-21 09:53:45 +0200 dr r275221 : #i92645# full support for encrypted Word2007 files
2009-08-21 09:50:52 +0200 dr r275219 : #i92645# final changes for decryption
2009-08-20 19:48:40 +0200 dr r275195 : #i104370# missing parentheses, patch from cmc
2009-08-20 18:28:22 +0200 dr r275193 : #i92645# rework package decryption to repair 'Reload Document' functionality
2009-08-20 13:55:14 +0200 dr r275179 : #i92645# add new property names
2009-08-19 19:24:21 +0200 dr r275159 : #160401# open writeprotected files read-only, merged to DEV300
2009-08-18 14:41:47 +0200 dr r275109 : #i92645# add 'Aborted' property
2009-08-18 11:20:34 +0200 dr r275084 : #i92645# write back password to medium
2009-08-17 17:52:51 +0200 dr r275066 : #i92645# detect Word2007 docs with oox detection impl, this adds support of encryped Word2007; correct detection of templates and macro-enabled docs
2009-08-17 17:51:31 +0200 dr r275065 : #i92645# detect Word2007 docs with oox detection impl, this adds support of encryped Word2007; correct detection of templates and macro-enabled docs
2009-08-17 11:06:39 +0200 dr r275035 : #i92645# more password handling
2009-08-17 11:05:21 +0200 dr r275034 : #i92645# use new password input mechanism for BIFF filter and dumper in oox
2009-08-14 16:33:53 +0200 nn r274996 : #i104228# DelBroadcastAreasInRange: remove area from hash_set before deleting
2009-08-14 16:27:12 +0200 nn r274995 : #i104059# restore a change lost in the integration of fhawfixes1
2009-08-14 16:24:00 +0200 dr r274994 : #i92645# adapt BIFF import to latest changes
2009-08-14 16:21:30 +0200 dr r274993 : #i92645# adapt BIFF import to latest changes
2009-08-14 16:20:43 +0200 dr r274992 : #i92645# do not add default passwords to media descriptor
2009-08-13 19:20:45 +0200 dr r274965 : #i92645# add a helper to request a document password
2009-08-13 19:09:35 +0200 dr r274964 : #i92645# add a helper to request a document password
2009-08-13 19:09:03 +0200 dr r274963 : #i92645# add a helper to request a document password
2009-08-13 14:35:01 +0200 dr r274946 : #i92645# comment typo
2009-08-13 14:33:47 +0200 dr r274945 : #i92645# add a helper to request a document password
2009-08-13 14:04:47 +0200 dr r274941 : #i92645# add a helper to request a document password
2009-08-13 14:04:22 +0200 dr r274940 : #i92645# add a helper to request a document password
2009-08-13 11:16:27 +0200 dr r274927 : #i42303# show quick help if field name too long for button
2009-08-13 10:55:48 +0200 dr r274925 : #i31600# cut field name and add ellipsis, if too long for button
2009-08-12 18:47:26 +0200 dr r274914 : #i92645# ask user for a password
2009-08-12 18:02:39 +0200 dr r274909 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox
2009-08-12 16:59:11 +0200 dr r274906 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox
2009-08-12 16:41:18 +0200 dr r274905 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox
2009-08-12 16:40:33 +0200 dr r274904 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox
2009-08-12 16:40:08 +0200 dr r274903 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox
2009-08-12 16:39:30 +0200 dr r274902 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox
2009-08-12 16:15:28 +0200 dr r274899 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox
2009-08-11 19:51:12 +0200 dr r274877 : #i92645# open encrypted MSOOXML package protected with standard XL password 'VelvetSweatshop'
Diffstat (limited to 'oox/source/xls/biffcodec.cxx')
-rw-r--r-- | oox/source/xls/biffcodec.cxx | 289 |
1 files changed, 132 insertions, 157 deletions
diff --git a/oox/source/xls/biffcodec.cxx b/oox/source/xls/biffcodec.cxx index b76f51ad0e7e..a589b1b3218f 100644 --- a/oox/source/xls/biffcodec.cxx +++ b/oox/source/xls/biffcodec.cxx @@ -31,95 +31,89 @@ #include "oox/xls/biffcodec.hxx" #include <osl/thread.h> #include <string.h> +#include "oox/core/filterbase.hxx" #include "oox/xls/biffinputstream.hxx" using ::rtl::OString; using ::rtl::OUString; using ::rtl::OStringToOUString; +using ::oox::core::FilterBase; namespace oox { namespace xls { // ============================================================================ -BiffDecoderBase::BiffDecoderBase( const WorkbookHelper& rHelper ) : - WorkbookHelper( rHelper ), - mnError( CODEC_ERROR_UNSUPP_CRYPT ) +BiffDecoderBase::BiffDecoderBase() : + mbValid( false ) { } -BiffDecoderBase::BiffDecoderBase( const BiffDecoderBase& rDecoder ) : - WorkbookHelper( rDecoder ), - mnError( rDecoder.mnError ) +BiffDecoderBase::~BiffDecoderBase() { } -BiffDecoderBase::~BiffDecoderBase() +::comphelper::DocPasswordVerifierResult BiffDecoderBase::verifyPassword( const OUString& rPassword ) { + mbValid = implVerify( rPassword ); + return mbValid ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD; } void BiffDecoderBase::decode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes ) { if( pnDestData && pnSrcData && (nBytes > 0) ) { - if( isValid() ) + if( mbValid ) implDecode( pnDestData, pnSrcData, nStreamPos, nBytes ); else memcpy( pnDestData, pnSrcData, nBytes ); } } -void BiffDecoderBase::setHasValidPassword( bool bValid ) -{ - mnError = bValid ? CODEC_OK : CODEC_ERROR_WRONG_PASS; -} - // ============================================================================ -BiffDecoder_XOR::BiffDecoder_XOR( const WorkbookHelper& rHelper, sal_uInt16 nKey, sal_uInt16 nHash ) : - BiffDecoderBase( rHelper ), +BiffDecoder_XOR::BiffDecoder_XOR( sal_uInt16 nKey, sal_uInt16 nHash ) : maCodec( ::oox::core::BinaryCodec_XOR::CODEC_EXCEL ), + maPassword( 16 ), mnKey( nKey ), mnHash( nHash ) { - init( BiffCodecHelper::getBiff5WbProtPassword() ); - if( !isValid() ) - init( OUStringToOString( getCodecHelper().queryPassword(), osl_getThreadTextEncoding() ) ); } BiffDecoder_XOR::BiffDecoder_XOR( const BiffDecoder_XOR& rDecoder ) : - BiffDecoderBase( rDecoder ), + BiffDecoderBase(), // must be called to prevent compiler warning maCodec( ::oox::core::BinaryCodec_XOR::CODEC_EXCEL ), + maPassword( rDecoder.maPassword ), mnKey( rDecoder.mnKey ), mnHash( rDecoder.mnHash ) { - init( rDecoder.maPass ); + if( isValid() ) + maCodec.initKey( &maPassword.front() ); } -void BiffDecoder_XOR::init( const OString& rPass ) +BiffDecoder_XOR* BiffDecoder_XOR::implClone() { - maPass = rPass; - sal_Int32 nLen = maPass.getLength(); - bool bValid = (0 < nLen) && (nLen < 16); + return new BiffDecoder_XOR( *this ); +} - if( bValid ) +bool BiffDecoder_XOR::implVerify( const OUString& rPassword ) +{ + /* Convert password to a byte string. TODO: this needs some finetuning + according to the spec... */ + OString aBytePassword = OUStringToOString( rPassword, osl_getThreadTextEncoding() ); + sal_Int32 nLen = aBytePassword.getLength(); + if( (0 < nLen) && (nLen < 16) ) { // copy byte string to sal_uInt8 array - sal_uInt8 pnPassw[ 16 ]; - memset( pnPassw, 0, sizeof( pnPassw ) ); - memcpy( pnPassw, maPass.getStr(), static_cast< size_t >( nLen ) ); + maPassword.clear(); + maPassword.resize( 16, 0 ); + memcpy( &maPassword.front(), aBytePassword.getStr(), static_cast< size_t >( nLen ) ); // init codec - maCodec.initKey( pnPassw ); - bValid = maCodec.verifyKey( mnKey, mnHash ); + maCodec.initKey( &maPassword.front() ); + return maCodec.verifyKey( mnKey, mnHash ); } - - setHasValidPassword( bValid ); -} - -BiffDecoder_XOR* BiffDecoder_XOR::implClone() -{ - return new BiffDecoder_XOR( *this ); + return false; } void BiffDecoder_XOR::implDecode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes ) @@ -149,55 +143,49 @@ sal_Int32 lclGetRcfOffset( sal_Int64 nStreamPos ) // ---------------------------------------------------------------------------- -BiffDecoder_RCF::BiffDecoder_RCF( const WorkbookHelper& rHelper, - sal_uInt8 pnDocId[ 16 ], sal_uInt8 pnSaltData[ 16 ], sal_uInt8 pnSaltHash[ 16 ] ) : - BiffDecoderBase( rHelper ), - maDocId( pnDocId, pnDocId + 16 ), - maSaltData( pnSaltData, pnSaltData + 16 ), - maSaltHash( pnSaltHash, pnSaltHash + 16 ) +BiffDecoder_RCF::BiffDecoder_RCF( sal_uInt8 pnSalt[ 16 ], sal_uInt8 pnVerifier[ 16 ], sal_uInt8 pnVerifierHash[ 16 ] ) : + maPassword( 16, 0 ), + maSalt( pnSalt, pnSalt + 16 ), + maVerifier( pnVerifier, pnVerifier + 16 ), + maVerifierHash( pnVerifierHash, pnVerifierHash + 16 ) { - init( BiffCodecHelper::getBiff8WbProtPassword() ); - if( !isValid() ) - init( getCodecHelper().queryPassword() ); } BiffDecoder_RCF::BiffDecoder_RCF( const BiffDecoder_RCF& rDecoder ) : - BiffDecoderBase( rDecoder ), - maDocId( rDecoder.maDocId ), - maSaltData( rDecoder.maSaltData ), - maSaltHash( rDecoder.maSaltHash ) + BiffDecoderBase(), // must be called to prevent compiler warning + maPassword( rDecoder.maPassword ), + maSalt( rDecoder.maSalt ), + maVerifier( rDecoder.maVerifier ), + maVerifierHash( rDecoder.maVerifierHash ) { - init( rDecoder.maPass ); + if( isValid() ) + maCodec.initKey( &maPassword.front(), &maSalt.front() ); } -void BiffDecoder_RCF::init( const OUString& rPass ) +BiffDecoder_RCF* BiffDecoder_RCF::implClone() { - maPass = rPass; - sal_Int32 nLen = maPass.getLength(); - bool bValid = (0 < nLen) && (nLen < 16); + return new BiffDecoder_RCF( *this ); +} - if( bValid ) +bool BiffDecoder_RCF::implVerify( const OUString& rPassword ) +{ + sal_Int32 nLen = rPassword.getLength(); + if( (0 < nLen) && (nLen < 16) ) { // copy string to sal_uInt16 array - sal_uInt16 pnPassw[ 16 ]; - memset( pnPassw, 0, sizeof( pnPassw ) ); - const sal_Unicode* pcChar = maPass.getStr(); + maPassword.clear(); + maPassword.resize( 16, 0 ); + const sal_Unicode* pcChar = rPassword.getStr(); const sal_Unicode* pcCharEnd = pcChar + nLen; - sal_uInt16* pnCurrPass = pnPassw; - for( ; pcChar < pcCharEnd; ++pcChar, ++pnCurrPass ) - *pnCurrPass = static_cast< sal_uInt16 >( *pcChar ); + ::std::vector< sal_uInt16 >::iterator aIt = maPassword.begin(); + for( ; pcChar < pcCharEnd; ++pcChar, ++aIt ) + *aIt = static_cast< sal_uInt16 >( *pcChar ); // init codec - maCodec.initKey( pnPassw, &maDocId.front() ); - bValid = maCodec.verifyKey( &maSaltData.front(), &maSaltHash.front() ); + maCodec.initKey( &maPassword.front(), &maSalt.front() ); + return maCodec.verifyKey( &maVerifier.front(), &maVerifierHash.front() ); } - - setHasValidPassword( bValid ); -} - -BiffDecoder_RCF* BiffDecoder_RCF::implClone() -{ - return new BiffDecoder_RCF( *this ); + return false; } void BiffDecoder_RCF::implDecode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes ) @@ -229,130 +217,117 @@ void BiffDecoder_RCF::implDecode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcD namespace { -const sal_uInt16 BIFF_FILEPASS_BIFF2 = 0x0000; -const sal_uInt16 BIFF_FILEPASS_BIFF8 = 0x0001; -const sal_uInt16 BIFF_FILEPASS_BIFF8_RCF = 0x0001; -const sal_uInt16 BIFF_FILEPASS_BIFF8_STRONG = 0x0002; +const sal_uInt16 BIFF_FILEPASS_XOR = 0; +const sal_uInt16 BIFF_FILEPASS_RCF = 1; -} // namespace +const sal_uInt16 BIFF_FILEPASS_BIFF8_RCF = 1; +const sal_uInt16 BIFF_FILEPASS_BIFF8_CRYPTOAPI_2003 = 2; +const sal_uInt16 BIFF_FILEPASS_BIFF8_CRYPTOAPI_2007 = 3; // ---------------------------------------------------------------------------- -BiffCodecHelper::BiffCodecHelper( const WorkbookHelper& rHelper ) : - WorkbookHelper( rHelper ), - mbHasPassword( false ) -{ -} - -const OString& BiffCodecHelper::getBiff5WbProtPassword() -{ - static const OString saPass( "VelvetSweatshop" ); - return saPass; -} - -const OUString& BiffCodecHelper::getBiff8WbProtPassword() +BiffDecoderRef lclReadFilePass_XOR( BiffInputStream& rStrm ) { - static const OUString saPass = OStringToOUString( getBiff5WbProtPassword(), RTL_TEXTENCODING_ASCII_US ); - return saPass; -} - -OUString BiffCodecHelper::queryPassword() -{ - if( !mbHasPassword ) - { - //! TODO - maPassword = OUString(); - // set to true, even if dialog has been cancelled (never ask twice) - mbHasPassword = true; - } - return maPassword; -} - -bool BiffCodecHelper::importFilePass( BiffInputStream& rStrm ) -{ - OSL_ENSURE( !mxDecoder, "BiffCodecHelper::importFilePass - multiple FILEPASS records" ); - rStrm.enableDecoder( false ); - mxDecoder.reset(); - if( getBiff() == BIFF8 ) importFilePass8( rStrm ); else importFilePass2( rStrm ); - - // set decoder at import stream - rStrm.setDecoder( mxDecoder ); - //! TODO remember encryption state for export -// mrStrm.GetRoot().GetExtDocOptions().GetDocSettings().mbEncrypted = true; - - return mxDecoder.get() && mxDecoder->isValid(); -} - -void BiffCodecHelper::cloneDecoder( BiffInputStream& rStrm ) -{ - if( mxDecoder.get() ) - rStrm.setDecoder( BiffDecoderRef( mxDecoder->clone() ) ); -} - -// private -------------------------------------------------------------------- - -void BiffCodecHelper::importFilePass_XOR( BiffInputStream& rStrm ) -{ - OSL_ENSURE( rStrm.getRemaining() == 4, "BiffCodecHelper::importFilePass_XOR - wrong record size" ); + BiffDecoderRef xDecoder; + OSL_ENSURE( rStrm.getRemaining() == 4, "lclReadFilePass_XOR - wrong record size" ); if( rStrm.getRemaining() == 4 ) { sal_uInt16 nBaseKey, nHash; rStrm >> nBaseKey >> nHash; - mxDecoder.reset( new BiffDecoder_XOR( *this, nBaseKey, nHash ) ); + xDecoder.reset( new BiffDecoder_XOR( nBaseKey, nHash ) ); } + return xDecoder; } -void BiffCodecHelper::importFilePass_RCF( BiffInputStream& rStrm ) +BiffDecoderRef lclReadFilePass_RCF( BiffInputStream& rStrm ) { - OSL_ENSURE( rStrm.getRemaining() == 48, "BiffCodecHelper::importFilePass_RCF - wrong record size" ); + BiffDecoderRef xDecoder; + OSL_ENSURE( rStrm.getRemaining() == 48, "lclReadFilePass_RCF - wrong record size" ); if( rStrm.getRemaining() == 48 ) { - sal_uInt8 pnDocId[ 16 ]; - sal_uInt8 pnSaltData[ 16 ]; - sal_uInt8 pnSaltHash[ 16 ]; - rStrm.readMemory( pnDocId, 16 ); - rStrm.readMemory( pnSaltData, 16 ); - rStrm.readMemory( pnSaltHash, 16 ); - mxDecoder.reset( new BiffDecoder_RCF( *this, pnDocId, pnSaltData, pnSaltHash ) ); + sal_uInt8 pnSalt[ 16 ]; + sal_uInt8 pnVerifier[ 16 ]; + sal_uInt8 pnVerifierHash[ 16 ]; + rStrm.readMemory( pnSalt, 16 ); + rStrm.readMemory( pnVerifier, 16 ); + rStrm.readMemory( pnVerifierHash, 16 ); + xDecoder.reset( new BiffDecoder_RCF( pnSalt, pnVerifier, pnVerifierHash ) ); } + return xDecoder; } -void BiffCodecHelper::importFilePass_Strong( BiffInputStream& /*rStrm*/ ) +BiffDecoderRef lclReadFilePass_CryptoApi( BiffInputStream& /*rStrm*/ ) { // not supported + return BiffDecoderRef(); } -void BiffCodecHelper::importFilePass2( BiffInputStream& rStrm ) -{ - importFilePass_XOR( rStrm ); -} - -void BiffCodecHelper::importFilePass8( BiffInputStream& rStrm ) +BiffDecoderRef lclReadFilePassBiff8( BiffInputStream& rStrm ) { + BiffDecoderRef xDecoder; switch( rStrm.readuInt16() ) { - case BIFF_FILEPASS_BIFF2: - importFilePass_XOR( rStrm ); + case BIFF_FILEPASS_XOR: + xDecoder = lclReadFilePass_XOR( rStrm ); break; - case BIFF_FILEPASS_BIFF8: + case BIFF_FILEPASS_RCF: + { + sal_uInt16 nMajor = rStrm.readuInt16(); rStrm.skip( 2 ); - switch( rStrm.readuInt16() ) + switch( nMajor ) { case BIFF_FILEPASS_BIFF8_RCF: - importFilePass_RCF( rStrm ); + xDecoder = lclReadFilePass_RCF( rStrm ); break; - case BIFF_FILEPASS_BIFF8_STRONG: - importFilePass_Strong( rStrm ); + case BIFF_FILEPASS_BIFF8_CRYPTOAPI_2003: + case BIFF_FILEPASS_BIFF8_CRYPTOAPI_2007: + xDecoder = lclReadFilePass_CryptoApi( rStrm ); break; default: - OSL_ENSURE( false, "BiffCodecHelper::importFilePass8 - unknown BIFF8 encryption sub mode" ); + OSL_ENSURE( false, "lclReadFilePassBiff8 - unknown BIFF8 encryption sub mode" ); } + } break; default: - OSL_ENSURE( false, "BiffCodecHelper::importFilePass8 - unknown encryption mode" ); + OSL_ENSURE( false, "lclReadFilePassBiff8 - unknown encryption mode" ); } + return xDecoder; +} + +} // namespace + +// ---------------------------------------------------------------------------- + +BiffCodecHelper::BiffCodecHelper( const WorkbookHelper& rHelper ) : + WorkbookHelper( rHelper ) +{ +} + +/*static*/ BiffDecoderRef BiffCodecHelper::implReadFilePass( BiffInputStream& rStrm, BiffType eBiff ) +{ + rStrm.enableDecoder( false ); + BiffDecoderRef xDecoder = (eBiff == BIFF8) ? lclReadFilePassBiff8( rStrm ) : lclReadFilePass_XOR( rStrm ); + rStrm.setDecoder( xDecoder ); + return xDecoder; +} + +bool BiffCodecHelper::importFilePass( BiffInputStream& rStrm ) +{ + OSL_ENSURE( !mxDecoder, "BiffCodecHelper::importFilePass - multiple FILEPASS records" ); + mxDecoder = implReadFilePass( rStrm, getBiff() ); + // request and verify a password (decoder implements IDocPasswordVerifier) + if( mxDecoder.get() ) + getBaseFilter().requestPassword( *mxDecoder ); + // correct password is indicated by isValid() function of decoder + return mxDecoder.get() && mxDecoder->isValid(); +} + +void BiffCodecHelper::cloneDecoder( BiffInputStream& rStrm ) +{ + if( mxDecoder.get() ) + rStrm.setDecoder( BiffDecoderRef( mxDecoder->clone() ) ); } // ============================================================================ |