sfx2: warn user before saving doc with scripting signature encrypted

The pre-ODF 1.5 encryption necessarily destroys macro signatures, but
the user would learn this only when re-loading the encrypted document.

Change-Id: Ic8a0190205412f484f47a4b8d864b280eea0d23c
(cherry picked from commit 558c6a83c210a4d9d7a699616c6f254fb23d7cf4)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184822
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
This commit is contained in:
Michael Stahl
2025-04-30 16:40:34 +02:00
parent 6fee94e76d
commit 2753c21abe
9 changed files with 75 additions and 19 deletions
+3 -1
View File
@@ -47,6 +47,7 @@ namespace com::sun::star::uno { template <typename > class Reference; }
namespace com::sun::star::uno { class XComponentContext; }
namespace weld { class Window; }
enum class SignatureState;
class Graphic;
class SfxFilter;
class SfxItemSet;
@@ -283,7 +284,8 @@ public:
OUString& rFilter,
const OUString& rDirPath );
ErrCode Execute( std::optional<SfxAllItemSet>& rpSet,
OUString& rFilter );
OUString& rFilter,
SignatureState nScriptingSignatureState);
};
#define SFX2_IMPL_DIALOG_CONFIG 0
+1
View File
@@ -146,6 +146,7 @@
#define STR_SECURITY_WARNING_NO_HYPERLINKS NC_("STR_SECURITY_WARNING_NO_HYPERLINKS", "For security reasons, the hyperlink cannot be executed.\nThe stated address will not be opened.")
#define RID_SECURITY_WARNING_TITLE NC_("RID_SECURITY_WARNING_TITLE", "Security Warning")
#define RID_SVXSTR_XMLSEC_QUERY_LOSINGSIGNATURE NC_("RID_SVXSTR_XMLSEC_QUERY_LOSINGSIGNATURE", "Saving will remove all existing signatures.\nDo you want to continue saving the document?")
#define RID_SVXSTR_XMLSEC_QUERY_LOSINGSCRIPTINGSIGNATURE NC_("RID_SVXSTR_XMLSEC_QUERY_LOSINGSCRIPTINGSIGNATURE", "Saving with password will remove all existing scripting signatures, and (depending on macro security settings) macros in the document may no longer be runnable.\nDo you want to continue saving the document with password?")
#define RID_SVXSTR_XMLSEC_QUERY_SAVEBEFORESIGN NC_("RID_SVXSTR_XMLSEC_QUERY_SAVEBEFORESIGN", "The document has to be saved before it can be signed.\nDo you want to save the document?")
#define STR_QUERY_CANCELCHECKOUT NC_("STR_QUERY_CANCELCHECKOUT", "This will discard all changes on the server since check-out.\nDo you want to proceed?")
#define STR_QUERY_REMEMBERSIGNATURE NC_("STR_QUERY_REMEMBERSIGNATURE", "Do you want to remember that signature for each save?")
+10 -1
View File
@@ -38,6 +38,8 @@
#include <svtools/dialogclosedlistener.hxx>
#include <unotools/saveopt.hxx>
#include <tools/urlobj.hxx>
@@ -46,6 +48,10 @@ namespace com::sun::star::document { class XDocumentProperties; }
namespace weld { class Window; }
class ModelData_Impl;
namespace sfx2 {
bool UseODFWholesomeEncryption(SvtSaveOptions::ODFSaneDefaultVersion const nODFVersion);
} // namespace sfx2
class SfxStoringHelper
{
friend class ModelData_Impl;
@@ -67,6 +73,7 @@ private:
bool m_bDialogUsed;
bool m_bSetStandardName;
sal_Int16 m_nStoreMode;
SignatureState m_nScriptingSignatureState{SignatureState::UNKNOWN};
static bool FinishGUIStoreModel(::comphelper::SequenceAsHashMap::const_iterator& aFileNameIter,
ModelData_Impl& aModelData, bool bRemote, sal_Int16 nStoreMode,
@@ -74,7 +81,8 @@ private:
bool bSetStandardName, bool bPreselectPassword, bool bDialogUsed,
std::u16string_view aFilterFromMediaDescr, std::u16string_view aOldFilterName,
css::uno::Sequence< css::beans::PropertyValue >& aArgsSequence,
OUString aFilterName);
OUString aFilterName,
SignatureState nScriptingSignatureState);
void CallFinishGUIStoreModel();
@@ -87,6 +95,7 @@ public:
css::uno::Sequence< css::beans::PropertyValue >& aArgsSequence,
bool bPreselectPassword,
SignatureState nDocumentSignatureState,
SignatureState nScriptingSignatureState,
bool bIsAsync );
static bool CheckFilterOptionsAppearance(
+33 -4
View File
@@ -87,6 +87,7 @@
#include <sfx2/objsh.hxx>
#include <sfx2/sfxresid.hxx>
#include <sfx2/sfxsids.hrc>
#include <guisaveas.hxx>
#include "filtergrouping.hxx"
#include "filedlgimpl.hxx"
#include <fpicker/fpsofficeResMgr.hxx>
@@ -1453,7 +1454,8 @@ void FileDialogHelper_Impl::implGetAndCacheFiles(const uno::Reference< XInterfac
ErrCode FileDialogHelper_Impl::execute( std::vector<OUString>& rpURLList,
std::optional<SfxAllItemSet>& rpSet,
OUString& rFilter )
OUString& rFilter,
SignatureState const nScriptingSignatureState)
{
// rFilter is a pure output parameter, it shouldn't be used for anything else
// changing this would surely break code
@@ -1586,6 +1588,32 @@ ErrCode FileDialogHelper_Impl::execute( std::vector<OUString>& rpURLList,
Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0 );
bool bPassWord = false;
if ( ( aValue >>= bPassWord ) && bPassWord )
{
SvtSaveOptions::ODFSaneDefaultVersion nVersion{
SvtSaveOptions::ODFSVER_LATEST_EXTENDED};
if (!comphelper::IsFuzzing())
{
nVersion = GetODFSaneDefaultVersion();
}
// old per-zip-entry ODF encryption destroys macro signatures
if (!::sfx2::UseODFWholesomeEncryption(nVersion)
&& ( SignatureState::OK == nScriptingSignatureState
|| SignatureState::INVALID == nScriptingSignatureState
|| SignatureState::NOTVALIDATED == nScriptingSignatureState
|| SignatureState::PARTIAL_OK == nScriptingSignatureState))
{
std::unique_ptr<weld::MessageDialog> xBox(
Application::CreateMessageDialog(mpFrameWeld,
VclMessageType::Question, VclButtonsType::YesNo,
SfxResId(RID_SVXSTR_XMLSEC_QUERY_LOSINGSCRIPTINGSIGNATURE)));
if (xBox->run() == RET_NO)
{
bPassWord = false;
}
}
}
if (bPassWord)
{
// ask for a password
const OUString& aDocName(rpURLList[0]);
@@ -2652,7 +2680,7 @@ ErrCode FileDialogHelper::Execute( std::vector<OUString>& rpURLList,
const OUString& rDirPath )
{
SetDisplayFolder( rDirPath );
return mpImpl->execute( rpURLList, rpSet, rFilter );
return mpImpl->execute(rpURLList, rpSet, rFilter, SignatureState::UNKNOWN);
}
@@ -2662,11 +2690,12 @@ ErrCode FileDialogHelper::Execute()
}
ErrCode FileDialogHelper::Execute( std::optional<SfxAllItemSet>& rpSet,
OUString& rFilter )
OUString& rFilter,
SignatureState const nScriptingSignatureState)
{
ErrCode nRet;
std::vector<OUString> rURLList;
nRet = mpImpl->execute(rURLList, rpSet, rFilter);
nRet = mpImpl->execute(rURLList, rpSet, rFilter, nScriptingSignatureState);
return nRet;
}
+3 -2
View File
@@ -27,6 +27,7 @@
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/ui/dialogs/XFilePickerListener.hpp>
#include <com/sun/star/ui/dialogs/XDialogClosedListener.hpp>
#include <unotools/saveopt.hxx>
#include <sfx2/fcontnr.hxx>
#include <sfx2/filedlghelper.hxx>
@@ -181,7 +182,8 @@ namespace sfx2
ErrCode execute( std::vector<OUString>& rpURLList,
std::optional<SfxAllItemSet>& rpSet,
OUString& rFilter );
OUString& rFilter,
SignatureState nScriptingSignatureState);
ErrCode execute();
void setFilter( const OUString& rFilter );
@@ -215,7 +217,6 @@ namespace sfx2
css::uno::Reference<css::awt::XWindow> GetFrameInterface();
};
} // end of namespace sfx2
#endif // INCLUDED_SFX2_SOURCE_DIALOG_FILEDLGIMPL_HXX
+15 -8
View File
@@ -340,7 +340,8 @@ public:
OUString& aSuggestedDir,
sal_Int16 nDialog,
OUString& rStandardDir,
const css::uno::Sequence< OUString >& rDenyList
const css::uno::Sequence<OUString>& rDenyList,
SignatureState const nScriptingSignatureState
);
bool ShowDocumentInfoDialog();
@@ -679,7 +680,8 @@ void SfxStoringHelper::CallFinishGUIStoreModel()
SfxStoringHelper::FinishGUIStoreModel(aFileNameIter, *m_xModelData, m_bRemote, m_nStoreMode, aFilterProps,
m_bSetStandardName, m_bPreselectPassword, m_bDialogUsed,
aFilterFromMediaDescr, aOldFilterName, m_aArgsSequence, aFilterName);
aFilterFromMediaDescr, aOldFilterName, m_aArgsSequence,
aFilterName, m_nScriptingSignatureState);
if (SfxViewShell::Current())
SfxViewShell::Current()->SetStoringHelper(nullptr);
@@ -895,7 +897,8 @@ bool ModelData_Impl::OutputFileDialog( sal_Int16 nStoreMode,
OUString& aSuggestedDir,
sal_Int16 nDialog,
OUString& rStandardDir,
const css::uno::Sequence< OUString >& rDenyList)
const css::uno::Sequence<OUString>& rDenyList,
SignatureState const nScriptingSignatureState)
{
if ( nStoreMode == SAVEASREMOTE_REQUESTED )
nStoreMode = SAVEAS_REQUESTED;
@@ -1097,7 +1100,7 @@ bool ModelData_Impl::OutputFileDialog( sal_Int16 nStoreMode,
// aFilterName is a pure output parameter, pDialogParams is an in/out parameter
OUString aFilterName;
// in LOK case we don't show File Picker so it will fail, but execute to do other preparations
if ( pFileDlg->Execute( pDialogParams, aFilterName ) != ERRCODE_NONE
if (pFileDlg->Execute(pDialogParams, aFilterName, nScriptingSignatureState) != ERRCODE_NONE
&& !comphelper::LibreOfficeKit::isActive() )
{
throw task::ErrorCodeIOException(
@@ -1477,7 +1480,8 @@ bool SfxStoringHelper::GUIStoreModel( const uno::Reference< frame::XModel2 >& xM
std::u16string_view aSlotName,
uno::Sequence< beans::PropertyValue >& aArgsSequence,
bool bPreselectPassword,
SignatureState nDocumentSignatureState,
SignatureState const nDocumentSignatureState,
SignatureState const nScriptingSignatureState,
bool bIsAsync)
{
m_xModelData = std::make_shared<ModelData_Impl>( *this, xModel, aArgsSequence );
@@ -1488,6 +1492,7 @@ bool SfxStoringHelper::GUIStoreModel( const uno::Reference< frame::XModel2 >& xM
m_bSetStandardName = false; // can be set only for SaveAs
m_bPreselectPassword = bPreselectPassword;
m_nScriptingSignatureState = nScriptingSignatureState;
// parse the slot name
m_bRemote = false;
@@ -1646,7 +1651,8 @@ bool SfxStoringHelper::GUIStoreModel( const uno::Reference< frame::XModel2 >& xM
return SfxStoringHelper::FinishGUIStoreModel(aFileNameIter, aModelData, m_bRemote, m_nStoreMode, aFilterProps,
m_bSetStandardName, m_bPreselectPassword, m_bDialogUsed,
aFilterFromMediaDescr, aOldFilterName, aArgsSequence, aFilterName);
aFilterFromMediaDescr, aOldFilterName, aArgsSequence,
aFilterName, nScriptingSignatureState);
}
bool SfxStoringHelper::FinishGUIStoreModel(::comphelper::SequenceAsHashMap::const_iterator& aFileNameIter,
@@ -1656,7 +1662,8 @@ bool SfxStoringHelper::FinishGUIStoreModel(::comphelper::SequenceAsHashMap::cons
std::u16string_view aFilterFromMediaDescr,
std::u16string_view aOldFilterName,
uno::Sequence< beans::PropertyValue >& aArgsSequence,
OUString aFilterName)
OUString aFilterName,
SignatureState const nScriptingSignatureState)
{
const OUString sFilterNameString(aFilterNameString);
const OUString sFilterOptionsString(aFilterOptionsString);
@@ -1718,7 +1725,7 @@ bool SfxStoringHelper::FinishGUIStoreModel(::comphelper::SequenceAsHashMap::cons
for (;;)
{
// in case the dialog is opened a second time the folder should be the same as previously navigated to by the user, not what was handed over by initial parameters
bUseFilterOptions = aModelData.OutputFileDialog( nStoreMode, aFilterProps, bSetStandardName, aSuggestedName, bPreselectPassword, aSuggestedDir, nDialog, sStandardDir, aDenyList );
bUseFilterOptions = aModelData.OutputFileDialog(nStoreMode, aFilterProps, bSetStandardName, aSuggestedName, bPreselectPassword, aSuggestedDir, nDialog, sStandardDir, aDenyList, nScriptingSignatureState);
if ( nStoreMode == SAVEAS_REQUESTED )
{
// in case of saving check filter for possible alien warning
+1
View File
@@ -1153,6 +1153,7 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq)
aDispatchArgs,
bPreselectPassword,
GetDocumentSignatureState(),
GetScriptingSignatureState(),
bIsAsync );
if (bMailPrepareExport)
+8 -3
View File
@@ -116,6 +116,7 @@
#include <sfx2/viewfrm.hxx>
#include "graphhelp.hxx"
#include <appbaslib.hxx>
#include <guisaveas.hxx>
#include "objstor.hxx"
#include "exoticfileloadexception.hxx"
#include <unicode/ucsdet.h>
@@ -180,11 +181,15 @@ bool SfxObjectShell::QuerySlotExecutable( sal_uInt16 /*nSlotId*/ )
return true;
}
static bool UseODFWholesomeEncryption(SvtSaveOptions::ODFSaneDefaultVersion const nODFVersion)
namespace sfx2 {
bool UseODFWholesomeEncryption(SvtSaveOptions::ODFSaneDefaultVersion const nODFVersion)
{
return nODFVersion == SvtSaveOptions::ODFSVER_LATEST_EXTENDED;
}
} // namespace sfx2
bool GetEncryptionData_Impl( const SfxItemSet* pSet, uno::Sequence< beans::NamedValue >& o_rEncryptionData )
{
bool bResult = false;
@@ -365,7 +370,7 @@ void SfxObjectShell::SetupStorage( const uno::Reference< embed::XStorage >& xSto
auto pEncryptionAlgs = aEncryptionAlgs.getArray();
pEncryptionAlgs[0].Value <<= xml::crypto::DigestID::SHA256;
if (UseODFWholesomeEncryption(nDefVersion))
if (::sfx2::UseODFWholesomeEncryption(nDefVersion))
{
pEncryptionAlgs[1].Value <<= xml::crypto::CipherID::AES_GCM_W3C;
pEncryptionAlgs[2].Value.clear();
@@ -1549,7 +1554,7 @@ bool SfxObjectShell::SaveTo_Impl
if (GetEncryptionData_Impl(&rMedium.GetItemSet(), aEncryptionData))
{
assert(aEncryptionData.getLength() != 0);
if (bOwnTarget && UseODFWholesomeEncryption(nVersion))
if (bOwnTarget && ::sfx2::UseODFWholesomeEncryption(nVersion))
{
// when embedded objects are stored here, it should be called from
// this function for the root document and encryption data was cleared
+1
View File
@@ -923,6 +923,7 @@ ErrCodeMsg SfxInPlaceClient::DoVerb(sal_Int32 nVerb)
aDispatchArgs,
false,
SignatureState::NOSIGNATURES,
SignatureState::NOSIGNATURES,
false );
}
catch( const task::ErrorCodeIOException& aErrorEx )