diff options
author | Daniel Rentz [dr] <daniel.rentz@oracle.com> | 2010-12-27 12:33:29 +0100 |
---|---|---|
committer | Daniel Rentz [dr] <daniel.rentz@oracle.com> | 2010-12-27 12:33:29 +0100 |
commit | d1743d1d6b0cffe02ddf247ea7f370992791ed7c (patch) | |
tree | a86147c926dfcc5056ee2bb19c1c112722a7d247 /sc/source/filter/excel | |
parent | c2582bb129a0368f5ca054ea8efcc075a75136e8 (diff) | |
parent | e0cef95bab1bd41fce1f08be9d6a2fed71f16944 (diff) |
dr77: rebase to DEV300m96
Diffstat (limited to 'sc/source/filter/excel')
-rw-r--r-- | sc/source/filter/excel/excdoc.cxx | 2 | ||||
-rw-r--r-- | sc/source/filter/excel/excel.cxx | 17 | ||||
-rw-r--r-- | sc/source/filter/excel/excimp8.cxx | 13 | ||||
-rw-r--r-- | sc/source/filter/excel/xeroot.cxx | 64 | ||||
-rw-r--r-- | sc/source/filter/excel/xestream.cxx | 112 | ||||
-rw-r--r-- | sc/source/filter/excel/xicontent.cxx | 2 | ||||
-rw-r--r-- | sc/source/filter/excel/xistream.cxx | 110 | ||||
-rw-r--r-- | sc/source/filter/excel/xlroot.cxx | 6 |
8 files changed, 230 insertions, 96 deletions
diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx index 5623da885daa..7295d42cc2e2 100644 --- a/sc/source/filter/excel/excdoc.cxx +++ b/sc/source/filter/excel/excdoc.cxx @@ -221,7 +221,7 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList ) else { if( IsDocumentEncrypted() ) - Add( new XclExpFilePass( GetRoot() ) ); + Add( new XclExpFileEncryption( GetRoot() ) ); Add( new XclExpInterfaceHdr( nCodePage ) ); Add( new XclExpUInt16Record( EXC_ID_MMS, 0 ) ); Add( new XclExpInterfaceEnd ); diff --git a/sc/source/filter/excel/excel.cxx b/sc/source/filter/excel/excel.cxx index 380a81123f12..e238100f75f8 100644 --- a/sc/source/filter/excel/excel.cxx +++ b/sc/source/filter/excel/excel.cxx @@ -31,6 +31,8 @@ #include <sfx2/docfile.hxx> #include <sfx2/objsh.hxx> #include <sfx2/app.hxx> +#include <sfx2/frame.hxx> +#include <sfx2/request.hxx> #include <sot/storage.hxx> #include <sot/exchange.hxx> #include <tools/globname.hxx> @@ -99,10 +101,17 @@ FltError ScFormatFilterPluginImpl::ScImportExcel( SfxMedium& rMedium, ScDocument SfxItemSet* pItemSet = rMedium.GetItemSet(); if( pItemSet ) { - if( const SfxStringItem* pItem = static_cast< const SfxStringItem* >( pItemSet->GetItem( SID_FILE_NAME ) ) ) - aMediaDesc[ MediaDescriptor::PROP_URL() ] <<= ::rtl::OUString( pItem->GetValue() ); - if( const SfxStringItem* pItem = static_cast< const SfxStringItem* >( pItemSet->GetItem( SID_PASSWORD ) ) ) - aMediaDesc[ MediaDescriptor::PROP_PASSWORD() ] <<= ::rtl::OUString( pItem->GetValue() ); + SFX_ITEMSET_ARG( pItemSet, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False); + if( pFileNameItem ) + aMediaDesc[ MediaDescriptor::PROP_URL() ] <<= ::rtl::OUString( pFileNameItem->GetValue() ); + + SFX_ITEMSET_ARG( pItemSet, pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False); + if( pPasswordItem ) + aMediaDesc[ MediaDescriptor::PROP_PASSWORD() ] <<= ::rtl::OUString( pPasswordItem->GetValue() ); + + SFX_ITEMSET_ARG( pItemSet, pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False); + if( pEncryptionDataItem ) + aMediaDesc[ MediaDescriptor::PROP_ENCRYPTIONDATA() ] = pEncryptionDataItem->GetValue(); } aMediaDesc[ MediaDescriptor::PROP_INPUTSTREAM() ] <<= rMedium.GetInputStream(); aMediaDesc[ MediaDescriptor::PROP_INTERACTIONHANDLER() ] <<= rMedium.GetInteractionHandler(); diff --git a/sc/source/filter/excel/excimp8.cxx b/sc/source/filter/excel/excimp8.cxx index e2640a1f525a..53f850366551 100644 --- a/sc/source/filter/excel/excimp8.cxx +++ b/sc/source/filter/excel/excimp8.cxx @@ -254,10 +254,15 @@ void ImportExcel8::ReadBasic( void ) SfxItemSet* pItemSet = rMedium.GetItemSet(); if( pItemSet ) { - if( const SfxStringItem* pItem = static_cast< const SfxStringItem* >( pItemSet->GetItem( SID_FILE_NAME ) ) ) - aMediaDesc[ MediaDescriptor::PROP_URL() ] <<= ::rtl::OUString( pItem->GetValue() ); - if( const SfxStringItem* pItem = static_cast< const SfxStringItem* >( pItemSet->GetItem( SID_PASSWORD ) ) ) - aMediaDesc[ MediaDescriptor::PROP_PASSWORD() ] <<= ::rtl::OUString( pItem->GetValue() ); + SFX_ITEMSET_ARG( pItemSet, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False ); + if( pFileNameItem ) + aMediaDesc[ MediaDescriptor::PROP_URL() ] <<= ::rtl::OUString( pFileNameItem->GetValue() ); + SFX_ITEMSET_ARG( pItemSet, pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False ); + if( pPasswordItem ) + aMediaDesc[ MediaDescriptor::PROP_PASSWORD() ] <<= ::rtl::OUString( pPasswordItem->GetValue() ); + SFX_ITEMSET_ARG( pItemSet, pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False ); + if( pEncryptionDataItem ) + aMediaDesc[ MediaDescriptor::PROP_ENCRYPTIONDATA() ] = pEncryptionDataItem->GetValue(); } aMediaDesc[ MediaDescriptor::PROP_INPUTSTREAM() ] <<= rMedium.GetInputStream(); aMediaDesc[ MediaDescriptor::PROP_INTERACTIONHANDLER() ] <<= rMedium.GetInteractionHandler(); diff --git a/sc/source/filter/excel/xeroot.cxx b/sc/source/filter/excel/xeroot.cxx index 50e07ae1f2ed..4632a10a088e 100644 --- a/sc/source/filter/excel/xeroot.cxx +++ b/sc/source/filter/excel/xeroot.cxx @@ -28,7 +28,10 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" +#include <rtl/random.h> #include <sfx2/docfile.hxx> +#include <sfx2/request.hxx> +#include <sfx2/frame.hxx> #include <sfx2/sfxsids.hrc> #include <unotools/saveopt.hxx> #include <svl/itemset.hxx> @@ -51,6 +54,8 @@ #include "document.hxx" #include "scextopt.hxx" +using namespace ::com::sun::star; + // Global data ================================================================ XclExpRootData::XclExpRootData( XclBiff eBiff, SfxMedium& rMedium, @@ -241,23 +246,66 @@ bool XclExpRoot::IsDocumentEncrypted() const if (pDocProt && pDocProt->isProtected() && pDocProt->isOptionEnabled(ScDocProtection::STRUCTURE)) return true; - if (GetPassword().Len() > 0) + if ( GetEncryptionData().getLength() > 0 ) // Password is entered directly into the save dialog. return true; return false; } -String XclExpRoot::GetPassword() const +uno::Sequence< beans::NamedValue > XclExpRoot::GenerateEncryptionData( const ::rtl::OUString& aPass ) const { - if( SfxItemSet* pItemSet = GetMedium().GetItemSet() ) + uno::Sequence< beans::NamedValue > aEncryptionData; + + if ( aPass.getLength() > 0 && aPass.getLength() < 16 ) { - const SfxPoolItem* pItem = 0; - if( pItemSet->GetItemState( SID_PASSWORD, TRUE, &pItem ) == SFX_ITEM_SET ) - if( const SfxStringItem* pStrItem = dynamic_cast< const SfxStringItem* >( pItem ) ) - return pStrItem->GetValue(); + TimeValue aTime; + osl_getSystemTime( &aTime ); + rtlRandomPool aRandomPool = rtl_random_createPool (); + rtl_random_addBytes ( aRandomPool, &aTime, 8 ); + + sal_uInt8 pnDocId[16]; + rtl_random_getBytes( aRandomPool, pnDocId, 16 ); + + rtl_random_destroyPool( aRandomPool ); + + sal_uInt16 pnPasswd[16]; + memset( pnPasswd, 0, sizeof( pnPasswd ) ); + for (xub_StrLen nChar = 0; nChar < aPass.getLength(); ++nChar ) + pnPasswd[nChar] = aPass.getStr()[nChar]; + + ::msfilter::MSCodec_Std97 aCodec; + aCodec.InitKey( pnPasswd, pnDocId ); + aEncryptionData = aCodec.GetEncryptionData(); } - return String::EmptyString(); + + return aEncryptionData; +} + +uno::Sequence< beans::NamedValue > XclExpRoot::GetEncryptionData() const +{ + uno::Sequence< beans::NamedValue > aEncryptionData; + SFX_ITEMSET_ARG( GetMedium().GetItemSet(), pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False ); + if ( pEncryptionDataItem ) + pEncryptionDataItem->GetValue() >>= aEncryptionData; + else + { + // try to get the encryption data from the password + SFX_ITEMSET_ARG( GetMedium().GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False ); + if ( pPasswordItem && pPasswordItem->GetValue().Len() ) + aEncryptionData = GenerateEncryptionData( pPasswordItem->GetValue() ); + } + + return aEncryptionData; +} + +uno::Sequence< beans::NamedValue > XclExpRoot::GenerateDefaultEncryptionData() const +{ + uno::Sequence< beans::NamedValue > aEncryptionData; + if ( GetDefaultPassword().Len() > 0 ) + aEncryptionData = GenerateEncryptionData( GetDefaultPassword() ); + + return aEncryptionData; } XclExpRootData::XclExpLinkMgrRef XclExpRoot::GetLocalLinkMgrRef() const diff --git a/sc/source/filter/excel/xestream.cxx b/sc/source/filter/excel/xestream.cxx index d8b3823c5f11..b6b0c3051987 100644 --- a/sc/source/filter/excel/xestream.cxx +++ b/sc/source/filter/excel/xestream.cxx @@ -32,6 +32,7 @@ #include <utility> #include <rtl/ustring.hxx> +#include <rtl/random.h> #include <sax/fshelper.hxx> #include <unotools/streamwrap.hxx> @@ -50,18 +51,15 @@ #define DEBUG_XL_ENCRYPTION 0 -using ::com::sun::star::beans::PropertyValue; -using ::com::sun::star::io::XOutputStream; -using ::com::sun::star::io::XStream; -using ::com::sun::star::lang::XComponent; -using ::com::sun::star::lang::XMultiServiceFactory; -using ::com::sun::star::lang::XServiceInfo; -using ::com::sun::star::sheet::XSpreadsheetDocument; using ::rtl::OString; using ::rtl::OUString; using ::utl::OStreamWrapper; using ::std::vector; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::sheet; using namespace ::com::sun::star::uno; using namespace ::formula; using namespace ::oox; @@ -484,17 +482,16 @@ void XclExpStream::WriteRawZeroBytes( sal_Size nBytes ) // ============================================================================ -XclExpBiff8Encrypter::XclExpBiff8Encrypter( const XclExpRoot& rRoot, const sal_uInt8 nDocId[16], - const sal_uInt8 nSalt[16] ) : +XclExpBiff8Encrypter::XclExpBiff8Encrypter( const XclExpRoot& rRoot ) : mrRoot(rRoot), mnOldPos(STREAM_SEEK_TO_END), mbValid(false) { - String aPass = rRoot.GetPassword(); - if (aPass.Len() == 0) + Sequence< NamedValue > aEncryptionData = rRoot.GetEncryptionData(); + if( !aEncryptionData.hasElements() ) // Empty password. Get the default biff8 password. - aPass = rRoot.GetDefaultPassword(); - Init(aPass, nDocId, nSalt); + aEncryptionData = rRoot.GenerateDefaultEncryptionData(); + Init( aEncryptionData ); } XclExpBiff8Encrypter::~XclExpBiff8Encrypter() @@ -506,9 +503,22 @@ bool XclExpBiff8Encrypter::IsValid() const return mbValid; } -void XclExpBiff8Encrypter::GetSaltDigest( sal_uInt8 nSaltDigest[16] ) const +void XclExpBiff8Encrypter::GetSaltDigest( sal_uInt8 pnSaltDigest[16] ) const { - memcpy(nSaltDigest, mnSaltDigest, 16); + if ( sizeof( mpnSaltDigest ) == 16 ) + memcpy( pnSaltDigest, mpnSaltDigest, 16 ); +} + +void XclExpBiff8Encrypter::GetSalt( sal_uInt8 pnSalt[16] ) const +{ + if ( sizeof( mpnSalt ) == 16 ) + memcpy( pnSalt, mpnSalt, 16 ); +} + +void XclExpBiff8Encrypter::GetDocId( sal_uInt8 pnDocId[16] ) const +{ + if ( sizeof( mpnDocId ) == 16 ) + memcpy( pnDocId, mpnDocId, 16 ); } void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_uInt8 nData ) @@ -565,46 +575,42 @@ void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_Int32 nData ) Encrypt(rStrm, static_cast<sal_uInt32>(nData)); } -void XclExpBiff8Encrypter::Init( const String& aPass, const sal_uInt8 nDocId[16], - const sal_uInt8 nSalt[16] ) +void XclExpBiff8Encrypter::Init( const Sequence< NamedValue >& rEncryptionData ) { - memset(mnSaltDigest, 0, sizeof(mnSaltDigest)); + mbValid = false; - xub_StrLen nLen = aPass.Len(); - bool bValid = (0 < nLen) && (nLen < 16); - if ( bValid ) + if( maCodec.InitCodec( rEncryptionData ) ) { - // transform String to sal_uInt16 array - memset(mnPassw, 0, sizeof(mnPassw)); - for (xub_StrLen nChar = 0; nChar < nLen; ++nChar) - mnPassw[nChar] = static_cast<sal_uInt16>(aPass.GetChar(nChar)); + maCodec.GetDocId( mpnDocId ); - // copy document ID - memcpy(mnDocId, nDocId, sizeof(mnDocId)); + // generate the salt here + TimeValue aTime; + osl_getSystemTime( &aTime ); + rtlRandomPool aRandomPool = rtl_random_createPool (); + rtl_random_addBytes( aRandomPool, &aTime, 8 ); + rtl_random_getBytes( aRandomPool, mpnSalt, 16 ); + rtl_random_destroyPool( aRandomPool ); - // init codec - maCodec.InitKey(mnPassw, mnDocId); + memset( mpnSaltDigest, 0, sizeof( mpnSaltDigest ) ); // generate salt hash. ::msfilter::MSCodec_Std97 aCodec; - aCodec.InitKey(mnPassw, mnDocId); - aCodec.CreateSaltDigest(nSalt, mnSaltDigest); + aCodec.InitCodec( rEncryptionData ); + aCodec.CreateSaltDigest( mpnSalt, mpnSaltDigest ); // verify to make sure it's in good shape. - bValid = maCodec.VerifyKey(nSalt, mnSaltDigest); + mbValid = maCodec.VerifyKey( mpnSalt, mpnSaltDigest ); } - - mbValid = bValid; } sal_uInt32 XclExpBiff8Encrypter::GetBlockPos( sal_Size nStrmPos ) const { - return static_cast<sal_uInt32>(nStrmPos / EXC_ENCR_BLOCKSIZE); + return static_cast< sal_uInt32 >( nStrmPos / EXC_ENCR_BLOCKSIZE ); } sal_uInt16 XclExpBiff8Encrypter::GetOffsetInBlock( sal_Size nStrmPos ) const { - return static_cast<sal_uInt16>(nStrmPos % EXC_ENCR_BLOCKSIZE); + return static_cast< sal_uInt16 >( nStrmPos % EXC_ENCR_BLOCKSIZE ); } void XclExpBiff8Encrypter::EncryptBytes( SvStream& rStrm, vector<sal_uInt8>& aBytes ) @@ -671,9 +677,9 @@ void XclExpBiff8Encrypter::EncryptBytes( SvStream& rStrm, vector<sal_uInt8>& aBy mnOldPos = nStrmPos; } -rtl::OUString XclXmlUtils::GetStreamName( const char* sStreamDir, const char* sStream, sal_Int32 nId ) +OUString XclXmlUtils::GetStreamName( const char* sStreamDir, const char* sStream, sal_Int32 nId ) { - rtl::OUStringBuffer sBuf; + OUStringBuffer sBuf; if( sStreamDir ) sBuf.appendAscii( sStreamDir ); sBuf.appendAscii( sStream ); @@ -683,7 +689,7 @@ rtl::OUString XclXmlUtils::GetStreamName( const char* sStreamDir, const char* sS return sBuf.makeStringAndClear(); } -rtl::OString XclXmlUtils::ToOString( const Color& rColor ) +OString XclXmlUtils::ToOString( const Color& rColor ) { char buf[9]; sprintf( buf, "%.2X%.2X%.2X%.2X", rColor.GetTransparency(), rColor.GetRed(), rColor.GetGreen(), rColor.GetBlue() ); @@ -691,37 +697,37 @@ rtl::OString XclXmlUtils::ToOString( const Color& rColor ) return OString( buf ); } -rtl::OString XclXmlUtils::ToOString( const ::rtl::OUString& s ) +OString XclXmlUtils::ToOString( const OUString& s ) { return OUStringToOString( s, RTL_TEXTENCODING_UTF8 ); } -rtl::OString XclXmlUtils::ToOString( const String& s ) +OString XclXmlUtils::ToOString( const String& s ) { - return rtl::OString( s.GetBuffer(), s.Len(), RTL_TEXTENCODING_UTF8 ); + return OString( s.GetBuffer(), s.Len(), RTL_TEXTENCODING_UTF8 ); } -rtl::OString XclXmlUtils::ToOString( const ScAddress& rAddress ) +OString XclXmlUtils::ToOString( const ScAddress& rAddress ) { String sAddress; rAddress.Format( sAddress, SCA_VALID, NULL, ScAddress::Details( FormulaGrammar::CONV_XL_A1 ) ); return ToOString( sAddress ); } -rtl::OString XclXmlUtils::ToOString( const ScfUInt16Vec& rBuffer ) +OString XclXmlUtils::ToOString( const ScfUInt16Vec& rBuffer ) { const sal_uInt16* pBuffer = &rBuffer [0]; - return ::rtl::OString( pBuffer, rBuffer.size(), RTL_TEXTENCODING_UTF8 ); + return OString( pBuffer, rBuffer.size(), RTL_TEXTENCODING_UTF8 ); } -rtl::OString XclXmlUtils::ToOString( const ScRange& rRange ) +OString XclXmlUtils::ToOString( const ScRange& rRange ) { String sRange; rRange.Format( sRange, SCA_VALID, NULL, ScAddress::Details( FormulaGrammar::CONV_XL_A1 ) ); return ToOString( sRange ); } -rtl::OString XclXmlUtils::ToOString( const ScRangeList& rRangeList ) +OString XclXmlUtils::ToOString( const ScRangeList& rRangeList ) { String s; rRangeList.Format( s, SCA_VALID, NULL, FormulaGrammar::CONV_XL_A1, ' ' ); @@ -741,12 +747,12 @@ static ScAddress lcl_ToAddress( const XclAddress& rAddress ) return aAddress; } -rtl::OString XclXmlUtils::ToOString( const XclAddress& rAddress ) +OString XclXmlUtils::ToOString( const XclAddress& rAddress ) { return ToOString( lcl_ToAddress( rAddress ) ); } -rtl::OString XclXmlUtils::ToOString( const XclExpString& s ) +OString XclXmlUtils::ToOString( const XclExpString& s ) { DBG_ASSERT( !s.IsRich(), "XclXmlUtils::ToOString(XclExpString): rich text string found!" ); return ToOString( s.GetUnicodeBuffer() ); @@ -762,7 +768,7 @@ static ScRange lcl_ToRange( const XclRange& rRange ) return aRange; } -rtl::OString XclXmlUtils::ToOString( const XclRangeList& rRanges ) +OString XclXmlUtils::ToOString( const XclRangeList& rRanges ) { ScRangeList aRanges; for( XclRangeList::const_iterator i = rRanges.begin(), end = rRanges.end(); @@ -791,7 +797,7 @@ OUString XclXmlUtils::ToOUString( const String& s ) return OUString( s.GetBuffer(), s.Len() ); } -rtl::OUString XclXmlUtils::ToOUString( ScDocument& rDocument, const ScAddress& rAddress, ScTokenArray* pTokenArray ) +OUString XclXmlUtils::ToOUString( ScDocument& rDocument, const ScAddress& rAddress, ScTokenArray* pTokenArray ) { ScCompiler aCompiler( &rDocument, rAddress, *pTokenArray); aCompiler.SetGrammar(FormulaGrammar::GRAM_NATIVE_XL_A1); @@ -970,7 +976,7 @@ sax_fastparser::FSHelperPtr XclExpXmlStream::CreateOutputStream ( const Reference< XOutputStream >& xParentRelation, const char* sContentType, const char* sRelationshipType, - ::rtl::OUString* pRelationshipId ) + OUString* pRelationshipId ) { OUString sRelationshipId; if (xParentRelation.is()) @@ -1024,7 +1030,7 @@ bool XclExpXmlStream::exportDocument() throw() return new ::oox::xls::ExcelVbaProject( getComponentContext(), Reference< XSpreadsheetDocument >( getModel(), UNO_QUERY ) ); } -::rtl::OUString XclExpXmlStream::implGetImplementationName() const +OUString XclExpXmlStream::implGetImplementationName() const { return CREATE_OUSTRING( "TODO" ); } diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx index bfd6a787ff36..4aaf0ac9b944 100644 --- a/sc/source/filter/excel/xicontent.cxx +++ b/sc/source/filter/excel/xicontent.cxx @@ -1117,7 +1117,7 @@ ErrCode XclImpDecryptHelper::ReadFilepass( XclImpStream& rStrm ) // request and verify a password (decrypter implements IDocPasswordVerifier) if( xDecr.is() ) - rStrm.GetRoot().RequestPassword( *xDecr ); + rStrm.GetRoot().RequestEncryptionData( *xDecr ); // return error code (success, wrong password, etc.) return xDecr.is() ? xDecr->GetError() : EXC_ENCR_ERROR_UNSUPP_CRYPT; diff --git a/sc/source/filter/excel/xistream.cxx b/sc/source/filter/excel/xistream.cxx index 98db9dcb4471..534d40fa5cd5 100644 --- a/sc/source/filter/excel/xistream.cxx +++ b/sc/source/filter/excel/xistream.cxx @@ -28,6 +28,9 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" +#include <comphelper/docpasswordhelper.hxx> +#include <comphelper/sequenceashashmap.hxx> + #include "xistream.hxx" #include "xlstring.hxx" #include "xiroot.hxx" @@ -38,6 +41,8 @@ using ::rtl::OString; using ::rtl::OUString; using ::rtl::OUStringToOString; +using namespace ::com::sun::star; + // ============================================================================ // Decryption // ============================================================================ @@ -69,9 +74,16 @@ XclImpDecrypterRef XclImpDecrypter::Clone() const return xNewDecr; } -::comphelper::DocPasswordVerifierResult XclImpDecrypter::verifyPassword( const OUString& rPassword ) +::comphelper::DocPasswordVerifierResult XclImpDecrypter::verifyPassword( const ::rtl::OUString& rPassword, uno::Sequence< beans::NamedValue >& o_rEncryptionData ) +{ + o_rEncryptionData = OnVerifyPassword( rPassword ); + mnError = o_rEncryptionData.getLength() ? ERRCODE_NONE : ERRCODE_ABORT; + return o_rEncryptionData.getLength() ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD; +} + +::comphelper::DocPasswordVerifierResult XclImpDecrypter::verifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData ) { - bool bValid = OnVerify( rPassword ); + bool bValid = OnVerifyEncryptionData( rEncryptionData ); mnError = bValid ? ERRCODE_NONE : ERRCODE_ABORT; return bValid ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD; } @@ -110,7 +122,6 @@ sal_uInt16 XclImpDecrypter::Read( SvStream& rStrm, void* pData, sal_uInt16 nByte // ---------------------------------------------------------------------------- XclImpBiff5Decrypter::XclImpBiff5Decrypter( sal_uInt16 nKey, sal_uInt16 nHash ) : - maPassword( 16 ), mnKey( nKey ), mnHash( nHash ) { @@ -118,12 +129,12 @@ XclImpBiff5Decrypter::XclImpBiff5Decrypter( sal_uInt16 nKey, sal_uInt16 nHash ) XclImpBiff5Decrypter::XclImpBiff5Decrypter( const XclImpBiff5Decrypter& rSrc ) : XclImpDecrypter( rSrc ), - maPassword( rSrc.maPassword ), + maEncryptionData( rSrc.maEncryptionData ), mnKey( rSrc.mnKey ), mnHash( rSrc.mnHash ) { if( IsValid() ) - maCodec.InitKey( &maPassword.front() ); + maCodec.InitCodec( maEncryptionData ); } XclImpBiff5Decrypter* XclImpBiff5Decrypter::OnClone() const @@ -131,24 +142,59 @@ XclImpBiff5Decrypter* XclImpBiff5Decrypter::OnClone() const return new XclImpBiff5Decrypter( *this ); } -bool XclImpBiff5Decrypter::OnVerify( const OUString& rPassword ) +uno::Sequence< beans::NamedValue > XclImpBiff5Decrypter::OnVerifyPassword( const ::rtl::OUString& rPassword ) { + maEncryptionData.realloc( 0 ); + /* 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 - maPassword.clear(); - maPassword.resize( 16, 0 ); - memcpy( &maPassword.front(), aBytePassword.getStr(), static_cast< size_t >( nLen ) ); + // init codec + maCodec.InitKey( (sal_uInt8*)aBytePassword.getStr() ); + + if ( maCodec.VerifyKey( mnKey, mnHash ) ) + { + maEncryptionData = maCodec.GetEncryptionData(); + + // since the export uses Std97 encryption always we have to request it here + ::std::vector< sal_uInt16 > aPassVect( 16 ); + ::std::vector< sal_uInt16 >::iterator aIt = aPassVect.begin(); + for( sal_Int32 nInd = 0; nInd < nLen; ++nInd, ++aIt ) + *aIt = static_cast< sal_uInt16 >( rPassword.getStr()[nInd] ); + + uno::Sequence< sal_Int8 > aDocId = ::comphelper::DocPasswordHelper::GenerateRandomByteSequence( 16 ); + OSL_ENSURE( aDocId.getLength() == 16, "Unexpected length of the senquence!" ); + + ::msfilter::MSCodec_Std97 aCodec97; + aCodec97.InitKey( &aPassVect.front(), (sal_uInt8*)aDocId.getConstArray() ); + + // merge the EncryptionData, there should be no conflicts + ::comphelper::SequenceAsHashMap aEncryptionHash( maEncryptionData ); + aEncryptionHash.update( ::comphelper::SequenceAsHashMap( aCodec97.GetEncryptionData() ) ); + aEncryptionHash >> maEncryptionData; + } + } + + return maEncryptionData; +} +bool XclImpBiff5Decrypter::OnVerifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData ) +{ + maEncryptionData.realloc( 0 ); + + if( rEncryptionData.getLength() ) + { // init codec - maCodec.InitKey( &maPassword.front() ); - return maCodec.VerifyKey( mnKey, mnHash ); + maCodec.InitCodec( rEncryptionData ); + + if ( maCodec.VerifyKey( mnKey, mnHash ) ) + maEncryptionData = rEncryptionData; } - return false; + + return maEncryptionData.getLength(); } void XclImpBiff5Decrypter::OnUpdate( sal_Size /*nOldStrmPos*/, sal_Size nNewStrmPos, sal_uInt16 nRecSize ) @@ -168,7 +214,6 @@ sal_uInt16 XclImpBiff5Decrypter::OnRead( SvStream& rStrm, sal_uInt8* pnData, sal XclImpBiff8Decrypter::XclImpBiff8Decrypter( 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 ) @@ -177,13 +222,13 @@ XclImpBiff8Decrypter::XclImpBiff8Decrypter( sal_uInt8 pnSalt[ 16 ], XclImpBiff8Decrypter::XclImpBiff8Decrypter( const XclImpBiff8Decrypter& rSrc ) : XclImpDecrypter( rSrc ), - maPassword( rSrc.maPassword ), + maEncryptionData( rSrc.maEncryptionData ), maSalt( rSrc.maSalt ), maVerifier( rSrc.maVerifier ), maVerifierHash( rSrc.maVerifierHash ) { if( IsValid() ) - maCodec.InitKey( &maPassword.front(), &maSalt.front() ); + maCodec.InitCodec( maEncryptionData ); } XclImpBiff8Decrypter* XclImpBiff8Decrypter::OnClone() const @@ -191,25 +236,44 @@ XclImpBiff8Decrypter* XclImpBiff8Decrypter::OnClone() const return new XclImpBiff8Decrypter( *this ); } -bool XclImpBiff8Decrypter::OnVerify( const OUString& rPassword ) +uno::Sequence< beans::NamedValue > XclImpBiff8Decrypter::OnVerifyPassword( const ::rtl::OUString& rPassword ) { + maEncryptionData.realloc( 0 ); + sal_Int32 nLen = rPassword.getLength(); if( (0 < nLen) && (nLen < 16) ) { // copy string to sal_uInt16 array - maPassword.clear(); - maPassword.resize( 16, 0 ); + ::std::vector< sal_uInt16 > aPassVect( 16 ); const sal_Unicode* pcChar = rPassword.getStr(); const sal_Unicode* pcCharEnd = pcChar + nLen; - ::std::vector< sal_uInt16 >::iterator aIt = maPassword.begin(); + ::std::vector< sal_uInt16 >::iterator aIt = aPassVect.begin(); for( ; pcChar < pcCharEnd; ++pcChar, ++aIt ) *aIt = static_cast< sal_uInt16 >( *pcChar ); // init codec - maCodec.InitKey( &maPassword.front(), &maSalt.front() ); - return maCodec.VerifyKey( &maVerifier.front(), &maVerifierHash.front() ); + maCodec.InitKey( &aPassVect.front(), &maSalt.front() ); + if ( maCodec.VerifyKey( &maVerifier.front(), &maVerifierHash.front() ) ) + maEncryptionData = maCodec.GetEncryptionData(); + } + + return maEncryptionData; +} + +bool XclImpBiff8Decrypter::OnVerifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData ) +{ + maEncryptionData.realloc( 0 ); + + if( rEncryptionData.getLength() ) + { + // init codec + maCodec.InitCodec( rEncryptionData ); + + if ( maCodec.VerifyKey( &maVerifier.front(), &maVerifierHash.front() ) ) + maEncryptionData = rEncryptionData; } - return false; + + return maEncryptionData.getLength(); } void XclImpBiff8Decrypter::OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 /*nRecSize*/ ) diff --git a/sc/source/filter/excel/xlroot.cxx b/sc/source/filter/excel/xlroot.cxx index 2b2180db5e6a..c6d6c5b9246a 100644 --- a/sc/source/filter/excel/xlroot.cxx +++ b/sc/source/filter/excel/xlroot.cxx @@ -71,6 +71,8 @@ using ::com::sun::star::frame::XFrame; using ::com::sun::star::frame::XFramesSupplier; using ::com::sun::star::lang::XMultiServiceFactory; +using namespace ::com::sun::star; + // Global data ================================================================ #ifdef DBG_UTIL @@ -240,11 +242,11 @@ sal_Int32 XclRoot::GetHmmFromPixelY( double fPixelY ) const return static_cast< sal_Int32 >( fPixelY * mrData.mfScreenPixelY + 0.5 ); } -String XclRoot::RequestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const +uno::Sequence< beans::NamedValue > XclRoot::RequestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ) const { ::std::vector< OUString > aDefaultPasswords; aDefaultPasswords.push_back( mrData.maDefPassword ); - return ScfApiHelper::QueryPasswordForMedium( mrData.mrMedium, rVerifier, &aDefaultPasswords ); + return ScfApiHelper::QueryEncryptionDataForMedium( mrData.mrMedium, rVerifier, &aDefaultPasswords ); } bool XclRoot::HasVbaStorage() const |