Hello Kohei, all, this is a possible patch for the problem that the button at File->Properties is always disabled even if you have a password protected file.
The problem was that SID_PASSWORD, which saved the plain text password, is no longer used but we use SID_ENCRYPTIONDATA which saves the hash. I changed the code for this button so that it shares the implementation with the file save dialog. I haven't found a nice place for the method RequestPassword so I have decided to leave it in filedlghelper.[ch]xx . I'm open for any suggestions where this method should be located. This patch applies to 3.4, I haven't tested yet with master since master has several code changes in the password related code. Regards, Markus
From e2310e98ce47af28854296bda31eb4f3d76d2474 Mon Sep 17 00:00:00 2001 From: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Sun, 24 Jul 2011 19:58:27 +0200 Subject: [PATCH] fix for fdo#37628: change password button is always disabled --- sfx2/inc/sfx2/filedlghelper.hxx | 6 +- sfx2/source/dialog/dinfdlg.cxx | 24 ++++--- sfx2/source/dialog/filedlghelper.cxx | 134 ++++++++++++++++++---------------- 3 files changed, 90 insertions(+), 74 deletions(-) diff --git a/sfx2/inc/sfx2/filedlghelper.hxx b/sfx2/inc/sfx2/filedlghelper.hxx index 7155006..c18c16c 100644 --- a/sfx2/inc/sfx2/filedlghelper.hxx +++ b/sfx2/inc/sfx2/filedlghelper.hxx @@ -43,7 +43,7 @@ #include <vcl/graph.hxx> #include <sfx2/sfxdefs.hxx> #include <sfx2/sfxuno.hxx> - +#include <sfx2/docfilt.hxx> //----------------------------------------------------------------------------- namespace com @@ -309,8 +309,12 @@ ErrCode FileOpenDialog_Impl( sal_Int64 nFlags, sal_Int16 nDialog = SFX2_IMPL_DIALOG_CONFIG, const String& rStandardDir = String::CreateFromAscii( "" ), const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList = ::com::sun::star::uno::Sequence< ::rtl::OUString >()); + + +ErrCode RequestPassword(const SfxFilter* pCurrentFilter, rtl::OUString& aURL, SfxItemSet* pSet); } + //----------------------------------------------------------------------------- #endif diff --git a/sfx2/source/dialog/dinfdlg.cxx b/sfx2/source/dialog/dinfdlg.cxx index 7770ded..621790c 100644 --- a/sfx2/source/dialog/dinfdlg.cxx +++ b/sfx2/source/dialog/dinfdlg.cxx @@ -69,6 +69,7 @@ #include <sfx2/viewfrm.hxx> #include <sfx2/request.hxx> #include <sfx2/passwd.hxx> +#include <sfx2/filedlghelper.hxx> #include "helper.hxx" #include <sfx2/objsh.hxx> #include <sfx2/docfile.hxx> @@ -925,14 +926,12 @@ IMPL_LINK( SfxDocumentPage, ChangePassHdl, PushButton*, EMPTYARG ) if (!pMedSet) break; - ::std::auto_ptr<SfxPasswordDialog> pDlg(new SfxPasswordDialog(this)); - pDlg->SetMinLen(1); - pDlg->ShowExtras(SHOWEXTRAS_CONFIRM); - if (pDlg->Execute() != RET_OK) + const SfxFilter* pFilter = pShell->GetMedium()->GetFilter(); + if (!pFilter) break; - String aNewPass = pDlg->GetPassword(); - pMedSet->Put( SfxStringItem(SID_PASSWORD, aNewPass) ); + rtl::OUString aDocName; + sfx2::RequestPassword(pFilter, aDocName, pMedSet); pShell->SetModified(true); } while (false); @@ -987,14 +986,19 @@ void SfxDocumentPage::ImplCheckPasswordState() break; const SfxPoolItem* pItem; - if (!pMedSet->GetItemState(SID_PASSWORD, true, &pItem)) + if (!pMedSet->GetItemState(SID_ENCRYPTIONDATA, true, &pItem)) + break; + + SFX_ITEMSET_ARG( pMedSet, pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False); + uno::Sequence< beans::NamedValue > aEncryptionData; + if (pEncryptionDataItem) + pEncryptionDataItem->GetValue() >>= aEncryptionData; + else break; - const SfxStringItem* pStrItem = dynamic_cast<const SfxStringItem*>(pItem); - if (!pStrItem) + if (!aEncryptionData.getLength()) break; - String aPass = pStrItem->GetValue(); aChangePassBtn.Enable(); return; } diff --git a/sfx2/source/dialog/filedlghelper.cxx b/sfx2/source/dialog/filedlghelper.cxx index 610bbf2..e2f35e8 100644 --- a/sfx2/source/dialog/filedlghelper.cxx +++ b/sfx2/source/dialog/filedlghelper.cxx @@ -1557,69 +1557,10 @@ ErrCode FileDialogHelper_Impl::execute( SvStringsDtor*& rpURLList, if ( ( aValue >>= bPassWord ) && bPassWord ) { // ask for a password - uno::Reference < ::com::sun::star::task::XInteractionHandler > xInteractionHandler( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.uui.UUIInteractionHandler"))), UNO_QUERY ); - - if( xInteractionHandler.is() ) - { - // TODO: need a save way to distinguish MS filters from other filters - // for now MS-filters are the only alien filters that support encryption - sal_Bool bMSType = !pCurrentFilter->IsOwnFormat(); - ::comphelper::DocPasswordRequestType eType = bMSType ? - ::comphelper::DocPasswordRequestType_MS : - ::comphelper::DocPasswordRequestType_STANDARD; - - ::rtl::Reference< ::comphelper::DocPasswordRequest > pPasswordRequest( new ::comphelper::DocPasswordRequest( eType, ::com::sun::star::task::PasswordRequestMode_PASSWORD_CREATE, *(rpURLList->GetObject(0)), ( pCurrentFilter->GetFilterFlags() & SFX_FILTER_PASSWORDTOMODIFY ) != 0 ) ); - - uno::Reference< com::sun::star::task::XInteractionRequest > rRequest( pPasswordRequest.get() ); - xInteractionHandler->handle( rRequest ); - if ( pPasswordRequest->isPassword() ) - { - if ( pPasswordRequest->getPassword().getLength() ) - { - // TODO/LATER: The filters should show the password dialog themself in future - if ( bMSType ) - { - // all the current MS-filters use MSCodec_Std97 implementation - uno::Sequence< sal_Int8 > aUniqueID = ::comphelper::DocPasswordHelper::GenerateRandomByteSequence( 16 ); - uno::Sequence< sal_Int8 > aEncryptionKey = ::comphelper::DocPasswordHelper::GenerateStd97Key( pPasswordRequest->getPassword(), aUniqueID ); - - if ( aEncryptionKey.getLength() ) - { - ::comphelper::SequenceAsHashMap aHashData; - aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97EncryptionKey" ) ) ] <<= aEncryptionKey; - aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97UniqueID" ) ) ] <<= aUniqueID; - - rpSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aHashData.getAsConstNamedValueList() ) ) ); - } - else - return ERRCODE_IO_NOTSUPPORTED; - } - else - { - rpSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( ::comphelper::OStorageHelper::CreatePackageEncryptionData( pPasswordRequest->getPassword() ) ) ) ); - } - } - - if ( pPasswordRequest->getRecommendReadOnly() ) - rpSet->Put( SfxBoolItem( SID_RECOMMENDREADONLY, sal_True ) ); - - if ( bMSType ) - { - // the empty password has 0 as Hash - sal_Int32 nHash = SfxMedium::CreatePasswordToModifyHash( pPasswordRequest->getPasswordToModify(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextDocument" ) ).equals( pCurrentFilter->GetServiceName() ) ); - if ( nHash ) - rpSet->Put( SfxUnoAnyItem( SID_MODIFYPASSWORDINFO, uno::makeAny( nHash ) ) ); - } - else - { - uno::Sequence< beans::PropertyValue > aModifyPasswordInfo = ::comphelper::DocPasswordHelper::GenerateNewModifyPasswordInfo( pPasswordRequest->getPasswordToModify() ); - if ( aModifyPasswordInfo.getLength() ) - rpSet->Put( SfxUnoAnyItem( SID_MODIFYPASSWORDINFO, uno::makeAny( aModifyPasswordInfo ) ) ); - } - } - else - return ERRCODE_ABORT; - } + rtl::OUString aDocName(*(rpURLList->GetObject(0))); + ErrCode errCode = RequestPassword(pCurrentFilter, aDocName, rpSet); + if (errCode != ERRCODE_NONE) + return errCode; } } catch( IllegalArgumentException ){} @@ -2778,6 +2719,73 @@ ErrCode FileOpenDialog_Impl( sal_Int64 nFlags, return nRet; } +ErrCode RequestPassword(const SfxFilter* pCurrentFilter, rtl::OUString& aURL, SfxItemSet* pSet) +{ + uno::Reference < ::com::sun::star::task::XInteractionHandler > xInteractionHandler( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.uui.UUIInteractionHandler"))), UNO_QUERY ); + + if( xInteractionHandler.is() ) + { + // TODO: need a save way to distinguish MS filters from other filters + // for now MS-filters are the only alien filters that support encryption + bool bMSType = !pCurrentFilter->IsOwnFormat(); + ::comphelper::DocPasswordRequestType eType = bMSType ? + ::comphelper::DocPasswordRequestType_MS : + ::comphelper::DocPasswordRequestType_STANDARD; + + ::rtl::Reference< ::comphelper::DocPasswordRequest > pPasswordRequest( new ::comphelper::DocPasswordRequest( eType, ::com::sun::star::task::PasswordRequestMode_PASSWORD_CREATE, aURL, ( pCurrentFilter->GetFilterFlags() & SFX_FILTER_PASSWORDTOMODIFY ) != 0 ) ); + + uno::Reference< com::sun::star::task::XInteractionRequest > rRequest( pPasswordRequest.get() ); + xInteractionHandler->handle( rRequest ); + if ( pPasswordRequest->isPassword() ) + { + if ( pPasswordRequest->getPassword().getLength() ) + { + // TODO/LATER: The filters should show the password dialog themself in future + if ( bMSType ) + { + // all the current MS-filters use MSCodec_Std97 implementation + uno::Sequence< sal_Int8 > aUniqueID = ::comphelper::DocPasswordHelper::GenerateRandomByteSequence( 16 ); + uno::Sequence< sal_Int8 > aEncryptionKey = ::comphelper::DocPasswordHelper::GenerateStd97Key( pPasswordRequest->getPassword(), aUniqueID ); + + if ( aEncryptionKey.getLength() ) + { + ::comphelper::SequenceAsHashMap aHashData; + aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97EncryptionKey" ) ) ] <<= aEncryptionKey; + aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97UniqueID" ) ) ] <<= aUniqueID; + + pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aHashData.getAsConstNamedValueList() ) ) ); + } + else + return ERRCODE_IO_NOTSUPPORTED; + } + else + { + pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( ::comphelper::OStorageHelper::CreatePackageEncryptionData( pPasswordRequest->getPassword() ) ) ) ); + } + } + + if ( pPasswordRequest->getRecommendReadOnly() ) + pSet->Put( SfxBoolItem( SID_RECOMMENDREADONLY, sal_True ) ); + + if ( bMSType ) + { + // the empty password has 0 as Hash + sal_Int32 nHash = SfxMedium::CreatePasswordToModifyHash( pPasswordRequest->getPasswordToModify(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextDocument" ) ).equals( pCurrentFilter->GetServiceName() ) ); + if ( nHash ) + pSet->Put( SfxUnoAnyItem( SID_MODIFYPASSWORDINFO, uno::makeAny( nHash ) ) ); + } + else + { + uno::Sequence< beans::PropertyValue > aModifyPasswordInfo = ::comphelper::DocPasswordHelper::GenerateNewModifyPasswordInfo( pPasswordRequest->getPasswordToModify() ); + if ( aModifyPasswordInfo.getLength() ) + pSet->Put( SfxUnoAnyItem( SID_MODIFYPASSWORDINFO, uno::makeAny( aModifyPasswordInfo ) ) ); + } + } + else + return ERRCODE_ABORT; + } + return ERRCODE_NONE; +} // ------------------------------------------------------------------------ String EncodeSpaces_Impl( const String& rSource ) -- 1.7.3.4
_______________________________________________ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice