tdf#159040: add sign with default certificate to save dialog

Include X.509 certificates under Tools->Options->UserData
among the keys for signing.

Add a new checkbox to Save file dialog, to sign with that
selected key easily.

The checkbox is disabled if there's no matching key found.

Change-Id: I9fc16790c479819cd1f35bcad040d0ebc7c4bdef
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170619
Tested-by: Jenkins
Reviewed-by: Sarper Akdemir <sarper.akdemir@allotropia.de>
This commit is contained in:
Sarper Akdemir 2024-07-17 12:47:22 +02:00
parent 6ca02ef177
commit 426c641976
27 changed files with 293 additions and 24 deletions

View file

@ -22,6 +22,7 @@
#include <rtl/ustrbuf.hxx>
#include <osl/diagnose.h>
#include <o3tl/string_view.hxx>
#include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp>
#include <utility>
#include <vector>
@ -308,6 +309,34 @@ std::vector< std::pair< OUString, OUString> > parseDN(std::u16string_view rRawSt
return aStr.makeStringAndClear();
}
css::uno::Reference<css::security::XCertificate> FindCertInContext(
const css::uno::Reference<css::xml::crypto::XXMLSecurityContext>& xSecurityContext,
const OUString& rContentPart)
{
if (!xSecurityContext.is())
return {};
css::uno::Reference<css::xml::crypto::XSecurityEnvironment> xSE
= xSecurityContext->getSecurityEnvironment();
css::uno::Sequence<css::uno::Reference<css::security::XCertificate>> xCertificates
= xSE->getPersonalCertificates();
auto aCertsIter = asNonConstRange(xCertificates);
auto pxCert
= std::find_if(aCertsIter.begin(), aCertsIter.end(),
[&rContentPart](auto& xCert)
{
return comphelper::xmlsec::GetContentPart(
xCert->getSubjectName(), xCert->getCertificateKind())
== rContentPart;
});
if (pxCert == aCertsIter.end())
return {};
return *pxCert;
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -25,6 +25,8 @@
# include <com/sun/star/xml/crypto/GPGSEInitializer.hpp>
# include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp>
#endif
#include <com/sun/star/xml/crypto/SEInitializer.hpp>
#include <comphelper/xmlsechelper.hxx>
#include <i18nlangtag/languagetag.hxx>
#include <i18nlangtag/mslangid.hxx>
@ -300,26 +302,52 @@ void SvxGeneralTabPage::InitCryptography()
#if HAVE_FEATURE_GPGME
m_xCryptoFrame->show();
uno::Reference< xml::crypto::XSEInitializer > xSEInitializer;
try
{
xSEInitializer = xml::crypto::GPGSEInitializer::create( comphelper::getProcessComponentContext() );
uno::Reference<xml::crypto::XXMLSecurityContext> xSC = xSEInitializer->createSecurityContext( OUString() );
if (xSC.is())
uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext
= xml::crypto::SEInitializer::create(comphelper::getProcessComponentContext())
->createSecurityContext("");
uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContextGPG
= xml::crypto::GPGSEInitializer::create(comphelper::getProcessComponentContext())
->createSecurityContext("");
if (xSecurityContextGPG.is())
{
uno::Reference<xml::crypto::XSecurityEnvironment> xSE = xSC->getSecurityEnvironment();
uno::Reference<xml::crypto::XSecurityEnvironment> xSE = xSecurityContextGPG->getSecurityEnvironment();
uno::Sequence<uno::Reference<security::XCertificate>> xCertificates = xSE->getPersonalCertificates();
if (xCertificates.hasElements())
{
for (auto& xCert : asNonConstRange(xCertificates))
{
m_xSigningKeyLB->append_text( xCert->getIssuerName());
m_xEncryptionKeyLB->append_text( xCert->getIssuerName());
const auto aIssuer = comphelper::xmlsec::GetContentPart(
xCert->getSubjectName(), xCert->getCertificateKind());
m_xSigningKeyLB->append_text(aIssuer);
m_xEncryptionKeyLB->append_text(aIssuer);
}
}
}
//tdf#115015: wrap checkbox text and listboxes if necessary
if (xSecurityContext.is())
{
uno::Reference<xml::crypto::XSecurityEnvironment> xSE = xSecurityContext->getSecurityEnvironment();
uno::Sequence<uno::Reference<security::XCertificate>> xCertificates
= xSE->getPersonalCertificates();
if (xCertificates.hasElements())
{
for (auto& xCert : asNonConstRange(xCertificates))
{
const auto aIssuer
= comphelper::xmlsec::GetContentPart(xCert->getSubjectName(),
xCert->getCertificateKind());
m_xSigningKeyLB->append_text(aIssuer);
}
}
}
if (xSecurityContext.is() || xSecurityContextGPG.is())
{
//tdf#115015: wrap checkbox text and listboxes if necessary
int nPrefWidth(m_xEncryptToSelfCB->get_preferred_size().Width());
int nMaxWidth = m_xEncryptToSelfCB->get_approximate_digit_width() * 40;
if (nPrefWidth > nMaxWidth)

View file

@ -1098,7 +1098,7 @@
<object class="GtkLabel" id="signingkeylabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes" context="optuserpage|signingkeylabel">_OpenPGP signing key:</property>
<property name="label" translatable="yes" context="optuserpage|signingkeylabel">_Signing key:</property>
<property name="use-underline">True</property>
<property name="mnemonic-widget">signingkey</property>
<property name="xalign">0</property>
@ -1151,7 +1151,7 @@
</items>
<child internal-child="accessible">
<object class="AtkObject" id="signingkey-atkobject">
<property name="AtkObject::accessible-description" translatable="yes" context="extended tip | signingkey">Select your OpenPGP key from the drop-down list for signing ODF documents.</property>
<property name="AtkObject::accessible-description" translatable="yes" context="extended tip | signingkey">Select your key from the drop-down list for signing ODF documents.</property>
</object>
</child>
</object>

View file

@ -70,6 +70,7 @@ public:
AUTOEXTENSION, //but autoextension is handled differently on MacOSX
PASSWORD,
GPGENCRYPTION,
GPGSIGN,
FILTEROPTIONS,
READONLY,
LINK,

View file

@ -17,6 +17,7 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <config_gpgme.h>
#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
#include <com/sun/star/ui/dialogs/ControlActions.hpp>
@ -185,11 +186,17 @@ void ControlHelper::initialize( sal_Int16 nTemplateId )
m_bToggleVisibility[AUTOEXTENSION] = true;
m_bToggleVisibility[PASSWORD] = true;
m_bToggleVisibility[GPGENCRYPTION] = true;
#if HAVE_FEATURE_GPGME
m_bToggleVisibility[GPGSIGN] = true;
#endif
break;
case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
m_bToggleVisibility[AUTOEXTENSION] = true;
m_bToggleVisibility[PASSWORD] = true;
m_bToggleVisibility[GPGENCRYPTION] = true;
#if HAVE_FEATURE_GPGME
m_bToggleVisibility[GPGSIGN] = true;
#endif
m_bToggleVisibility[FILTEROPTIONS] = true;
break;
case FILESAVE_AUTOEXTENSION_SELECTION:
@ -605,6 +612,7 @@ int ControlHelper::getControlElementName(const Class aClazz, const int nControlI
TOGGLE_ELEMENT( AUTOEXTENSION );
TOGGLE_ELEMENT( PASSWORD );
TOGGLE_ELEMENT( GPGENCRYPTION );
TOGGLE_ELEMENT( GPGSIGN );
TOGGLE_ELEMENT( FILTEROPTIONS );
TOGGLE_ELEMENT( READONLY );
TOGGLE_ELEMENT( LINK );
@ -729,6 +737,7 @@ case ExtendedFilePickerElementIds::LISTBOX_##elem##_LABEL: \
MAP_TOGGLE( AUTOEXTENSION );
MAP_TOGGLE( PASSWORD );
MAP_TOGGLE( GPGENCRYPTION );
MAP_TOGGLE( GPGSIGN );
MAP_TOGGLE( FILTEROPTIONS );
MAP_TOGGLE( READONLY );
MAP_TOGGLE( LINK );

View file

@ -51,6 +51,7 @@ Entry const CtrlIdToResIdTable[] = {
{ CHECKBOX_AUTOEXTENSION, STR_SVT_FILEPICKER_AUTO_EXTENSION },
{ CHECKBOX_PASSWORD, STR_SVT_FILEPICKER_PASSWORD },
{ CHECKBOX_GPGENCRYPTION, STR_SVT_FILEPICKER_GPGENCRYPT },
{ CHECKBOX_GPGSIGN, STR_SVT_FILEPICKER_GPGSIGN },
{ CHECKBOX_FILTEROPTIONS, STR_SVT_FILEPICKER_FILTER_OPTIONS },
{ CHECKBOX_READONLY, STR_SVT_FILEPICKER_READONLY },
{ CHECKBOX_LINK, STR_SVT_FILEPICKER_INSERT_AS_LINK },

View file

@ -79,6 +79,7 @@ namespace svt
{ "FilterListLabel", LISTBOX_FILTER_LABEL, PROPERTY_FLAGS_COMMON | PropFlags::Text },
{ "FilterOptionsBox", CHECKBOX_FILTEROPTIONS, PROPERTY_FLAGS_COMMON | PROPERTY_FLAGS_CHECKBOX },
{ "GpgPassword", CHECKBOX_GPGENCRYPTION, PROPERTY_FLAGS_COMMON | PROPERTY_FLAGS_CHECKBOX },
{ "GpgSign", CHECKBOX_GPGSIGN, PROPERTY_FLAGS_COMMON | PROPERTY_FLAGS_CHECKBOX },
{ "HelpButton", PUSHBUTTON_HELP, PROPERTY_FLAGS_COMMON | PropFlags::Text },
{ "ImageAnchorList", LISTBOX_IMAGE_ANCHOR, PROPERTY_FLAGS_COMMON | PROPERTY_FLAGS_LISTBOX },
{ "ImageAnchorListLabel", LISTBOX_IMAGE_ANCHOR_LABEL, PROPERTY_FLAGS_COMMON | PropFlags::Text },
@ -399,6 +400,7 @@ namespace svt
case CHECKBOX_AUTOEXTENSION:
case CHECKBOX_PASSWORD:
case CHECKBOX_GPGENCRYPTION:
case CHECKBOX_GPGSIGN:
case CHECKBOX_FILTEROPTIONS:
case CHECKBOX_READONLY:
case CHECKBOX_LINK:

View file

@ -302,6 +302,7 @@ SvtFileDialog::SvtFileDialog(weld::Window* pParent, PickerFlags nStyle)
m_xImpl->m_xBtnNewFolder = m_xBuilder->weld_button(u"new_folder"_ustr);
m_xImpl->m_xCbPassword = m_xBuilder->weld_check_button(u"password"_ustr);
m_xImpl->m_xCbGPGEncrypt = m_xBuilder->weld_check_button(u"gpgencrypt"_ustr);
m_xImpl->m_xCbGPGSign = m_xBuilder->weld_check_button(u"gpgsign"_ustr);
m_xImpl->m_xCbAutoExtension = m_xBuilder->weld_check_button(u"extension"_ustr);
m_xImpl->m_xSharedLabel = m_xBuilder->weld_label(u"shared_label"_ustr);
m_xImpl->m_xSharedListBox = m_xBuilder->weld_combo_box(u"shared"_ustr);
@ -367,8 +368,12 @@ SvtFileDialog::SvtFileDialog(weld::Window* pParent, PickerFlags nStyle)
m_xImpl->m_xCbPassword->set_label( FpsResId( STR_SVT_FILEPICKER_PASSWORD ) );
m_xImpl->m_xCbPassword->connect_toggled( LINK( this, SvtFileDialog, ClickHdl_Impl ) );
m_xImpl->m_xCbPassword->show();
m_xImpl->m_xCbGPGEncrypt->connect_toggled( LINK( this, SvtFileDialog, ClickHdl_Impl ) );
m_xImpl->m_xCbGPGEncrypt->show();
m_xImpl->m_xCbGPGSign->connect_toggled( LINK( this, SvtFileDialog, ClickHdl_Impl ) );
m_xImpl->m_xCbGPGSign->show();
}
// set the ini file for extracting the size
@ -1240,6 +1245,8 @@ IMPL_LINK( SvtFileDialog, ClickHdl_Impl, weld::Toggleable&, rCheckBox, void )
nId = CHECKBOX_PASSWORD;
else if ( &rCheckBox == m_xImpl->m_xCbGPGEncrypt.get() )
nId = CHECKBOX_GPGENCRYPTION;
else if ( &rCheckBox == m_xImpl->m_xCbGPGSign.get() )
nId = CHECKBOX_GPGSIGN;
else if ( &rCheckBox == m_xCbLinkBox.get() )
nId = CHECKBOX_LINK;
else if ( &rCheckBox == m_xCbPreviewBox.get() )
@ -1918,6 +1925,10 @@ weld::Widget* SvtFileDialog::getControl( sal_Int16 nControlId, bool bLabelContro
pReturn = m_xImpl->m_xCbGPGEncrypt.get();
break;
case CHECKBOX_GPGSIGN:
pReturn = m_xImpl->m_xCbGPGSign.get();
break;
case CHECKBOX_FILTEROPTIONS:
pReturn = m_xImpl->m_xCbOptions.get();
break;

View file

@ -127,6 +127,7 @@ public:
std::unique_ptr<weld::Button> m_xBtnNewFolder;
std::unique_ptr<weld::CheckButton> m_xCbPassword;
std::unique_ptr<weld::CheckButton> m_xCbGPGEncrypt;
std::unique_ptr<weld::CheckButton> m_xCbGPGSign;
std::unique_ptr<SvtURLBox> m_xEdCurrentPath;
std::unique_ptr<weld::CheckButton> m_xCbAutoExtension;
std::unique_ptr<weld::CheckButton> m_xCbOptions;

View file

@ -18,6 +18,7 @@
*/
#include <sal/config.h>
#include <config_gpgme.h>
#include "VistaFilePicker.hxx"
@ -362,6 +363,9 @@ void SAL_CALL VistaFilePicker::initialize(const css::uno::Sequence< css::uno::An
nFeatures |= FEATURE_AUTOEXTENSION;
nFeatures |= FEATURE_PASSWORD;
nFeatures |= FEATURE_GPGPASSWORD;
#if HAVE_FEATURE_GPGME
nFeatures |= FEATURE_GPGSIGN;
#endif
}
break;
@ -372,6 +376,9 @@ void SAL_CALL VistaFilePicker::initialize(const css::uno::Sequence< css::uno::An
nFeatures |= FEATURE_PASSWORD;
nFeatures |= FEATURE_FILTEROPTIONS;
nFeatures |= FEATURE_GPGPASSWORD;
#if HAVE_FEATURE_GPGME
nFeatures |= FEATURE_GPGSIGN;
#endif
}
break;

View file

@ -641,6 +641,13 @@ void VistaFilePickerImpl::impl_sta_enableFeatures(::sal_Int32 nFeatures, ::sal_I
setLabelToControl(iCustom, nControlId);
}
if ((nFeatures & FEATURE_GPGSIGN) == FEATURE_GPGSIGN)
{
nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_GPGSIGN;
iCustom->AddCheckButton (nControlId, L"GpgSign", false);
setLabelToControl(iCustom, nControlId);
}
if ((nFeatures & FEATURE_READONLY) == FEATURE_READONLY)
{
nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY;
@ -1093,6 +1100,7 @@ void VistaFilePickerImpl::impl_sta_GetControlValue(Request& rRequest)
{
case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD :
case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_GPGENCRYPTION :
case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_GPGSIGN :
case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY :
case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS :
case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK :

View file

@ -56,6 +56,7 @@ const ::sal_Int32 FEATURE_READONLY = 512;
const ::sal_Int32 FEATURE_VERSION = 1024;
const ::sal_Int32 FEATURE_GPGPASSWORD = 2048;
const ::sal_Int32 FEATURE_IMAGEANCHOR = 4096;
const ::sal_Int32 FEATURE_GPGSIGN = 8192;
inline constexpr OUString PROP_PICKER_LISTENER(u"picker_listener"_ustr ); // [XFilePickerListenert]
inline constexpr OUString PROP_DIALOG_SHOW_RESULT(u"dialog_show_result"_ustr ); // [sal_Bool] true=OK, false=CANCEL

View file

@ -66,7 +66,8 @@ Entry const CtrlIdToResIdTable[] = {
{ CHECKBOX_SELECTION, STR_SVT_FILEPICKER_SELECTION },
{ FOLDERPICKER_TITLE, STR_SVT_FOLDERPICKER_DEFAULT_TITLE },
{ FOLDER_PICKER_DEF_DESCRIPTION, STR_SVT_FOLDERPICKER_DEFAULT_DESCRIPTION },
{ CHECKBOX_GPGENCRYPTION, STR_SVT_FILEPICKER_GPGENCRYPT }
{ CHECKBOX_GPGENCRYPTION, STR_SVT_FILEPICKER_GPGENCRYPT },
{ CHECKBOX_GPGSIGN, STR_SVT_FILEPICKER_GPGSIGN }
};
const sal_Int32 SIZE_TABLE = SAL_N_ELEMENTS( CtrlIdToResIdTable );

View file

@ -755,7 +755,17 @@
</packing>
</child>
<child>
<placeholder/>
<object class="GtkCheckButton" id="gpgsign">
<property name="label" translatable="yes" context="explorerfiledialog|gpgencrypt">Sign with default certificate</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
</object>
<packing>

View file

@ -27,6 +27,16 @@
#include <vector>
namespace com::sun::star::xml::crypto
{
class XXMLSecurityContext;
}
namespace com::sun::star::security
{
class XCertificate;
}
namespace comphelper::xmlsec
{
COMPHELPER_DLLPUBLIC OUString GetCertificateKind(const css::security::CertificateKind& rKind);
@ -40,6 +50,10 @@ COMPHELPER_DLLPUBLIC OUString GetContentPart(const OUString& _rRawString,
COMPHELPER_DLLPUBLIC OUString GetHexString(const css::uno::Sequence<sal_Int8>& _rSeq,
const char* _pSep, sal_uInt16 _nLineBreak = 0xFFFF);
COMPHELPER_DLLPUBLIC css::uno::Reference<css::security::XCertificate> FindCertInContext(
const css::uno::Reference<css::xml::crypto::XXMLSecurityContext>& xSecurityContext,
const OUString& rContentPart);
}
#endif

View file

@ -15,6 +15,7 @@
#define STR_SVT_FILEPICKER_PASSWORD NC_("STR_SVT_FILEPICKER_PASSWORD", "Save with pass~word")
//dear loplugins, please don't remove this constant, it will be used in follow-up commits
#define STR_SVT_FILEPICKER_GPGENCRYPT NC_("STR_SVT_FILEPICKER_GPGENCRYPT", "Encrypt with ~GPG key")
#define STR_SVT_FILEPICKER_GPGSIGN NC_("STR_SVT_FILEPICKER_GPGSIGN", "Sign with ~default certificate")
#define STR_SVT_FILEPICKER_FILTER_OPTIONS NC_("STR_SVT_FILEPICKER_FILTER_OPTIONS", "~Edit filter settings")
#define STR_SVT_FILEPICKER_READONLY NC_("STR_SVT_FILEPICKER_READONLY", "~Read-only")
#define STR_SVT_FILEPICKER_INSERT_AS_LINK NC_("STR_SVT_FILEPICKER_INSERT_AS_LINK", "~Link")

View file

@ -477,6 +477,7 @@ public:
bool IsAvoidRecentDocs() const { return mbAvoidRecentDocs; }
bool IsRememberingSignature() const { return bRememberSignature; }
void SetRememberCurrentSignature(bool bRemember);
/// Don't add to the recent documents - it's an expensive operation, sometimes it is not wanted.
void AvoidRecentDocs(bool bAvoid) { mbAvoidRecentDocs = bAvoid; }

View file

@ -301,7 +301,7 @@ class SvxZoomItem;
#define FN_CHANGE_THEME (SID_SFX_START + 1745)
#define FN_PARAM_NEW_THEME TypedWhichId<SfxStringItem>(SID_SFX_START + 1746)
#define SID_OPTIONS_PAGEID TypedWhichId<SfxUInt16Item>(SID_SFX_START + 1747)
#define SID_GPGSIGN TypedWhichId<SfxBoolItem>(SID_SFX_START + 1748)
// SID_SFX_free_END (SID_SFX_START + 3999)
#define SID_OPEN_NEW_VIEW TypedWhichId<SfxBoolItem>(SID_SFX_START + 520)

View file

@ -49,6 +49,7 @@ published constants ExtendedFilePickerElementIds
/** @since LibreOffice 6.0 */ const short CHECKBOX_GPGENCRYPTION = 211;
/** @since LibreOffice 6.1 */ const short LISTBOX_IMAGE_ANCHOR = 212;
/** @since LibreOffice 6.1 */ const short LISTBOX_IMAGE_ANCHOR_LABEL = 213;
/** @since LibreOffice 25.2 */ const short CHECKBOX_GPGSIGN = 214;
};

View file

@ -170,7 +170,7 @@
<prop oor:name="signingkey" oor:type="xs:string" oor:nillable="false">
<!-- UIHints: Tools - Options - General - User Data -->
<info>
<desc>Specifies user's preferred OpenPGP key used for document signing.</desc>
<desc>Specifies user's preferred key used for document signing.</desc>
</info>
<value/>
</prop>

View file

@ -96,6 +96,15 @@
#include <o3tl/string_view.hxx>
#include <officecfg/Office/Common.hxx>
#include <config_gpgme.h>
#if HAVE_FEATURE_GPGME
# include <com/sun/star/xml/crypto/SEInitializer.hpp>
# include <com/sun/star/xml/crypto/GPGSEInitializer.hpp>
# include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp>
#endif
#include <comphelper/xmlsechelper.hxx>
#include <unotools/useroptions.hxx>
#ifdef UNX
#include <errno.h>
#include <sys/stat.h>
@ -284,6 +293,7 @@ void FileDialogHelper_Impl::handleControlStateChanged( const FilePickerEvent& aE
enablePasswordBox( false );
enableGpgEncrBox( false );
updateSelectionBox();
updateSignByDefault();
// only use it for export and with our own dialog
if ( mbExport && !mbSystemPicker )
updateExportButton();
@ -508,6 +518,43 @@ void FileDialogHelper_Impl::updateSelectionBox()
}
}
void FileDialogHelper_Impl::updateSignByDefault()
{
#if HAVE_FEATURE_GPGME
if (!mbHasSignByDefault)
return;
auto HaveMatchingUserSigningKey = []() -> bool
{
auto aSigningKey = SvtUserOptions{}.GetSigningKey();
if (aSigningKey.isEmpty())
return false;
std::vector<uno::Reference<xml::crypto::XXMLSecurityContext>> xSecurityContexts{
xml::crypto::SEInitializer::create(comphelper::getProcessComponentContext())
->createSecurityContext({}),
xml::crypto::GPGSEInitializer::create(comphelper::getProcessComponentContext())
->createSecurityContext({}),
};
for (const auto& xSecurityContext : xSecurityContexts)
{
if (xSecurityContext.is())
{
css::uno::Reference<css::security::XCertificate> xCert
= comphelper::xmlsec::FindCertInContext(xSecurityContext, aSigningKey);
if (xCert.is())
return true;
}
}
return false;
};
updateExtendedControl(ExtendedFilePickerElementIds::CHECKBOX_GPGSIGN,
HaveMatchingUserSigningKey());
#endif
}
void FileDialogHelper_Impl::enablePasswordBox( bool bInit )
{
if ( ! mbHasPassword )
@ -918,6 +965,7 @@ FileDialogHelper_Impl::FileDialogHelper_Impl(
mpAntiImpl = _pAntiImpl;
mbHasAutoExt = false;
mbHasPassword = false;
mbHasSignByDefault = false;
m_bHaveFilterOptions = false;
mbIsPwdEnabled = true;
mbIsGpgEncrEnabled = true;
@ -982,6 +1030,7 @@ FileDialogHelper_Impl::FileDialogHelper_Impl(
mbHasPassword = true;
mbHasAutoExt = true;
mbIsSaveDlg = true;
mbHasSignByDefault = true;
break;
case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
@ -998,6 +1047,7 @@ FileDialogHelper_Impl::FileDialogHelper_Impl(
mbHasAutoExt = true;
mbIsSaveDlg = true;
mbHasSignByDefault = true;
break;
case FILESAVE_AUTOEXTENSION_SELECTION:
@ -1257,6 +1307,7 @@ IMPL_LINK_NOARG( FileDialogHelper_Impl, InitControls, void*, void )
enableGpgEncrBox( true );
updateFilterOptionsBox( );
updateSelectionBox( );
updateSignByDefault();
}
void FileDialogHelper_Impl::preExecute()
@ -1606,6 +1657,19 @@ ErrCode FileDialogHelper_Impl::execute( std::vector<OUString>& rpURLList,
}
catch( const IllegalArgumentException& ){}
}
if ( pCurrentFilter && xCtrlAccess.is() )
{
try
{
Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_GPGSIGN, 0 );
bool bSign = false;
if ((aValue >>= bSign) && bSign)
{
rpSet->Put(SfxBoolItem(SID_GPGSIGN, bSign));
}
}
catch( const IllegalArgumentException& ){}
}
SaveLastUsedFilter();
return ERRCODE_NONE;

View file

@ -95,6 +95,7 @@ namespace sfx2
bool mbSelectionEnabled : 1;
bool mbHasSelectionBox : 1;
bool mbSelectionFltrEnabled : 1;
bool mbHasSignByDefault : 1;
private:
void addFilters( const OUString& rFactory,
@ -108,6 +109,7 @@ namespace sfx2
void updateFilterOptionsBox();
void updateExportButton();
void updateSelectionBox();
void updateSignByDefault();
void updateVersions();
void updatePreviewState( bool _bUpdatePreviewWindow );
void dispose();

View file

@ -16,6 +16,14 @@
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <config_gpgme.h>
#if HAVE_FEATURE_GPGME
#include <com/sun/star/xml/crypto/GPGSEInitializer.hpp>
#include <com/sun/star/xml/crypto/SEInitializer.hpp>
#include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp>
#endif
#include <com/sun/star/security/DocumentDigitalSignatures.hpp>
#include <com/sun/star/security/XCertificate.hpp>
#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
#include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
@ -63,6 +71,7 @@
#include <comphelper/sequenceashashmap.hxx>
#include <comphelper/mimeconfighelper.hxx>
#include <comphelper/lok.hxx>
#include <comphelper/xmlsechelper.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <utility>
#include <vcl/svapp.hxx>
@ -275,6 +284,7 @@ class ModelData_Impl
::comphelper::SequenceAsHashMap m_aMediaDescrHM;
bool m_bRecommendReadOnly;
bool m_bSignWithDefaultSignature;
DECL_LINK(OptionsDialogClosedHdl, css::ui::dialogs::DialogClosedEvent*, void);
@ -294,6 +304,7 @@ public:
::comphelper::SequenceAsHashMap& GetMediaDescr() { return m_aMediaDescrHM; }
bool IsRecommendReadOnly() const { return m_bRecommendReadOnly; }
bool IsSignWithDefaultSignature() const { return m_bSignWithDefaultSignature; }
const ::comphelper::SequenceAsHashMap& GetDocProps();
@ -1093,6 +1104,10 @@ bool ModelData_Impl::OutputFileDialog( sal_Int16 nStoreMode,
m_bRecommendReadOnly = ( pRecommendReadOnly && pRecommendReadOnly->GetValue() );
pDialogParams->ClearItem( SID_RECOMMENDREADONLY );
const SfxBoolItem* pSignWithDefaultKey = SfxItemSet::GetItem<SfxBoolItem>(&*pDialogParams, SID_GPGSIGN, false);
m_bSignWithDefaultSignature = (pSignWithDefaultKey && pSignWithDefaultKey->GetValue());
pDialogParams->ClearItem( SID_GPGSIGN );
uno::Sequence< beans::PropertyValue > aPropsFromDialog;
TransformItems( nSlotID, *pDialogParams, aPropsFromDialog );
GetMediaDescr() << aPropsFromDialog;
@ -1878,6 +1893,52 @@ bool SfxStoringHelper::FinishGUIStoreModel(::comphelper::SequenceAsHashMap::cons
#endif
}
if (aModelData.IsSignWithDefaultSignature())
{
auto SignWithDefaultSignature = [&]()
{
#if HAVE_FEATURE_GPGME
auto aSigningKey = SvtUserOptions().GetSigningKey();
if (aSigningKey.isEmpty())
return;
std::vector<uno::Reference<xml::crypto::XXMLSecurityContext>> xSecurityContexts{
xml::crypto::SEInitializer::create(comphelper::getProcessComponentContext())
->createSecurityContext({}),
xml::crypto::GPGSEInitializer::create(comphelper::getProcessComponentContext())
->createSecurityContext({}),
};
for (const auto& xSecurityContext : xSecurityContexts)
{
if (xSecurityContext.is())
{
css::uno::Reference<css::security::XCertificate> xCert
= comphelper::xmlsec::FindCertInContext(xSecurityContext, aSigningKey);
if (xCert.is() && SfxViewShell::Current())
{
SfxObjectShell* pDocShell = SfxViewShell::Current()->GetObjectShell();
bool bSigned = pDocShell->SignDocumentContentUsingCertificate(xCert);
if (bSigned && pDocShell->HasValidSignatures())
{
std::unique_ptr<weld::MessageDialog> xBox(
Application::CreateMessageDialog(
SfxStoringHelper::GetModelWindow(aModelData.GetModel()),
VclMessageType::Question, VclButtonsType::YesNo,
SfxResId(STR_QUERY_REMEMBERSIGNATURE)));
pDocShell->SetRememberCurrentSignature(xBox->run() == RET_YES);
}
return;
}
}
}
return;
#endif
};
SignWithDefaultSignature();
}
// Launch PDF viewer
if ( nStoreMode & PDFEXPORT_REQUESTED && !comphelper::LibreOfficeKit::isActive() )
{

View file

@ -600,16 +600,7 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq)
{
std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog( pDialogParent,
VclMessageType::Question, VclButtonsType::YesNo, SfxResId(STR_QUERY_REMEMBERSIGNATURE)));
if (xBox->run() == RET_YES)
{
rSignatureInfosRemembered = GetDocumentSignatureInformation(false);
bRememberSignature = true;
}
else
{
rSignatureInfosRemembered = uno::Sequence< security::DocumentSignatureInformation >();
bRememberSignature = false;
}
SetRememberCurrentSignature(xBox->run() == RET_YES);
}
return;
@ -1899,6 +1890,20 @@ uno::Sequence< security::DocumentSignatureInformation > SfxObjectShell::GetDocum
return aResult;
}
void SfxObjectShell::SetRememberCurrentSignature(bool bRemember)
{
if (bRemember)
{
rSignatureInfosRemembered = GetDocumentSignatureInformation(false);
bRememberSignature = true;
}
else
{
rSignatureInfosRemembered = uno::Sequence<security::DocumentSignatureInformation>();
bRememberSignature = false;
}
}
SignatureState SfxObjectShell::ImplGetSignatureState( bool bScriptingContent )
{
SignatureState* pState = bScriptingContent ? &pImpl->nScriptingSignatureState : &pImpl->nDocumentSignatureState;

View file

@ -18,6 +18,7 @@
*/
#include <config_gio.h>
#include <config_gpgme.h>
#include <com/sun/star/awt/SystemDependentXWindow.hpp>
#include <com/sun/star/awt/Toolkit.hpp>
@ -201,6 +202,7 @@ SalGtkFilePicker::SalGtkFilePicker( const uno::Reference< uno::XComponentContext
LABEL_TOGGLE( AUTOEXTENSION );
LABEL_TOGGLE( PASSWORD );
LABEL_TOGGLE( GPGENCRYPTION );
LABEL_TOGGLE( GPGSIGN );
LABEL_TOGGLE( FILTEROPTIONS );
LABEL_TOGGLE( READONLY );
LABEL_TOGGLE( LINK );
@ -1118,6 +1120,7 @@ GtkWidget *SalGtkFilePicker::getWidget( sal_Int16 nControlId, GType *pType )
MAP_TOGGLE( AUTOEXTENSION );
MAP_TOGGLE( PASSWORD );
MAP_TOGGLE( GPGENCRYPTION );
MAP_TOGGLE( GPGSIGN );
MAP_TOGGLE( FILTEROPTIONS );
MAP_TOGGLE( READONLY );
MAP_TOGGLE( LINK );
@ -1698,6 +1701,9 @@ void SalGtkFilePicker::impl_initialize(GtkWidget* pParentWidget, sal_Int16 templ
first_button_text = sSave.getStr();
mbToggleVisibility[PASSWORD] = true;
mbToggleVisibility[GPGENCRYPTION] = true;
#if HAVE_FEATURE_GPGME
mbToggleVisibility[GPGSIGN] = true;
#endif
// TODO
break;
case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
@ -1705,6 +1711,9 @@ void SalGtkFilePicker::impl_initialize(GtkWidget* pParentWidget, sal_Int16 templ
first_button_text = sSave.getStr();
mbToggleVisibility[PASSWORD] = true;
mbToggleVisibility[GPGENCRYPTION] = true;
#if HAVE_FEATURE_GPGME
mbToggleVisibility[GPGSIGN] = true;
#endif
mbToggleVisibility[FILTEROPTIONS] = true;
// TODO
break;

View file

@ -162,6 +162,7 @@ class SalGtkFilePicker : public SalGtkPicker, public SalGtkFilePicker_Base
PREVIEW,
SELECTION,
GPGENCRYPTION,
GPGSIGN,
TOGGLE_LAST
};

View file

@ -37,6 +37,7 @@ const struct
{ CHECKBOX_AUTOEXTENSION, STR_SVT_FILEPICKER_AUTO_EXTENSION },
{ CHECKBOX_PASSWORD, STR_SVT_FILEPICKER_PASSWORD },
{ CHECKBOX_GPGENCRYPTION, STR_SVT_FILEPICKER_GPGENCRYPT },
{ CHECKBOX_GPGSIGN, STR_SVT_FILEPICKER_GPGSIGN },
{ CHECKBOX_FILTEROPTIONS, STR_SVT_FILEPICKER_FILTER_OPTIONS },
{ CHECKBOX_READONLY, STR_SVT_FILEPICKER_READONLY },
{ CHECKBOX_LINK, STR_SVT_FILEPICKER_INSERT_AS_LINK },