diff options
author | Ivo Hinkelmann <ihi@openoffice.org> | 2010-11-30 17:00:37 +0100 |
---|---|---|
committer | Ivo Hinkelmann <ihi@openoffice.org> | 2010-11-30 17:00:37 +0100 |
commit | b0816eb88892669128e9a04516d51330a663f171 (patch) | |
tree | 37eff1eeaaa48b1f40b34da22e3719ad90c6dcd0 | |
parent | dbb4b0ecb6454f358417adc1e0f6e71b16b6dd2d (diff) | |
parent | 9f593058be35599d9520d064433411d3cadc3601 (diff) |
CWS-TOOLING: integrate CWS pl08ooo/DEV300_m95
-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/xeroot.cxx | 64 | ||||
-rw-r--r-- | sc/source/filter/excel/xestream.cxx | 64 | ||||
-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 | ||||
-rw-r--r-- | sc/source/filter/ftools/fapihelper.cxx | 34 | ||||
-rw-r--r-- | sc/source/filter/inc/fapihelper.hxx | 7 | ||||
-rw-r--r-- | sc/source/filter/inc/xcl97rec.hxx | 6 | ||||
-rw-r--r-- | sc/source/filter/inc/xeroot.hxx | 6 | ||||
-rw-r--r-- | sc/source/filter/inc/xestream.hxx | 18 | ||||
-rw-r--r-- | sc/source/filter/inc/xistream.hxx | 24 | ||||
-rw-r--r-- | sc/source/filter/inc/xlroot.hxx | 5 | ||||
-rw-r--r-- | sc/source/filter/xcl97/xcl97rec.cxx | 33 |
15 files changed, 277 insertions, 121 deletions
diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx index 0c6153857..493976998 100644 --- a/sc/source/filter/excel/excdoc.cxx +++ b/sc/source/filter/excel/excdoc.cxx @@ -222,7 +222,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 cd95b023e..1c39420b3 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/xeroot.cxx b/sc/source/filter/excel/xeroot.cxx index 50e07ae1f..acd1fb051 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 51d6d3a1d..4a2b64f14 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> @@ -65,6 +66,7 @@ using ::utl::OStreamWrapper; using ::std::vector; using namespace formula; +using namespace ::com::sun::star; // ============================================================================ @@ -484,17 +486,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) + uno::Sequence< beans::NamedValue > aEncryptionData = rRoot.GetEncryptionData(); + if ( aEncryptionData.getLength() == 0 ) // Empty password. Get the default biff8 password. - aPass = rRoot.GetDefaultPassword(); - Init(aPass, nDocId, nSalt); + aEncryptionData = rRoot.GenerateDefaultEncryptionData(); + Init( aEncryptionData ); } XclExpBiff8Encrypter::~XclExpBiff8Encrypter() @@ -506,9 +507,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,36 +579,32 @@ 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 uno::Sequence< beans::NamedValue >& aEncryptionData ) { - memset(mnSaltDigest, 0, sizeof(mnSaltDigest)); + mbValid = false; - xub_StrLen nLen = aPass.Len(); - bool bValid = (0 < nLen) && (nLen < 16); - if ( bValid ) + if ( maCodec.InitCodec( aEncryptionData ) ) { - // 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( aEncryptionData ); + 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 diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx index 1b3efb20a..7cff78c47 100644 --- a/sc/source/filter/excel/xicontent.cxx +++ b/sc/source/filter/excel/xicontent.cxx @@ -1118,7 +1118,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 84f28383e..eb3f3849e 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 7870b9fd4..7ad19b9a3 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 diff --git a/sc/source/filter/ftools/fapihelper.cxx b/sc/source/filter/ftools/fapihelper.cxx index 559c0b853..7187078f2 100644 --- a/sc/source/filter/ftools/fapihelper.cxx +++ b/sc/source/filter/ftools/fapihelper.cxx @@ -38,6 +38,8 @@ #include <tools/urlobj.hxx> #include <sfx2/objsh.hxx> #include <sfx2/docfile.hxx> +#include <sfx2/request.hxx> +#include <sfx2/frame.hxx> #include <sfx2/sfxsids.hrc> #include <svl/stritem.hxx> #include <svl/itemset.hxx> @@ -59,6 +61,8 @@ using ::com::sun::star::lang::XServiceName; using ::com::sun::star::lang::XMultiServiceFactory; using ::com::sun::star::task::PasswordRequestMode_PASSWORD_ENTER; +using namespace ::com::sun::star; + // Static helper functions ==================================================== OUString ScfApiHelper::GetServiceName( Reference< XInterface > xInt ) @@ -136,25 +140,33 @@ Reference< XInterface > ScfApiHelper::CreateInstanceWithArgs( return CreateInstanceWithArgs( ::comphelper::getProcessServiceFactory(), rServiceName, rArgs ); } -String ScfApiHelper::QueryPasswordForMedium( SfxMedium& rMedium, +uno::Sequence< beans::NamedValue > ScfApiHelper::QueryEncryptionDataForMedium( SfxMedium& rMedium, ::comphelper::IDocPasswordVerifier& rVerifier, const ::std::vector< OUString >* pDefaultPasswords ) { - OUString aMediaPassword; - SfxItemSet* pItemSet = rMedium.GetItemSet(); - const SfxPoolItem *pPasswordItem; - if( pItemSet && (SFX_ITEM_SET == pItemSet->GetItemState( SID_PASSWORD, TRUE, &pPasswordItem )) ) - aMediaPassword = static_cast< const SfxStringItem* >( pPasswordItem )->GetValue(); + uno::Sequence< beans::NamedValue > aEncryptionData; + SFX_ITEMSET_ARG( rMedium.GetItemSet(), pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False); + if ( pEncryptionDataItem ) + pEncryptionDataItem->GetValue() >>= aEncryptionData; + + ::rtl::OUString aPassword; + SFX_ITEMSET_ARG( rMedium.GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False); + if ( pPasswordItem ) + aPassword = pPasswordItem->GetValue(); + OUString aDocName = INetURLObject( rMedium.GetOrigURL() ).GetName( INetURLObject::DECODE_WITH_CHARSET ); bool bIsDefaultPassword = false; - OUString aPassword = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword( - rVerifier, aMediaPassword, rMedium.GetInteractionHandler(), aDocName, + aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword( + rVerifier, aEncryptionData, aPassword, rMedium.GetInteractionHandler(), aDocName, ::comphelper::DocPasswordRequestType_MS, pDefaultPasswords, &bIsDefaultPassword ); - if( !bIsDefaultPassword && (aPassword.getLength() > 0) && pItemSet ) - pItemSet->Put( SfxStringItem( SID_PASSWORD, aPassword ) ); + rMedium.GetItemSet()->ClearItem( SID_PASSWORD ); + rMedium.GetItemSet()->ClearItem( SID_ENCRYPTIONDATA ); + + if( !bIsDefaultPassword && (aEncryptionData.getLength() > 0) ) + rMedium.GetItemSet()->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) ); - return aPassword; + return aEncryptionData; } // Property sets ============================================================== diff --git a/sc/source/filter/inc/fapihelper.hxx b/sc/source/filter/inc/fapihelper.hxx index c6c3483c6..2d05eab71 100644 --- a/sc/source/filter/inc/fapihelper.hxx +++ b/sc/source/filter/inc/fapihelper.hxx @@ -33,6 +33,7 @@ #include <com/sun/star/uno/Sequence.hxx> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/beans/XMultiPropertySet.hpp> +#include <com/sun/star/beans/NamedValue.hpp> #include <tools/color.hxx> #include <comphelper/types.hxx> #include "ftools.hxx" @@ -106,9 +107,9 @@ public: const ::rtl::OUString& rServiceName, const UnoAnySequence& rArgs ); - /** Opens a password dialog and returns the entered password. - @return The entered password or an empty string on 'Cancel' or any error. */ - static String QueryPasswordForMedium( SfxMedium& rMedium, + /** Opens a password dialog and returns the encryption data. + @return The encryption data or an empty sequence on 'Cancel' or any error. */ + static ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > QueryEncryptionDataForMedium( SfxMedium& rMedium, ::comphelper::IDocPasswordVerifier& rVerifier, const ::std::vector< ::rtl::OUString >* pDefaultPasswords = 0 ); }; diff --git a/sc/source/filter/inc/xcl97rec.hxx b/sc/source/filter/inc/xcl97rec.hxx index 82db77305..5f4e7f4a0 100644 --- a/sc/source/filter/inc/xcl97rec.hxx +++ b/sc/source/filter/inc/xcl97rec.hxx @@ -478,11 +478,11 @@ public: // ============================================================================ -class XclExpFilePass : public XclExpRecord +class XclExpFileEncryption : public XclExpRecord { public: - explicit XclExpFilePass( const XclExpRoot& rRoot ); - virtual ~XclExpFilePass(); + explicit XclExpFileEncryption( const XclExpRoot& rRoot ); + virtual ~XclExpFileEncryption(); private: virtual void WriteBody( XclExpStream& rStrm ); diff --git a/sc/source/filter/inc/xeroot.hxx b/sc/source/filter/inc/xeroot.hxx index 980590f9d..ba51abdef 100644 --- a/sc/source/filter/inc/xeroot.hxx +++ b/sc/source/filter/inc/xeroot.hxx @@ -28,6 +28,8 @@ #ifndef SC_XEROOT_HXX #define SC_XEROOT_HXX +#include <com/sun/star/beans/NamedValue.hpp> + #include "xlroot.hxx" // Forward declarations of objects in public use ============================== @@ -158,7 +160,9 @@ public: bool IsDocumentEncrypted() const; - String GetPassword() const; + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GenerateEncryptionData( const ::rtl::OUString& aPass ) const; + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GetEncryptionData() const; + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GenerateDefaultEncryptionData() const; private: diff --git a/sc/source/filter/inc/xestream.hxx b/sc/source/filter/inc/xestream.hxx index a8fae8fdf..397ebcd7b 100644 --- a/sc/source/filter/inc/xestream.hxx +++ b/sc/source/filter/inc/xestream.hxx @@ -30,6 +30,8 @@ #ifndef SC_XESTREAM_HXX #define SC_XESTREAM_HXX +#include <com/sun/star/beans/NamedValue.hpp> + #include <map> #include <stack> #include <string> @@ -216,13 +218,14 @@ private: class XclExpBiff8Encrypter { public: - explicit XclExpBiff8Encrypter( const XclExpRoot& rRoot, const sal_uInt8 nDocId[16], - const sal_uInt8 nSalt[16] ); + explicit XclExpBiff8Encrypter( const XclExpRoot& rRoot ); ~XclExpBiff8Encrypter(); bool IsValid() const; - void GetSaltDigest( sal_uInt8 nSaltDigest[16] ) const; + void GetSaltDigest( sal_uInt8 pnSaltDigest[16] ) const; + void GetSalt( sal_uInt8 pnSalt[16] ) const; + void GetDocId( sal_uInt8 pnDocId[16] ) const; void Encrypt( SvStream& rStrm, sal_uInt8 nData ); void Encrypt( SvStream& rStrm, sal_uInt16 nData ); @@ -238,17 +241,16 @@ public: void EncryptBytes( SvStream& rStrm, ::std::vector<sal_uInt8>& aBytes ); private: - void Init( const String& aPass, const sal_uInt8 nDocId[16], - const sal_uInt8 nSalt[16] ); + void Init( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aEncryptionData ); sal_uInt32 GetBlockPos( sal_Size nStrmPos ) const; sal_uInt16 GetOffsetInBlock( sal_Size nStrmPos ) const; private: ::msfilter::MSCodec_Std97 maCodec; /// Crypto algorithm implementation. - sal_uInt16 mnPassw[16]; /// Cached password data for copy construction. - sal_uInt8 mnDocId[16]; /// Cached document ID for copy construction. - sal_uInt8 mnSaltDigest[16]; + sal_uInt8 mpnDocId[16]; + sal_uInt8 mpnSalt[16]; + sal_uInt8 mpnSaltDigest[16]; const XclExpRoot& mrRoot; sal_Size mnOldPos; /// Last known stream position diff --git a/sc/source/filter/inc/xistream.hxx b/sc/source/filter/inc/xistream.hxx index de4e86bf0..894b6515e 100644 --- a/sc/source/filter/inc/xistream.hxx +++ b/sc/source/filter/inc/xistream.hxx @@ -64,10 +64,9 @@ public: /** Creates a (ref-counted) copy of this decrypter object. */ XclImpDecrypterRef Clone() const; - /** Implementation of the ::comphelper::IDocPasswordVerifier interface, - calls the new virtual function implVerify(). */ - virtual ::comphelper::DocPasswordVerifierResult - verifyPassword( const ::rtl::OUString& rPassword ); + /** Implementation of the ::comphelper::IDocPasswordVerifier interface */ + virtual ::comphelper::DocPasswordVerifierResult verifyPassword( const ::rtl::OUString& rPassword, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& o_rEncryptionData ); + virtual ::comphelper::DocPasswordVerifierResult verifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData ); /** Updates the decrypter on start of a new record or after seeking stream. */ void Update( SvStream& rStrm, sal_uInt16 nRecSize ); @@ -84,7 +83,10 @@ private: virtual XclImpDecrypter* OnClone() const = 0; /** Derived classes implement password verification and initialization of the decoder. */ - virtual bool OnVerify( const ::rtl::OUString& rPassword ) = 0; + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > + OnVerifyPassword( const ::rtl::OUString& rPassword ) = 0; + virtual bool OnVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData ) = 0; + /** Implementation of updating the decrypter. */ virtual void OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 nRecSize ) = 0; /** Implementation of the decryption. */ @@ -111,7 +113,9 @@ private: /** Implementation of cloning this object. */ virtual XclImpBiff5Decrypter* OnClone() const; /** Implements password verification and initialization of the decoder. */ - virtual bool OnVerify( const ::rtl::OUString& rPassword ); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > + OnVerifyPassword( const ::rtl::OUString& rPassword ); + virtual bool OnVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData ); /** Implementation of updating the decrypter. */ virtual void OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 nRecSize ); /** Implementation of the decryption. */ @@ -119,7 +123,7 @@ private: private: ::msfilter::MSCodec_XorXLS95 maCodec; /// Crypto algorithm implementation. - ::std::vector< sal_uInt8 > maPassword; + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > maEncryptionData; sal_uInt16 mnKey; sal_uInt16 mnHash; }; @@ -140,7 +144,9 @@ private: /** Implementation of cloning this object. */ virtual XclImpBiff8Decrypter* OnClone() const; /** Implements password verification and initialization of the decoder. */ - virtual bool OnVerify( const ::rtl::OUString& rPassword ); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > + OnVerifyPassword( const ::rtl::OUString& rPassword ); + virtual bool OnVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData ); /** Implementation of updating the decrypter. */ virtual void OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 nRecSize ); /** Implementation of the decryption. */ @@ -153,7 +159,7 @@ private: private: ::msfilter::MSCodec_Std97 maCodec; /// Crypto algorithm implementation. - ::std::vector< sal_uInt16 > maPassword; + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > maEncryptionData; ::std::vector< sal_uInt8 > maSalt; ::std::vector< sal_uInt8 > maVerifier; ::std::vector< sal_uInt8 > maVerifierHash; diff --git a/sc/source/filter/inc/xlroot.hxx b/sc/source/filter/inc/xlroot.hxx index 846a102de..3a273711e 100644 --- a/sc/source/filter/inc/xlroot.hxx +++ b/sc/source/filter/inc/xlroot.hxx @@ -28,6 +28,8 @@ #ifndef SC_XLROOT_HXX #define SC_XLROOT_HXX +#include <com/sun/star/beans/NamedValue.hpp> + #include <i18npool/lang.h> #include <sot/storage.hxx> #include "xlconst.hxx" @@ -196,7 +198,8 @@ public: /** Returns the default password used for stream encryption. */ inline const String& GetDefaultPassword() const { return mrData.maDefPassword; } /** Requests and verifies a password from the medium or the user. */ - String RequestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const; + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > + RequestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ) const; /** Returns the OLE2 root storage of the imported/exported file. @return Pointer to root storage or 0, if the file is a simple stream. */ diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx index cc0939990..65b73b4c1 100644 --- a/sc/source/filter/xcl97/xcl97rec.cxx +++ b/sc/source/filter/xcl97/xcl97rec.cxx @@ -1251,27 +1251,18 @@ void XclDelta::SaveXml( XclExpXmlStream& rStrm ) // ============================================================================ -XclExpFilePass::XclExpFilePass( const XclExpRoot& rRoot ) : +XclExpFileEncryption::XclExpFileEncryption( const XclExpRoot& rRoot ) : XclExpRecord(0x002F, 54), mrRoot(rRoot) { } -XclExpFilePass::~XclExpFilePass() +XclExpFileEncryption::~XclExpFileEncryption() { } -void XclExpFilePass::WriteBody( XclExpStream& rStrm ) +void XclExpFileEncryption::WriteBody( XclExpStream& rStrm ) { - static const sal_uInt8 nDocId[] = { - 0x17, 0xf7, 0x01, 0x08, 0xea, 0xad, 0x30, 0x5c, - 0x1a, 0x95, 0xa5, 0x75, 0xd6, 0x79, 0xcd, 0x8d }; - - - static const sal_uInt8 nSalt[] = { - 0xa4, 0x5b, 0xf7, 0xe9, 0x9f, 0x55, 0x21, 0xc5, - 0xc5, 0x56, 0xa8, 0x0d, 0x39, 0x05, 0x3a, 0xb4 }; - // 0x0000 - neither standard nor strong encryption // 0x0001 - standard or strong encryption rStrm << static_cast<sal_uInt16>(0x0001); @@ -1281,13 +1272,17 @@ void XclExpFilePass::WriteBody( XclExpStream& rStrm ) sal_uInt16 nStdEnc = 0x0001; rStrm << nStdEnc << nStdEnc; - sal_uInt8 nSaltHash[16]; - XclExpEncrypterRef xEnc( new XclExpBiff8Encrypter(mrRoot, nDocId, nSalt) ); - xEnc->GetSaltDigest(nSaltHash); - - rStrm.Write(nDocId, 16); - rStrm.Write(nSalt, 16); - rStrm.Write(nSaltHash, 16); + sal_uInt8 pnDocId[16]; + sal_uInt8 pnSalt[16]; + sal_uInt8 pnSaltHash[16]; + XclExpEncrypterRef xEnc( new XclExpBiff8Encrypter(mrRoot) ); + xEnc->GetDocId(pnDocId); + xEnc->GetSalt(pnSalt); + xEnc->GetSaltDigest(pnSaltHash); + + rStrm.Write(pnDocId, 16); + rStrm.Write(pnSalt, 16); + rStrm.Write(pnSaltHash, 16); rStrm.SetEncrypter(xEnc); } |