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 | 6bcbe6006dcf6853cd315c3167b2e5b6efa5b6f9 (patch) | |
tree | d49b53807dec683bc9a72ab0a0171e2f1964fe05 | |
parent | 511730d4cb5a248ccbfc48811a4717a15038fe26 (diff) | |
parent | 05f5182e2e42c9bdd2efa8ddd9997290f2d82e8f (diff) |
CWS-TOOLING: integrate CWS pl08
-rw-r--r-- | sw/source/filter/ww8/wrtww8.cxx | 92 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtww8.hxx | 7 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8par.cxx | 161 | ||||
-rw-r--r-- | sw/source/ui/app/docsh.cxx | 18 |
4 files changed, 176 insertions, 102 deletions
diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx index 0b1693e919f1..5c82f67a32f1 100644 --- a/sw/source/filter/ww8/wrtww8.cxx +++ b/sw/source/filter/ww8/wrtww8.cxx @@ -112,6 +112,8 @@ #include "dbgoutsw.hxx" #include <sfx2/docfile.hxx> +#include <sfx2/request.hxx> +#include <sfx2/frame.hxx> #include <svl/stritem.hxx> #include <unotools/tempfile.hxx> #include <filter/msfilter/mscodec.hxx> @@ -2995,20 +2997,54 @@ void MSWordExportBase::ExportDocument( bool bWriteAll ) pDoc->SetRedlineMode( (RedlineMode_t)(mnRedlineMode) ); } -String SwWW8Writer::GetPassword() +bool SwWW8Writer::InitStd97CodecUpdateMedium( ::msfilter::MSCodec_Std97& rCodec ) { - String sUniPassword; + uno::Sequence< beans::NamedValue > aEncryptionData; + if ( mpMedium ) { - SfxItemSet* pSet = mpMedium->GetItemSet(); + SFX_ITEMSET_ARG( mpMedium->GetItemSet(), pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False ); + if ( pEncryptionDataItem && ( pEncryptionDataItem->GetValue() >>= aEncryptionData ) && !rCodec.InitCodec( aEncryptionData ) ) + { + OSL_ENSURE( false, "Unexpected EncryptionData!" ); + aEncryptionData.realloc( 0 ); + } + + if ( !aEncryptionData.getLength() ) + { + // try to generate the encryption data based on password + SFX_ITEMSET_ARG( mpMedium->GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False ); + if ( pPasswordItem && pPasswordItem->GetValue().Len() && pPasswordItem->GetValue().Len() <= 15 ) + { + // Generate random number with a seed of time as salt. + TimeValue aTime; + osl_getSystemTime( &aTime ); + rtlRandomPool aRandomPool = rtl_random_createPool (); + rtl_random_addBytes ( aRandomPool, &aTime, 8 ); - const SfxPoolItem* pPasswordItem = NULL; - if ( pSet && SFX_ITEM_SET == pSet->GetItemState( SID_PASSWORD, sal_True, &pPasswordItem ) ) - if( pPasswordItem != NULL ) - sUniPassword = ( (const SfxStringItem*)pPasswordItem )->GetValue(); + sal_uInt8 pDocId[ 16 ]; + rtl_random_getBytes( aRandomPool, pDocId, 16 ); + + rtl_random_destroyPool( aRandomPool ); + + sal_Unicode aPassword[16]; + memset( aPassword, 0, sizeof( aPassword ) ); + for ( xub_StrLen nChar = 0; nChar < pPasswordItem->GetValue().Len(); ++nChar ) + aPassword[nChar] = pPasswordItem->GetValue().GetChar(nChar); + + rCodec.InitKey( aPassword, pDocId ); + aEncryptionData = rCodec.GetEncryptionData(); + + mpMedium->GetItemSet()->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) ); + } + } + + if ( aEncryptionData.getLength() ) + mpMedium->GetItemSet()->ClearItem( SID_PASSWORD ); } - return sUniPassword; + // nonempty encryption data means hier that the codec was successfuly initialized + return ( aEncryptionData.getLength() != 0 ); } void WW8Export::ExportDocument_Impl() @@ -3042,8 +3078,6 @@ void WW8Export::ExportDocument_Impl() Strm().SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); - String sUniPassword( GetWriter().GetPassword() ); - utl::TempFile aTempMain; aTempMain.EnableKillingFile(); utl::TempFile aTempTable; @@ -3051,13 +3085,10 @@ void WW8Export::ExportDocument_Impl() utl::TempFile aTempData; aTempData.EnableKillingFile(); - bool bEncrypt = false; - - xub_StrLen nLen = sUniPassword.Len(); - if ( nLen > 0 && nLen <= 15) // Password has been set + msfilter::MSCodec_Std97 aCtx; + bool bEncrypt = m_pWriter ? m_pWriter->InitStd97CodecUpdateMedium( aCtx ) : false; + if ( bEncrypt ) { - bEncrypt =true; - GetWriter().SetStream( aTempMain.GetStream( STREAM_READWRITE | STREAM_SHARE_DENYWRITE ) ); @@ -3121,24 +3152,6 @@ void WW8Export::ExportDocument_Impl() if ( bEncrypt ) { - // Generate random number with a seed of time as salt. - TimeValue aTime; - osl_getSystemTime( &aTime ); - rtlRandomPool aRandomPool = rtl_random_createPool (); - rtl_random_addBytes ( aRandomPool, &aTime, 8 ); - - sal_uInt8 aDocId[ 16 ] = {0}; - rtl_random_getBytes( aRandomPool, aDocId, 16 ); - - rtl_random_destroyPool( aRandomPool ); - - sal_Unicode aPassword[16] = {0}; - for (xub_StrLen nChar = 0; nChar < nLen; ++nChar ) - aPassword[nChar] = sUniPassword.GetChar(nChar); - - msfilter::MSCodec_Std97 aCtx; - aCtx.InitKey(aPassword, aDocId); - SvStream *pStrmTemp, *pTableStrmTemp, *pDataStrmTemp; pStrmTemp = &xWwStrm; pTableStrmTemp = &xTableStrm; @@ -3155,11 +3168,14 @@ void WW8Export::ExportDocument_Impl() sal_uInt32 nEncType = 0x10001; *pTableStrmTemp << nEncType; - sal_uInt8 pSaltData[16] = {0}; - sal_uInt8 pSaltDigest[16] = {0}; - aCtx.GetEncryptKey( aDocId, pSaltData, pSaltDigest ); + sal_uInt8 pDocId[16]; + aCtx.GetDocId( pDocId ); + + sal_uInt8 pSaltData[16]; + sal_uInt8 pSaltDigest[16]; + aCtx.GetEncryptKey( pDocId, pSaltData, pSaltDigest ); - pTableStrmTemp->Write( aDocId, 16 ); + pTableStrmTemp->Write( pDocId, 16 ); pTableStrmTemp->Write( pSaltData, 16 ); pTableStrmTemp->Write( pSaltDigest, 16 ); diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx index 4ba3bf3c1089..a4ab2c69aaa8 100644 --- a/sw/source/filter/ww8/wrtww8.hxx +++ b/sw/source/filter/ww8/wrtww8.hxx @@ -53,6 +53,11 @@ #include <expfld.hxx> // einige Forward Deklarationen +namespace msfilter +{ + class MSCodec_Std97; +} + class SwAttrIter; class AttributeOutputBase; class DocxAttributeOutput; @@ -881,7 +886,7 @@ public: static void WriteString_xstz(SvStream& rStrm, const String& rStr, bool bAddZero); - String GetPassword(); + bool InitStd97CodecUpdateMedium( ::msfilter::MSCodec_Std97& rCodec ); using StgWriter::Write; virtual ULONG Write( SwPaM&, SfxMedium&, const String* = 0 ); diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx index cd11631a0181..b5ceebcb1ba6 100644 --- a/sw/source/filter/ww8/ww8par.cxx +++ b/sw/source/filter/ww8/ww8par.cxx @@ -29,16 +29,20 @@ #include "precompiled_sw.hxx" /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */ -#include <hash_set> #include <com/sun/star/embed/ElementModes.hpp> #include <com/sun/star/embed/XStorage.hpp> + +#include <hash_set> #include <unotools/ucbstreamhelper.hxx> #include <tools/solar.h> #include <rtl/tencinfo.h> +#include <rtl/random.h> #include <sot/storage.hxx> #include <sfx2/docinf.hxx> #include <sfx2/docfile.hxx> +#include <sfx2/request.hxx> +#include <sfx2/frame.hxx> #include <tools/urlobj.hxx> #include <unotools/tempfile.hxx> #include <svtools/sfxecode.hxx> @@ -107,6 +111,7 @@ #include <com/sun/star/i18n/ForbiddenCharacters.hpp> #include <comphelper/extract.hxx> +#include <comphelper/sequenceashashmap.hxx> #include <fltini.hxx> #include <algorithm> @@ -4344,6 +4349,90 @@ namespace return aPassw; } + uno::Sequence< beans::NamedValue > InitXorWord95Codec( ::msfilter::MSCodec_XorWord95& rCodec, SfxMedium& rMedium, WW8Fib* pWwFib ) + { + uno::Sequence< beans::NamedValue > aEncryptionData; + SFX_ITEMSET_ARG( rMedium.GetItemSet(), pEncryptionData, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False ); + if ( pEncryptionData && ( pEncryptionData->GetValue() >>= aEncryptionData ) && !rCodec.InitCodec( aEncryptionData ) ) + aEncryptionData.realloc( 0 ); + + if ( !aEncryptionData.getLength() ) + { + String sUniPassword = QueryPasswordForMedium( rMedium ); + + ByteString sPassword(sUniPassword, WW8Fib::GetFIBCharset( pWwFib->chseTables ) ); + + xub_StrLen nLen = sPassword.Len(); + if( nLen <= 15 ) + { + sal_uInt8 pPassword[16]; + memset( pPassword, 0, sizeof( pPassword ) ); + + for (xub_StrLen nChar = 0; nChar < sPassword.Len(); ++nChar ) + pPassword[nChar] = sPassword.GetChar(nChar); + + rCodec.InitKey( pPassword ); + aEncryptionData = rCodec.GetEncryptionData(); + + // the export supports RC4 algorithm only, so we have to generate the related EncryptionData as well, + // so that Save can export the document without asking for a password; + // as result there will be EncryptionData for both algorithms in the MediaDescriptor + ::msfilter::MSCodec_Std97 aCodec97; + + // Generate random number with a seed of time as salt. + TimeValue aTime; + osl_getSystemTime( &aTime ); + rtlRandomPool aRandomPool = rtl_random_createPool(); + rtl_random_addBytes ( aRandomPool, &aTime, 8 ); + + sal_uInt8 pDocId[ 16 ]; + rtl_random_getBytes( aRandomPool, pDocId, 16 ); + + rtl_random_destroyPool( aRandomPool ); + + sal_uInt16 pStd97Pass[16]; + memset( pStd97Pass, 0, sizeof( pStd97Pass ) ); + for (xub_StrLen nChar = 0; nChar < nLen; ++nChar ) + pStd97Pass[nChar] = sUniPassword.GetChar(nChar); + + aCodec97.InitKey( pStd97Pass, pDocId ); + + // merge the EncryptionData, there should be no conflicts + ::comphelper::SequenceAsHashMap aEncryptionHash( aEncryptionData ); + aEncryptionHash.update( ::comphelper::SequenceAsHashMap( aCodec97.GetEncryptionData() ) ); + aEncryptionHash >> aEncryptionData; + } + } + + return aEncryptionData; + } + + uno::Sequence< beans::NamedValue > InitStd97Codec( ::msfilter::MSCodec_Std97& rCodec, sal_uInt8 pDocId[16], SfxMedium& rMedium ) + { + uno::Sequence< beans::NamedValue > aEncryptionData; + SFX_ITEMSET_ARG( rMedium.GetItemSet(), pEncryptionData, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False ); + if ( pEncryptionData && ( pEncryptionData->GetValue() >>= aEncryptionData ) && !rCodec.InitCodec( aEncryptionData ) ) + aEncryptionData.realloc( 0 ); + + if ( !aEncryptionData.getLength() ) + { + String sUniPassword = QueryPasswordForMedium( rMedium ); + + xub_StrLen nLen = sUniPassword.Len(); + if ( nLen <= 15 ) + { + sal_Unicode pPassword[16]; + memset( pPassword, 0, sizeof( pPassword ) ); + for (xub_StrLen nChar = 0; nChar < nLen; ++nChar ) + pPassword[nChar] = sUniPassword.GetChar(nChar); + + rCodec.InitKey( pPassword, pDocId ); + aEncryptionData = rCodec.GetEncryptionData(); + } + } + + return aEncryptionData; + } } ULONG SwWW8ImplReader::LoadThroughDecryption(SwPaM& rPaM ,WW8Glossary *pGloss) @@ -4397,31 +4486,22 @@ ULONG SwWW8ImplReader::LoadThroughDecryption(SwPaM& rPaM ,WW8Glossary *pGloss) if (bDecrypt) { nErrRet = ERRCODE_SVX_WRONGPASS; - switch (eAlgo) + SfxMedium* pMedium = mpDocShell->GetMedium(); + + if ( pMedium ) { - default: - nErrRet = ERRCODE_SVX_READ_FILTER_CRYPT; - break; - case XOR: + switch (eAlgo) { - String sUniPassword = - QueryPasswordForMedium(*(mpDocShell->GetMedium())); - - ByteString sPassword(sUniPassword, - WW8Fib::GetFIBCharset(pWwFib->chseTables)); - - xub_StrLen nLen = sPassword.Len(); - // DR: do not cut a wrong (too long) password - if( nLen <= 15 ) + default: + nErrRet = ERRCODE_SVX_READ_FILTER_CRYPT; + break; + case XOR: { - sal_uInt8 aPassword[16] = {0}; - - for (xub_StrLen nChar = 0; nChar < sPassword.Len(); ++nChar ) - aPassword[nChar] = sPassword.GetChar(nChar); - msfilter::MSCodec_XorWord95 aCtx; - aCtx.InitKey(aPassword); - if (aCtx.VerifyKey(pWwFib->nKey, pWwFib->nHash)) + uno::Sequence< beans::NamedValue > aEncryptionData = InitXorWord95Codec( aCtx, *pMedium, pWwFib ); + + // if initialization has failed the EncryptionData should be empty + if ( aEncryptionData.getLength() && aCtx.VerifyKey( pWwFib->nKey, pWwFib->nHash ) ) { nErrRet = 0; pTempMain = MakeTemp(aDecryptMain); @@ -4453,22 +4533,15 @@ ULONG SwWW8ImplReader::LoadThroughDecryption(SwPaM& rPaM ,WW8Glossary *pGloss) DecryptXOR(aCtx, *pDataStream, aDecryptData); pDataStream = &aDecryptData; } + + pMedium->GetItemSet()->ClearItem( SID_PASSWORD ); + pMedium->GetItemSet()->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) ); } } - } - break; - case RC4: - { - String sUniPassword = - QueryPasswordForMedium(*(mpDocShell->GetMedium())); - - xub_StrLen nLen = sUniPassword.Len(); - // DR: do not cut a wrong (too long) password - if (nLen <= 15) + break; + case RC4: { - sal_Unicode aPassword[16] = {0}; - for (xub_StrLen nChar = 0; nChar < nLen; ++nChar ) - aPassword[nChar] = sUniPassword.GetChar(nChar); + msfilter::MSCodec_Std97 aCtx; sal_uInt8 aDocId[ 16 ]; pTableStream->Read(aDocId, 16); @@ -4477,9 +4550,9 @@ ULONG SwWW8ImplReader::LoadThroughDecryption(SwPaM& rPaM ,WW8Glossary *pGloss) sal_uInt8 aSaltHash[ 16 ]; pTableStream->Read(aSaltHash, 16); - msfilter::MSCodec_Std97 aCtx; - aCtx.InitKey(aPassword, aDocId); - if (aCtx.VerifyKey(aSaltData, aSaltHash)) + // if initialization has failed the EncryptionData should be empty + uno::Sequence< beans::NamedValue > aEncryptionData = InitStd97Codec( aCtx, aDocId, *pMedium ); + if ( aEncryptionData.getLength() && aCtx.VerifyKey( aSaltData, aSaltHash ) ) { nErrRet = 0; @@ -4498,17 +4571,13 @@ ULONG SwWW8ImplReader::LoadThroughDecryption(SwPaM& rPaM ,WW8Glossary *pGloss) DecryptRC4(aCtx, *pDataStream, aDecryptData); pDataStream = &aDecryptData; } - SfxMedium* pMedium = mpDocShell->GetMedium(); - if ( pMedium ) - { - SfxItemSet* pSet = pMedium->GetItemSet(); - if ( pSet ) - pSet->Put( SfxStringItem(SID_PASSWORD, sUniPassword) ); - } + + pMedium->GetItemSet()->ClearItem( SID_PASSWORD ); + pMedium->GetItemSet()->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) ); } } + break; } - break; } if (nErrRet == 0) diff --git a/sw/source/ui/app/docsh.cxx b/sw/source/ui/app/docsh.cxx index 9508c4c17864..c839b5c03f52 100644 --- a/sw/source/ui/app/docsh.cxx +++ b/sw/source/ui/app/docsh.cxx @@ -209,23 +209,7 @@ Reader* SwDocShell::StartConvertFrom(SfxMedium& rMedium, SwReader** ppRdr, return 0; } } - if(rMedium.IsStorage()) - { - //SvStorageRef aStor( rMedium.GetStorage() ); - const SfxItemSet* pSet = rMedium.GetItemSet(); - const SfxPoolItem *pItem; - if(pSet && SFX_ITEM_SET == pSet->GetItemState(SID_PASSWORD, TRUE, &pItem)) - { - DBG_ASSERT(pItem->IsA( TYPE(SfxStringItem) ), "Fehler Parametertype"); - comphelper::OStorageHelper::SetCommonStoragePassword( rMedium.GetStorage(), ((const SfxStringItem *)pItem)->GetValue() ); - } - // Fuer's Dokument-Einfuegen noch die FF-Version, wenn's der - // eigene Filter ist. - ASSERT( /*pRead != ReadSw3 || */pRead != ReadXML || pFlt->GetVersion(), - "Am Filter ist keine FF-Version gesetzt" ); - //if( (pRead == ReadSw3 || pRead == ReadXML) && pFlt->GetVersion() ) - // aStor->SetVersion( (long)pFlt->GetVersion() ); - } + // #i30171# set the UpdateDocMode at the SwDocShell SFX_ITEMSET_ARG( rMedium.GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False); nUpdateDocMode = pUpdateDocItem ? pUpdateDocItem->GetValue() : document::UpdateDocMode::NO_UPDATE; |