tdf#159307 add default macOS certificate manager applications
Most, if not all, of the Linux certificate manager applications are
not available on macOS so create a separate list for macOS.
Also, fix uncloseable windows due to uncaught exceptions thrown by
XSystemShellExecute::execute(). Failure to catch such exceptions
would cause the document window to be uncloseable and the application
to be unquittable.
Change-Id: I9bc6dc9c6c9d054252b634874045cb066023214a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162887
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index f2bb372..d717ec9 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
@@ -74,6 +74,10 @@
#include <Shlobj.h>
#endif
#if defined MACOSX
#include <sys/stat.h>
#endif
using namespace comphelper;
using namespace css::security;
using namespace css::uno;
@@ -121,6 +125,10 @@ namespace
u"GNU\\GnuPG\\bin\\kleopatra.exe",
u"GNU\\GnuPG\\bin\\launch-gpa.exe",
u"GNU\\GnuPG\\bin\\gpa.exe"};
#elif defined MACOSX
constexpr std::u16string_view aGUIServers[]
= { u"/Applications/GPG Keychain.app",
u"/System/Applications/Utilities/Keychain Access.app"};
#else
constexpr std::u16string_view aGUIServers[]
= { u"kleopatra", u"seahorse", u"gpa", u"kgpg"};
@@ -175,12 +183,34 @@ void GetCertificateManager(OUString& sExecutable)
for (const auto& rServer: aGUIServers)
{
osl::FileBase::RC searchError = osl::File::searchFileURL(
OUString(rServer), aPath,
aFoundGUIServer);
if (searchError == osl::FileBase::E_None)
bool bSetCertMgrPath = false;
#ifdef MACOSX
// On macOS, the list of default certificate manager applications
// includes absolute paths so check if the path exists and is a
// directory
if (rServer.starts_with('/'))
{
osl::File::getSystemPathFromFileURL(aFoundGUIServer, sExecutable);
OString aSysPath = OUString(rServer).toUtf8();
if (struct stat st; stat(aSysPath.getStr(), &st) == 0 && S_ISDIR(st.st_mode))
{
bSetCertMgrPath = true;
sExecutable = rServer;
}
}
#endif
if (!bSetCertMgrPath)
{
osl::FileBase::RC searchError = osl::File::searchFileURL(
OUString(rServer), aPath,
aFoundGUIServer);
if (searchError == osl::FileBase::E_None && osl::File::getSystemPathFromFileURL(aFoundGUIServer, sExecutable) == osl::FileBase::E_None)
bSetCertMgrPath = true;
}
if (bSetCertMgrPath)
{
std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
comphelper::ConfigurationChanges::create());
officecfg::Office::Common::Security::Scripting::CertMgrPath::set(sExecutable,
@@ -558,8 +588,22 @@ IMPL_LINK_NOARG(DigitalSignaturesDialog, CertMgrButtonHdl, weld::Button&, void)
uno::Reference<css::system::XSystemShellExecute> xSystemShell(
css::system::SystemShellExecute::create(xContext));
xSystemShell->execute(sExecutable, OUString(),
css::system::SystemShellExecuteFlags::DEFAULTS);
try
{
xSystemShell->execute(sExecutable, OUString(),
css::system::SystemShellExecuteFlags::DEFAULTS);
}
catch (...)
{
// Related tdf#159307 fix uncloseable windows due to uncaught exception
// XSystemShellExecute::execute() throws an exception for a variety
// of common error conditions such as files or directories that
// are non-existent or non-executable. Failure to catch such
// exceptions would cause the document window to be uncloseable
// and the application to be unquittable.
TOOLS_WARN_EXCEPTION( "xmlsecurity.dialogs", "executable failed!" );
sExecutable = OUString();
}
}
OUString sDialogText = (sExecutable.isEmpty() ?