summaryrefslogtreecommitdiff
path: root/oox/source/xls/biffcodec.cxx
diff options
context:
space:
mode:
authorOliver Bolte <obo@openoffice.org>2009-09-07 14:41:16 +0000
committerOliver Bolte <obo@openoffice.org>2009-09-07 14:41:16 +0000
commit9fa41b880dcfef94fa3b7b057f601d97f8a37763 (patch)
treee9fa09c313164699137f72e8350585a0c8571849 /oox/source/xls/biffcodec.cxx
parentc2f366873f2a3b423265a1ebfdb5e1547d49f3e5 (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.cxx289
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() ) );
}
// ============================================================================