diff options
Diffstat (limited to 'xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx')
-rw-r--r-- | xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx | 77 |
1 files changed, 65 insertions, 12 deletions
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx index 3cd13c6060..8349a58a31 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,12 @@ 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"/Applications/Trusted Key Manager.app", // tdf#147291 + u"/Applications/SCinterface/scManager.app", // tdf#147291 + u"/System/Applications/Utilities/Keychain Access.app"}; #else constexpr std::u16string_view aGUIServers[] = { u"kleopatra", u"seahorse", u"gpa", u"kgpg"}; @@ -154,26 +164,55 @@ void GetCertificateManager(OUString& sExecutable) OUString aCetMgrConfig = officecfg::Office::Common::Security::Scripting::CertMgrPath::get(); if (!aCetMgrConfig.isEmpty()) { + if (aCetMgrConfig.indexOf('/') != -1 #ifdef _WIN32 - sal_Int32 nLastBackslashIndex = aCetMgrConfig.lastIndexOf('\\'); -#else - sal_Int32 nLastBackslashIndex = aCetMgrConfig.lastIndexOf('/'); + || aCetMgrConfig.indexOf('\\') != -1 #endif + ) + { + sExecutable = aCetMgrConfig; + return; + } osl::FileBase::RC searchError = osl::File::searchFileURL( - aCetMgrConfig.copy(0, nLastBackslashIndex + 1), aPath, + aCetMgrConfig, aPath, aFoundGUIServer); if (searchError == osl::FileBase::E_None) + { + osl::File::getSystemPathFromFileURL(aFoundGUIServer, sExecutable); return; + } } 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('/')) + { + 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) { - osl::File::getSystemPathFromFileURL(aFoundGUIServer, sExecutable); std::shared_ptr<comphelper::ConfigurationChanges> pBatch( comphelper::ConfigurationChanges::create()); officecfg::Office::Common::Security::Scripting::CertMgrPath::set(sExecutable, @@ -470,7 +509,7 @@ IMPL_LINK_NOARG(DigitalSignaturesDialog, AddButtonHdl, weld::Button&, void) if (DocumentSignatureHelper::CanSignWithGPG(maSignatureManager.getStore(), m_sODFVersion)) xSecContexts.push_back(maSignatureManager.getGpgSecurityContext()); - CertificateChooser* aChooser = CertificateChooser::getInstance(m_xDialog.get(), std::move(xSecContexts), UserAction::Sign); + std::unique_ptr<CertificateChooser> aChooser = CertificateChooser::getInstance(m_xDialog.get(), std::move(xSecContexts), UserAction::Sign); if (aChooser->run() == RET_OK) { sal_Int32 nSecurityId; @@ -551,8 +590,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() ? |