Allow selecting a custom certificate manager
Added a new option in Tools>Options>Security that allows choosing the
path of a different certificate manager.
Made Certificate Manager Button be disabled instead of hidden in case no
certificate manager is detected. Added a box notifying that the
certificate manager is opened (or not working in case it failed for some
reason).
Change-Id: I64a901766d4fb05c59c0f85fdf94c08a3ca4bdab
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153798
Tested-by: Jenkins
Reviewed-by: Thorsten Behrens <thorsten.behrens@allotropia.de>
diff --git a/cui/source/options/optinet2.cxx b/cui/source/options/optinet2.cxx
index 95d0ec1..cf879d0 100644
--- a/cui/source/options/optinet2.cxx
+++ b/cui/source/options/optinet2.cxx
@@ -493,6 +493,8 @@ SvxSecurityTabPage::SvxSecurityTabPage(weld::Container* pPage, weld::DialogContr
, m_xTSAURLsFrame(m_xBuilder->weld_container("tsaurls"))
, m_xTSAURLsPB(m_xBuilder->weld_button("tsas"))
, m_xNoPasswordSaveFT(m_xBuilder->weld_label("nopasswordsave"))
, m_xCertMgrPathLB(m_xBuilder->weld_button("browse"))
, m_xParameterEdit(m_xBuilder->weld_entry("parameterfield"))
{
//fdo#65595, we need height-for-width support here, but for now we can
//bodge it
@@ -516,10 +518,46 @@ SvxSecurityTabPage::SvxSecurityTabPage(weld::Container* pPage, weld::DialogContr
m_xMacroSecPB->connect_clicked( LINK( this, SvxSecurityTabPage, MacroSecPBHdl ) );
m_xCertPathPB->connect_clicked( LINK( this, SvxSecurityTabPage, CertPathPBHdl ) );
m_xTSAURLsPB->connect_clicked( LINK( this, SvxSecurityTabPage, TSAURLsPBHdl ) );
m_xCertMgrPathLB->connect_clicked( LINK( this, SvxSecurityTabPage, CertMgrPBHdl ) );
ActivatePage( rSet );
}
IMPL_LINK_NOARG(SvxSecurityTabPage, CertMgrPBHdl, weld::Button&, void)
{
try
{
FileDialogHelper aHelper(css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
FileDialogFlags::NONE, nullptr);
OUString sPath = m_xParameterEdit->get_text();
if (sPath.isEmpty())
sPath = "/usr/bin";
OUString sUrl;
osl::FileBase::getFileURLFromSystemPath(sPath, sUrl);
aHelper.SetDisplayDirectory(sUrl);
if (ERRCODE_NONE == aHelper.Execute())
{
sUrl = aHelper.GetPath();
if (osl::FileBase::getSystemPathFromFileURL(sUrl, sPath) != osl::FileBase::E_None)
{
sPath.clear();
}
m_xParameterEdit->set_text(sPath);
}
std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
comphelper::ConfigurationChanges::create());
OUString sCurCertMgr = m_xParameterEdit->get_text();
officecfg::Office::Common::Security::Scripting::CertMgrPath::set(sCurCertMgr, pBatch);
pBatch->commit();
}
catch (const uno::Exception&)
{
TOOLS_WARN_EXCEPTION("cui.options", "CertMgrPBHdl");
}
}
SvxSecurityTabPage::~SvxSecurityTabPage()
{
}
@@ -750,6 +788,17 @@ void SvxSecurityTabPage::InitControls()
{
m_xSavePasswordsCB->set_sensitive( false );
}
try
{
OUString sCurCertMgr = officecfg::Office::Common::Security::Scripting::CertMgrPath::get();
if (!sCurCertMgr.isEmpty())
m_xParameterEdit->set_text(sCurCertMgr);
}
catch (const uno::Exception&)
{
}
}
std::unique_ptr<SfxTabPage> SvxSecurityTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
@@ -803,6 +852,15 @@ bool SvxSecurityTabPage::FillItemSet( SfxItemSet* )
CheckAndSave( SvtSecurityOptions::EOption::BlockUntrustedRefererLinks, m_xSecOptDlg->IsBlockUntrustedRefererLinksChecked(), bModified );
}
std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
comphelper::ConfigurationChanges::create());
if (m_xParameterEdit->get_value_changed_from_saved())
{
OUString sCurCertMgr = m_xParameterEdit->get_text();
officecfg::Office::Common::Security::Scripting::CertMgrPath::set(sCurCertMgr, pBatch);
pBatch->commit();
}
return bModified;
}
diff --git a/cui/source/options/optinet2.hxx b/cui/source/options/optinet2.hxx
index 4d03d2d..9fea649 100644
--- a/cui/source/options/optinet2.hxx
+++ b/cui/source/options/optinet2.hxx
@@ -104,6 +104,9 @@ private:
std::unique_ptr<weld::Label> m_xNoPasswordSaveFT;
std::unique_ptr<weld::Button> m_xCertMgrPathLB;
std::unique_ptr<weld::Entry> m_xParameterEdit;
DECL_LINK(SecurityOptionsHdl, weld::Button&, void);
DECL_LINK(SavePasswordHdl, weld::Toggleable&, void);
DECL_LINK(MasterPasswordHdl, weld::Button&, void);
@@ -112,6 +115,7 @@ private:
DECL_LINK(MacroSecPBHdl, weld::Button&, void );
DECL_LINK(CertPathPBHdl, weld::Button&, void );
DECL_LINK(TSAURLsPBHdl, weld::Button&, void );
DECL_LINK(CertMgrPBHdl, weld::Button&, void );
void InitControls();
diff --git a/cui/uiconfig/ui/optsecuritypage.ui b/cui/uiconfig/ui/optsecuritypage.ui
index c728259..0c6099e 100644
--- a/cui/uiconfig/ui/optsecuritypage.ui
+++ b/cui/uiconfig/ui/optsecuritypage.ui
@@ -1,53 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.36.0 -->
<!-- Generated with glade 3.40.0 -->
<interface domain="cui">
<requires lib="gtk+" version="3.20"/>
<!-- n-columns=1 n-rows=1 -->
<!-- n-columns=1 n-rows=6 -->
<object class="GtkGrid" id="OptSecurityPage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="row_spacing">12</property>
<property name="can-focus">False</property>
<property name="border-width">6</property>
<property name="row-spacing">12</property>
<child>
<object class="GtkFrame" id="tsaurls">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<property name="label-xalign">0</property>
<property name="shadow-type">none</property>
<child>
<!-- n-columns=1 n-rows=1 -->
<!-- n-columns=2 n-rows=1 -->
<object class="GtkGrid" id="grid8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="column_spacing">24</property>
<property name="can-focus">False</property>
<property name="margin-start">12</property>
<property name="margin-top">6</property>
<property name="hexpand">True</property>
<property name="column-spacing">24</property>
<child>
<object class="GtkLabel" id="label9">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes" context="optsecuritypage|label9">Maintain a list of Time Stamping Authority (TSA) URLs to be used for digital signatures in PDF export.</property>
<property name="wrap">True</property>
<property name="width_chars">56</property>
<property name="max_width_chars">56</property>
<property name="width-chars">56</property>
<property name="max-width-chars">56</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="tsas">
<property name="label" translatable="yes" context="optsecuritypage|tsas">_TSAs...</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="valign">center</property>
<property name="use_underline">True</property>
<property name="use-underline">True</property>
<child internal-child="accessible">
<object class="AtkObject" id="tsas-atkobject">
<property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|tsas">Opens the Time Stamping Authority URLs dialog.</property>
@@ -55,8 +55,8 @@
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
</object>
@@ -64,7 +64,7 @@
<child type="label">
<object class="GtkLabel" id="label10">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes" context="optsecuritypage|label10">TSAs</property>
<attributes>
<attribute name="weight" value="bold"/>
@@ -73,50 +73,50 @@
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="left-attach">0</property>
<property name="top-attach">4</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="certificatepath">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<property name="label-xalign">0</property>
<property name="shadow-type">none</property>
<child>
<!-- n-columns=1 n-rows=1 -->
<!-- n-columns=2 n-rows=1 -->
<object class="GtkGrid" id="grid7">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="column_spacing">24</property>
<property name="can-focus">False</property>
<property name="margin-start">12</property>
<property name="margin-top">6</property>
<property name="hexpand">True</property>
<property name="column-spacing">24</property>
<child>
<object class="GtkLabel" id="label7">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes" context="optsecuritypage|label7">Select the Network Security Services certificate directory to use for digital signatures.</property>
<property name="wrap">True</property>
<property name="width_chars">56</property>
<property name="max_width_chars">56</property>
<property name="width-chars">56</property>
<property name="max-width-chars">56</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="cert">
<property name="label" translatable="yes" context="optsecuritypage|cert">_Certificate...</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="valign">center</property>
<property name="use_underline">True</property>
<property name="use-underline">True</property>
<child internal-child="accessible">
<object class="AtkObject" id="cert-atkobject">
<property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|cert">Opens the Certificate Path dialog.</property>
@@ -124,8 +124,8 @@
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
</object>
@@ -133,7 +133,7 @@
<child type="label">
<object class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes" context="optsecuritypage|label8">Certificate Path</property>
<attributes>
<attribute name="weight" value="bold"/>
@@ -142,50 +142,50 @@
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="macrosecurity">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<property name="label-xalign">0</property>
<property name="shadow-type">none</property>
<child>
<!-- n-columns=1 n-rows=1 -->
<!-- n-columns=2 n-rows=1 -->
<object class="GtkGrid" id="grid3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="column_spacing">24</property>
<property name="can-focus">False</property>
<property name="margin-start">12</property>
<property name="margin-top">6</property>
<property name="hexpand">True</property>
<property name="column-spacing">24</property>
<child>
<object class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes" context="optsecuritypage|label5">Adjust the security level for executing macros and specify trusted macro developers.</property>
<property name="wrap">True</property>
<property name="width_chars">56</property>
<property name="max_width_chars">56</property>
<property name="width-chars">56</property>
<property name="max-width-chars">56</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="macro">
<property name="label" translatable="yes" context="optsecuritypage|macro">Macro Securit_y...</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="valign">center</property>
<property name="use_underline">True</property>
<property name="use-underline">True</property>
<child internal-child="accessible">
<object class="AtkObject" id="macro-atkobject">
<property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|macro">Opens the Macro Security dialog.</property>
@@ -193,8 +193,8 @@
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
</object>
@@ -202,7 +202,7 @@
<child type="label">
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes" context="optsecuritypage|label3">Macro Security</property>
<attributes>
<attribute name="weight" value="bold"/>
@@ -211,41 +211,41 @@
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<property name="label-xalign">0</property>
<property name="shadow-type">none</property>
<child>
<!-- n-columns=1 n-rows=1 -->
<!-- n-columns=2 n-rows=1 -->
<object class="GtkGrid" id="grid2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="column_spacing">24</property>
<property name="can-focus">False</property>
<property name="margin-start">12</property>
<property name="margin-top">6</property>
<property name="hexpand">True</property>
<property name="column-spacing">24</property>
<child>
<!-- n-columns=1 n-rows=1 -->
<!-- n-columns=1 n-rows=2 -->
<object class="GtkGrid" id="grid4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="row_spacing">12</property>
<property name="row-spacing">12</property>
<child>
<object class="GtkCheckButton" id="savepassword">
<property name="label" translatable="yes" context="optsecuritypage|savepassword">Persistently _save passwords for web connections</property>
<property name="visible">True</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>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="use-underline">True</property>
<property name="draw-indicator">True</property>
<child internal-child="accessible">
<object class="AtkObject" id="savepassword-atkobject">
<property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|savepassword">If enabled, all passwords that you use to access files from web servers will be securely stored. You can retrieve the passwords from the list after you enter the master password.</property>
@@ -253,100 +253,100 @@
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<!-- n-columns=1 n-rows=1 -->
<!-- n-columns=1 n-rows=3 -->
<object class="GtkGrid" id="grid5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="row_spacing">6</property>
<property name="can-focus">False</property>
<property name="margin-start">12</property>
<property name="hexpand">True</property>
<property name="row-spacing">6</property>
<child>
<object class="GtkCheckButton" id="usemasterpassword">
<property name="label" translatable="yes" context="optsecuritypage|usemasterpassword">Protected _by a master password (recommended)</property>
<property name="visible">True</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>
<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">0</property>
<property name="top_attach">0</property>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="masterpasswordtext">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes" context="optsecuritypage|masterpasswordtext">Passwords are protected by a master password. You will be asked to enter it once per session, if %PRODUCTNAME retrieves a password from the protected password list.</property>
<property name="wrap">True</property>
<property name="width_chars">56</property>
<property name="max_width_chars">56</property>
<property name="width-chars">56</property>
<property name="max-width-chars">56</property>
<property name="xalign">0</property>
<attributes>
<attribute name="scale" value="0.9"/>
<attribute name="scale" value="0.90000000000000002"/>
</attributes>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="nopasswordsave">
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<property name="can-focus">False</property>
<property name="no-show-all">True</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes" context="optsecuritypage|nopasswordsave">Disabling the function to persistently store passwords deletes the list of passwords stored and resets the master password.
Do you want to delete password list and reset master password?</property>
<property name="wrap">True</property>
<property name="width_chars">56</property>
<property name="max_width_chars">56</property>
<property name="width-chars">56</property>
<property name="max-width-chars">56</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<!-- n-columns=1 n-rows=1 -->
<!-- n-columns=1 n-rows=2 -->
<object class="GtkGrid" id="grid6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_homogeneous">True</property>
<property name="can-focus">False</property>
<property name="row-homogeneous">True</property>
<child>
<!-- n-columns=1 n-rows=1 -->
<object class="GtkGrid" id="grid9">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<child>
<object class="GtkButton" id="connections">
<property name="label" translatable="yes" context="optsecuritypage|connections">Connect_ions...</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="valign">center</property>
<property name="use_underline">True</property>
<property name="use-underline">True</property>
<child internal-child="accessible">
<object class="AtkObject" id="connections-atkobject">
<property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|connections">Asks for the master password. If master password is correct, shows the Stored Web Connection Information dialog.</property>
@@ -354,29 +354,29 @@ Do you want to delete password list and reset master password?</property>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<!-- n-columns=1 n-rows=1 -->
<object class="GtkGrid" id="grid10">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<child>
<object class="GtkButton" id="masterpassword">
<property name="label" translatable="yes" context="optsecuritypage|masterpassword">_Master Password...</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="valign">center</property>
<property name="use_underline">True</property>
<property name="use-underline">True</property>
<child internal-child="accessible">
<object class="AtkObject" id="masterpassword-atkobject">
<property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|masterpassword">Opens the Enter Master Password dialog.</property>
@@ -384,20 +384,20 @@ Do you want to delete password list and reset master password?</property>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
</object>
@@ -405,7 +405,7 @@ Do you want to delete password list and reset master password?</property>
<child type="label">
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes" context="optsecuritypage|label2">Passwords for Web Connections</property>
<attributes>
<attribute name="weight" value="bold"/>
@@ -414,50 +414,50 @@ Do you want to delete password list and reset master password?</property>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<property name="label-xalign">0</property>
<property name="shadow-type">none</property>
<child>
<!-- n-columns=1 n-rows=1 -->
<!-- n-columns=2 n-rows=1 -->
<object class="GtkGrid" id="grid1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="column_spacing">24</property>
<property name="can-focus">False</property>
<property name="margin-start">12</property>
<property name="margin-top">6</property>
<property name="hexpand">True</property>
<property name="column-spacing">24</property>
<child>
<object class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes" context="optsecuritypage|label4">Adjust security related options and define warnings for hidden information in documents. </property>
<property name="wrap">True</property>
<property name="width_chars">56</property>
<property name="max_width_chars">56</property>
<property name="width-chars">56</property>
<property name="max-width-chars">56</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="options">
<property name="label" translatable="yes" context="optsecuritypage|options">O_ptions...</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="valign">center</property>
<property name="use_underline">True</property>
<property name="use-underline">True</property>
<child internal-child="accessible">
<object class="AtkObject" id="options-atkobject">
<property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|options">Opens the "Security Options and Warnings" dialog.</property>
@@ -465,8 +465,8 @@ Do you want to delete password list and reset master password?</property>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
</object>
@@ -474,7 +474,7 @@ Do you want to delete password list and reset master password?</property>
<child type="label">
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes" context="optsecuritypage|label1">Security Options and Warnings</property>
<attributes>
<attribute name="weight" value="bold"/>
@@ -483,14 +483,96 @@ Do you want to delete password list and reset master password?</property>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="OptSecurityPage-atkobject">
<property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|OptSecurityPage">Defines the security options for saving documents, for web connections, and for opening documents that contain macros.</property>
<child>
<object class="GtkFrame" id="certmgr">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="label-xalign">0</property>
<property name="shadow-type">none</property>
<child>
<!-- n-columns=2 n-rows=2 -->
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="row-spacing">8</property>
<property name="column-spacing">24</property>
<property name="margin-start">12</property>
<property name="margin-top">6</property>
<child>
<object class="GtkLabel" id="label11">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes" context="optsecuritypage|label9">Select custom certificate manager executable. Note that LibreOffice tries to locate installed ones automatically.</property>
<property name="wrap">True</property>
<property name="width-chars">56</property>
<property name="max-width-chars">56</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="browse">
<property name="label" translatable="yes" context="stock1">_Browse...</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="can-default">True</property>
<property name="has-default">True</property>
<property name="receives-default">True</property>
<property name="use-underline">True</property>
<property name="image-position">right</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="parameterfield">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="hexpand">True</property>
<property name="activates-default">True</property>
<property name="truncate-multiline">True</property>
<child internal-child="accessible">
<object class="AtkObject" id="parameterfield-atkobject">
<property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|parameterfield">Enter the executable of the certificate manager path.</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label12">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes" context="optsecuritypage|label10">Certificate Manager</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">5</property>
</packing>
</child>
</object>
<object class="GtkSizeGroup" id="sizegroup1">
@@ -501,6 +583,7 @@ Do you want to delete password list and reset master password?</property>
<widget name="connections"/>
<widget name="masterpassword"/>
<widget name="options"/>
<widget name="browse"/>
</widgets>
</object>
</interface>
diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
index 528cd5a..87ee6c6 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
@@ -2406,6 +2406,12 @@
<desc>Contains the last path manually selected by the user for the CertDir property.</desc>
</info>
</prop>
<prop oor:name="CertMgrPath" oor:type="xs:string" oor:nillable="false">
<info>
<desc>Contains the path of certificate manager if specified.</desc>
</info>
<value></value>
</prop>
<prop oor:name="TSAURLs" oor:type="oor:string-list">
<info>
<desc>Contains the URLs or Time Stamping Authority servers.</desc>
diff --git a/xmlsecurity/Module_xmlsecurity.mk b/xmlsecurity/Module_xmlsecurity.mk
index 2416d60..f5b4426 100644
--- a/xmlsecurity/Module_xmlsecurity.mk
+++ b/xmlsecurity/Module_xmlsecurity.mk
@@ -15,6 +15,10 @@ $(eval $(call gb_Module_add_targets,xmlsecurity,\
UIConfig_xmlsec \
))
$(eval $(call gb_Library_use_custom_headers,xmlsecurity,\
officecfg/registry \
))
$(eval $(call gb_Module_add_slowcheck_targets,xmlsecurity,\
CppunitTest_xmlsecurity_pdfsigning \
))
diff --git a/xmlsecurity/inc/digitalsignaturesdialog.hxx b/xmlsecurity/inc/digitalsignaturesdialog.hxx
index 21b04811..09a9bd0 100644
--- a/xmlsecurity/inc/digitalsignaturesdialog.hxx
+++ b/xmlsecurity/inc/digitalsignaturesdialog.hxx
@@ -90,6 +90,8 @@ private:
void ImplFillSignaturesBox();
void ImplShowSignaturesDetails();
bool IsThereCertificateMgr();
void GetCertificateManager(OUString& aPath, OUString& sExecutable, OUString& sFoundGUIServer);
bool GetPathAllOS(OUString& aPath);
css::uno::Reference<css::security::XCertificate> getCertificate(const SignatureInformation& rInfo);
css::uno::Reference<css::xml::crypto::XSecurityEnvironment> getSecurityEnvironmentForCertificate(
diff --git a/xmlsecurity/inc/strings.hrc b/xmlsecurity/inc/strings.hrc
index 8cf89b2..46e4c58 100644
--- a/xmlsecurity/inc/strings.hrc
+++ b/xmlsecurity/inc/strings.hrc
@@ -35,6 +35,7 @@
#define STR_THUMBPRINT_SHA1 NC_("STR_THUMBPRINT_SHA1", "Thumbprint SHA1")
#define STR_THUMBPRINT_MD5 NC_("STR_THUMBPRINT_MD5", "Thumbprint MD5")
#define STR_XMLSECDLG_OPENED_CRTMGR NC_("STR_XMLSECDLG_OPENED_CRTMGR", "You have opened the certificate manager at\n")
#define STR_XMLSECDLG_OLD_ODF_FORMAT NC_("STR_XMLSECDLG_OLD_ODF_FORMAT", "This document contains signatures in ODF 1.1 (OpenOffice.org 2.x) format. " \
"Signing documents in %PRODUCTNAME %PRODUCTVERSION requires ODF 1.2 format version. " \
"Thus no signatures can be added or removed to this document.\n\n" \
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index 921dedb..7ce82fd 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
@@ -17,6 +17,7 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <rtl/ustring.hxx>
#include <sal/config.h>
#include <string_view>
@@ -27,6 +28,8 @@
#include <biginteger.hxx>
#include <sax/tools/converter.hxx>
#include <comphelper/diagnose_ex.hxx>
#include <comphelper/configuration.hxx>
#include <officecfg/Office/Common.hxx>
#include <com/sun/star/embed/XStorage.hpp>
#include <com/sun/star/embed/ElementModes.hpp>
@@ -116,17 +119,21 @@ namespace
m_nODF = nTmp;
}
#ifdef _WIN32
constexpr std::u16string_view aGUIServers[] = { u"Gpg4win\\kleopatra.exe",
u"Gpg4win\\bin\\kleopatra.exe",
u"GNU\\GnuPG\\kleopatra.exe",
u"GNU\\GnuPG\\launch-gpa.exe",
u"GNU\\GnuPG\\gpa.exe",
u"GnuPG\\bin\\gpa.exe",
u"GNU\\GnuPG\\bin\\kleopatra.exe",
u"GNU\\GnuPG\\bin\\launch-gpa.exe",
u"GNU\\GnuPG\\bin\\gpa.exe"};
std::vector<std::u16string_view> aGUIServers
= { u"Gpg4win\\kleopatra.exe",
u"Gpg4win\\bin\\kleopatra.exe",
u"GNU\\GnuPG\\kleopatra.exe",
u"GNU\\GnuPG\\launch-gpa.exe",
u"GNU\\GnuPG\\gpa.exe",
u"GnuPG\\bin\\gpa.exe",
u"GNU\\GnuPG\\bin\\kleopatra.exe",
u"GNU\\GnuPG\\bin\\launch-gpa.exe",
u"GNU\\GnuPG\\bin\\gpa.exe",
officecfg::Office::Common::Security::Scripting::CertMgrPath::get() };
#else
constexpr std::u16string_view aGUIServers[] = { u"kleopatra", u"seahorse", u"gpa", u"kgpg" };
std::vector<std::u16string_view> aGUIServers
= { u"kleopatra", u"seahorse", u"gpa", u"kgpg",
officecfg::Office::Common::Security::Scripting::CertMgrPath::get() };
#endif
}
@@ -216,9 +223,9 @@ DigitalSignaturesDialog::DigitalSignaturesDialog(
m_xStartCertMgrBtn->hide();
}
if ( !IsThereCertificateMgr() )
if (!IsThereCertificateMgr())
{
m_xStartCertMgrBtn->hide();
m_xStartCertMgrBtn->set_sensitive(false);
}
}
@@ -311,23 +318,19 @@ bool DigitalSignaturesDialog::canAddRemove()
//It the user presses 'Add' or 'Remove' several times then, then the warning
//is shown every time until the user presses 'OK'. From then on, the warning
//is not displayed anymore as long as the signatures dialog is alive.
std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
VclMessageType::Question, VclButtonsType::YesNo,
XsResId(STR_XMLSECDLG_QUERY_REMOVEDOCSIGNBEFORESIGN)));
std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(
m_xDialog.get(), VclMessageType::Question, VclButtonsType::YesNo,
XsResId(STR_XMLSECDLG_QUERY_REMOVEDOCSIGNBEFORESIGN)));
if (xBox->run() == RET_NO)
ret = false;
else
m_bWarningShowSignMacro = true;
}
}
return ret;
}
bool DigitalSignaturesDialog::canAdd()
{
return canAddRemove();
}
bool DigitalSignaturesDialog::canAdd() { return canAddRemove(); }
bool DigitalSignaturesDialog::canRemove()
{
@@ -492,10 +495,11 @@ IMPL_LINK_NOARG(DigitalSignaturesDialog, RemoveButtonHdl, weld::Button&, void)
}
}
bool DigitalSignaturesDialog::IsThereCertificateMgr()
bool DigitalSignaturesDialog::GetPathAllOS(OUString& aPath)
{
#ifdef _WIN32
static const OUString aPath = [] {
aPath = []
{
sal::systools::CoTaskMemAllocated<wchar_t> sPath;
HRESULT hr
= SHGetKnownFolderPath(FOLDERID_ProgramFilesX86, KF_FLAG_DEFAULT, nullptr, &sPath);
@@ -509,77 +513,91 @@ bool DigitalSignaturesDialog::IsThereCertificateMgr()
const char* cPath = getenv("PATH");
if (!cPath)
return false;
OUString aPath(cPath, strlen(cPath), osl_getThreadTextEncoding());
aPath = OUString(cPath, strlen(cPath), osl_getThreadTextEncoding());
#endif
return (!aPath.isEmpty());
}
OUString sFoundGUIServer, sExecutable;
void DigitalSignaturesDialog::GetCertificateManager(OUString& aPath, OUString& sExecutable,
OUString& sFoundGUIServer)
{
aGUIServers.pop_back();
aGUIServers.push_back(officecfg::Office::Common::Security::Scripting::CertMgrPath::get());
for ( auto const &rServer : aGUIServers )
for (auto it = aGUIServers.rbegin(); it != aGUIServers.rend(); ++it)
{
osl::FileBase::RC searchError = osl::File::searchFileURL(OUString(rServer), aPath, sFoundGUIServer );
const auto& rServer = *it;
if (rServer.empty())
continue;
bool bValidSetMgr = (it == aGUIServers.rbegin() && rServer.size() > 0);
sal_Int32 nLastBackslashIndex = -1;
if (bValidSetMgr)
{
#ifdef _WIN32
nLastBackslashIndex = rServer.find_last_of('\\');
#else
nLastBackslashIndex = rServer.find_last_of('/');
#endif
}
osl::FileBase::RC searchError = osl::File::searchFileURL(
OUString(bValidSetMgr ? rServer.substr(nLastBackslashIndex + 1) : rServer), aPath,
sFoundGUIServer);
if (searchError == osl::FileBase::E_None)
{
osl::File::getSystemPathFromFileURL( sFoundGUIServer, sExecutable );
osl::File::getSystemPathFromFileURL(sFoundGUIServer, sExecutable);
if (it != aGUIServers.rbegin())
{
std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
comphelper::ConfigurationChanges::create());
officecfg::Office::Common::Security::Scripting::CertMgrPath::set(sExecutable,
pBatch);
pBatch->commit();
}
break;
}
}
}
return ( !sExecutable.isEmpty() );
bool DigitalSignaturesDialog::IsThereCertificateMgr()
{
OUString aPath, sFoundGUIServer, sExecutable;
if (!GetPathAllOS(aPath))
return false;
GetCertificateManager(aPath, sExecutable, sFoundGUIServer);
return (!sExecutable.isEmpty());
}
IMPL_LINK_NOARG(DigitalSignaturesDialog, CertMgrButtonHdl, weld::Button&, void)
{
#ifdef _WIN32
// FIXME: call GpgME::dirInfo("bindir") somewhere in
// SecurityEnvironmentGpg or whatnot
// FIXME: perhaps poke GpgME for uiserver, and hope it returns something useful?
static const OUString aPath = [] {
sal::systools::CoTaskMemAllocated<wchar_t> sPath;
HRESULT hr
= SHGetKnownFolderPath(FOLDERID_ProgramFilesX86, KF_FLAG_DEFAULT, nullptr, &sPath);
if (SUCCEEDED(hr))
return OUString(o3tl::toU(sPath));
return OUString();
}();
if (aPath.isEmpty())
OUString aPath, sFoundGUIServer, sExecutable;
if (!GetPathAllOS(aPath))
return;
#else
const char* cPath = getenv("PATH");
if (!cPath)
return;
OUString aPath(cPath, strlen(cPath), osl_getThreadTextEncoding());
#endif
OUString sFoundGUIServer, sExecutable;
GetCertificateManager(aPath, sExecutable, sFoundGUIServer);
for ( auto const &rServer : aGUIServers)
if (!sExecutable.isEmpty())
{
osl::FileBase::RC searchError = osl::File::searchFileURL(OUString(rServer), aPath, sFoundGUIServer );
if (searchError == osl::FileBase::E_None)
{
osl::File::getSystemPathFromFileURL( sFoundGUIServer, sExecutable );
break;
}
uno::Reference<uno::XComponentContext> xContext
= ::comphelper::getProcessComponentContext();
uno::Reference<css::system::XSystemShellExecute> xSystemShell(
css::system::SystemShellExecute::create(xContext));
xSystemShell->execute(sExecutable, OUString(),
css::system::SystemShellExecuteFlags::DEFAULTS);
}
if ( !sExecutable.isEmpty() )
{
uno::Reference< uno::XComponentContext > xContext =
::comphelper::getProcessComponentContext();
uno::Reference< css::system::XSystemShellExecute > xSystemShell(
css::system::SystemShellExecute::create(xContext) );
OUString sDialogText = (sExecutable.isEmpty() ?
XsResId(STR_XMLSECDLG_NO_CERT_MANAGER) : XsResId(STR_XMLSECDLG_OPENED_CRTMGR) + sExecutable);
xSystemShell->execute( sExecutable, OUString(),
css::system::SystemShellExecuteFlags::DEFAULTS );
}
else
{
std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
VclMessageType::Info, VclButtonsType::Ok,
XsResId(STR_XMLSECDLG_NO_CERT_MANAGER)));
xInfoBox->run();
}
std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(
m_xDialog.get(), VclMessageType::Info, VclButtonsType::Ok,
sDialogText));
xInfoBox->run();
}
IMPL_LINK_NOARG(DigitalSignaturesDialog, StartVerifySignatureHdl, LinkParamNone*, bool)