summaryrefslogtreecommitdiff
path: root/xmlsecurity
diff options
context:
space:
mode:
authorJan-Marek Glogowski <jan-marek.glogowski@extern.cib.de>2019-10-22 17:56:15 +0000
committerJan-Marek Glogowski <glogow@fbihome.de>2020-07-03 17:13:12 +0200
commitb1d0d0cf866ac7235cd23ff862a8f2e9085148d8 (patch)
treee5cb49b7fad2b5b072e58ebc3a9071734d2270a0 /xmlsecurity
parent47c098e5760537e8c43a92c9dbe16ace3902a19d (diff)
[API CHANGE] Move NSS profile handling into NSS service
While developing the patchset for tdf#127909, I broke the certificate path dialog, because I wasn't aware, that the NSSInitializer service has to use the same logic to auto- select the users profile, then the dialog. So currently you have to keep the complex service and dialog auto-select logic in sync. To prevent this error, this moves all the profile auto-selection and enumeration into the NSSInitializer service. What I also stumbled over is the particular lifecycle of the NSS library initialization in the NSS service. This is just done, when the first user calls some crypto function. As a result it's actually possible to change the path setting without restarting LibreOffice. But since the NSS deninitialization is run as an atexit handler, this setting can't be changed after the init. What is currently missing is any indication inside the dialog of the currently active NSS setting in comparison to any later user selection, if the user doesn't restart LibreOffice as requested. Change-Id: I886962777958c363abeb0ec91fc8a35cbd39eb98 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97668 Tested-by: Jenkins Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
Diffstat (limited to 'xmlsecurity')
-rw-r--r--xmlsecurity/source/xmlsec/nss/nssinitializer.cxx162
-rw-r--r--xmlsecurity/source/xmlsec/nss/nssinitializer.hxx13
2 files changed, 141 insertions, 34 deletions
diff --git a/xmlsecurity/source/xmlsec/nss/nssinitializer.cxx b/xmlsecurity/source/xmlsec/nss/nssinitializer.cxx
index d64ea10a05a0..c43abe14569f 100644
--- a/xmlsecurity/source/xmlsec/nss/nssinitializer.cxx
+++ b/xmlsecurity/source/xmlsec/nss/nssinitializer.cxx
@@ -21,6 +21,7 @@
#include <com/sun/star/mozilla/XMozillaBootstrap.hpp>
#include <com/sun/star/xml/crypto/DigestID.hpp>
#include <com/sun/star/xml/crypto/CipherID.hpp>
+#include <com/sun/star/xml/crypto/NSSInitializer.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <cppuhelper/supportsservice.hxx>
#include <officecfg/Office/Common.hxx>
@@ -33,6 +34,7 @@
#include <tools/diagnose_ex.h>
#include <unotools/tempfile.hxx>
#include <salhelper/singletonref.hxx>
+#include <comphelper/sequence.hxx>
#include <nss/nssinitializer.hxx>
@@ -144,8 +146,35 @@ void deleteRootsModule()
}
}
-OString getMozillaCurrentProfile( const css::uno::Reference< css::uno::XComponentContext > &rxContext )
+#endif
+
+bool lcl_pathExists(const OUString& sPath)
{
+ if (sPath.isEmpty())
+ return false;
+
+ ::osl::DirectoryItem aPathItem;
+ OUString sURL;
+ osl::FileBase::getFileURLFromSystemPath(sPath, sURL);
+ if (::osl::FileBase::E_None == ::osl::DirectoryItem::get(sURL, aPathItem))
+ {
+ ::osl::FileStatus aStatus = osl_FileStatus_Mask_Validate;
+ if (::osl::FileBase::E_None == aPathItem.getFileStatus(aStatus))
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace
+
+OUString ONSSInitializer::getMozillaCurrentProfile(const css::uno::Reference< css::uno::XComponentContext > &rxContext, bool bSetActive)
+{
+ if (m_bIsNSSinitialized)
+ return m_sNSSPath;
+ if (bSetActive)
+ m_bIsNSSinitialized = true;
+
// first, try to get the profile from "MOZILLA_CERTIFICATE_FOLDER"
const char* pEnv = getenv("MOZILLA_CERTIFICATE_FOLDER");
if (pEnv)
@@ -153,30 +182,33 @@ OString getMozillaCurrentProfile( const css::uno::Reference< css::uno::XComponen
SAL_INFO(
"xmlsecurity.xmlsec",
"Using Mozilla profile from MOZILLA_CERTIFICATE_FOLDER=" << pEnv);
- return pEnv;
+ m_sNSSPath = OStringToOUString(pEnv, osl_getThreadTextEncoding());
}
// second, try to get saved user-preference
- try
+ if (m_sNSSPath.isEmpty())
{
- OUString sUserSetCertPath =
- officecfg::Office::Common::Security::Scripting::CertDir::get().value_or(OUString());
+ try
+ {
+ OUString sUserSetCertPath =
+ officecfg::Office::Common::Security::Scripting::CertDir::get().value_or(OUString());
- if (!sUserSetCertPath.isEmpty())
+ if (lcl_pathExists(sUserSetCertPath))
+ {
+ SAL_INFO(
+ "xmlsecurity.xmlsec",
+ "Using Mozilla profile from /org.openoffice.Office.Common/"
+ "Security/Scripting/CertDir: " << sUserSetCertPath);
+ m_sNSSPath = sUserSetCertPath;
+ }
+ }
+ catch (const uno::Exception &)
{
- SAL_INFO(
- "xmlsecurity.xmlsec",
- "Using Mozilla profile from /org.openoffice.Office.Common/"
- "Security/Scripting/CertDir: " << sUserSetCertPath);
- return OUStringToOString(sUserSetCertPath, osl_getThreadTextEncoding());
+ TOOLS_WARN_EXCEPTION("xmlsecurity.xmlsec", "getMozillaCurrentProfile:");
}
}
- catch (const uno::Exception &)
- {
- TOOLS_WARN_EXCEPTION("xmlsecurity.xmlsec", "getMozillaCurrentProfile:");
- }
- // third, dig around to see if there's one available
+ // third, dig around to see if there's one default available
mozilla::MozillaProductType productTypes[3] = {
mozilla::MozillaProductType_Thunderbird,
mozilla::MozillaProductType_Firefox,
@@ -196,20 +228,95 @@ OString getMozillaCurrentProfile( const css::uno::Reference< css::uno::XComponen
if (!profile.isEmpty())
{
- OUString sProfilePath = xMozillaBootstrap->getProfilePath( productTypes[i], profile );
- SAL_INFO(
- "xmlsecurity.xmlsec",
- "Using Mozilla profile " << sProfilePath);
- return OUStringToOString(sProfilePath, osl_getThreadTextEncoding());
+ OUString sProfilePath = xMozillaBootstrap->getProfilePath(productTypes[i], profile);
+ if (m_sNSSPath.isEmpty())
+ {
+ SAL_INFO("xmlsecurity.xmlsec", "Using Mozilla profile " << sProfilePath);
+ m_sNSSPath = sProfilePath;
+ }
+ break;
}
}
}
- SAL_INFO("xmlsecurity.xmlsec", "No Mozilla profile found");
- return OString();
+ SAL_INFO_IF(m_sNSSPath.isEmpty(), "xmlsecurity.xmlsec", "No Mozilla profile found");
+ return m_sNSSPath;
}
-#endif
+css::uno::Sequence<css::xml::crypto::NSSProfile> SAL_CALL ONSSInitializer::getNSSProfiles()
+{
+ ONSSInitializer::getMozillaCurrentProfile(m_xContext);
+
+ std::vector<xml::crypto::NSSProfile> aProfileList;
+ aProfileList.reserve(10);
+
+ mozilla::MozillaProductType productTypes[3] = {
+ mozilla::MozillaProductType_Thunderbird,
+ mozilla::MozillaProductType_Firefox,
+ mozilla::MozillaProductType_Mozilla };
+
+ uno::Reference<uno::XInterface> xInstance = m_xContext->getServiceManager()->createInstanceWithContext("com.sun.star.mozilla.MozillaBootstrap", m_xContext);
+ OSL_ENSURE(xInstance.is(), "failed to create instance" );
+
+ uno::Reference<mozilla::XMozillaBootstrap> xMozillaBootstrap(xInstance,uno::UNO_QUERY);
+
+ if (xMozillaBootstrap.is())
+ {
+ for (int i=0; i<int(SAL_N_ELEMENTS(productTypes)); ++i)
+ {
+ uno::Sequence<OUString> aProductProfileList;
+ xMozillaBootstrap->getProfileList(productTypes[i], aProductProfileList);
+ for (const auto& sProfile : std::as_const(aProductProfileList))
+ aProfileList.push_back({sProfile, xMozillaBootstrap->getProfilePath(productTypes[i], sProfile), productTypes[i]});
+ }
+ }
+
+ OUString sUserSelect;
+ try
+ {
+ sUserSelect = officecfg::Office::Common::Security::Scripting::CertDir::get().value_or(OUString());;
+ if (!lcl_pathExists(sUserSelect))
+ sUserSelect = OUString();
+ }
+ catch (const uno::Exception &)
+ {
+ TOOLS_WARN_EXCEPTION("xmlsecurity.xmlsec", "getMozillaCurrentProfile:");
+ }
+ aProfileList.push_back({"MANUAL", sUserSelect, mozilla::MozillaProductType_Default});
+
+ const char* pEnv = getenv("MOZILLA_CERTIFICATE_FOLDER");
+ aProfileList.push_back({"MOZILLA_CERTIFICATE_FOLDER",
+ pEnv ? OStringToOUString(pEnv, osl_getThreadTextEncoding()) : OUString(),
+ mozilla::MozillaProductType_Default});
+
+ return comphelper::containerToSequence(aProfileList);
+}
+
+bool ONSSInitializer::m_bIsNSSinitialized = false;
+OUString ONSSInitializer::m_sNSSPath;
+
+OUString SAL_CALL ONSSInitializer::getNSSPath()
+{
+ ONSSInitializer::getMozillaCurrentProfile(m_xContext);
+ return m_sNSSPath;
+};
+
+sal_Bool SAL_CALL ONSSInitializer::getIsNSSinitialized()
+{
+ return m_bIsNSSinitialized;
+}
+
+ONSSInitializer::ONSSInitializer(const css::uno::Reference< css::uno::XComponentContext > &rxContext)
+ : m_xContext(rxContext)
+{
+}
+
+ONSSInitializer::ONSSInitializer()
+{
+}
+
+namespace
+{
//Older versions of Firefox (FF), for example FF2, and Thunderbird (TB) 2 write
//the roots certificate module (libnssckbi.so), which they use, into the
@@ -238,7 +345,7 @@ bool nsscrypto_initialize(css::uno::Reference<css::uno::XComponentContext> const
OString sCertDir;
#ifdef XMLSEC_CRYPTO_NSS
- sCertDir = getMozillaCurrentProfile(rxContext);
+ sCertDir = OUStringToOString(ONSSInitializer::getMozillaCurrentProfile(rxContext, true), osl_getThreadTextEncoding());
#else
(void) rxContext;
#endif
@@ -402,11 +509,6 @@ extern "C" void nsscrypto_finalize()
(*getInitNSSPrivate())->reset();
}
-ONSSInitializer::ONSSInitializer(
- const css::uno::Reference< css::uno::XComponentContext > &rxContext)
- :m_xContext( rxContext )
-{
-}
ONSSInitializer::~ONSSInitializer()
{
diff --git a/xmlsecurity/source/xmlsec/nss/nssinitializer.hxx b/xmlsecurity/source/xmlsec/nss/nssinitializer.hxx
index 7e1b7ff50537..2dcd821c020d 100644
--- a/xmlsecurity/source/xmlsec/nss/nssinitializer.hxx
+++ b/xmlsecurity/source/xmlsec/nss/nssinitializer.hxx
@@ -37,15 +37,22 @@ class ONSSInitializer : public cppu::WeakImplHelper
{
protected:
css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ static OUString m_sNSSPath;
+ static bool m_bIsNSSinitialized;
- ONSSInitializer()
- {}
+ ONSSInitializer();
public:
explicit ONSSInitializer(const css::uno::Reference<css::uno::XComponentContext> &rxContext);
virtual ~ONSSInitializer() override;
static bool initNSS( const css::uno::Reference< css::uno::XComponentContext > &rxContext );
+ static OUString getMozillaCurrentProfile(const css::uno::Reference< css::uno::XComponentContext > &rxContext, bool bSetActive = false);
+
+ /* XNSSInitializer */
+ virtual OUString SAL_CALL getNSSPath() override;
+ virtual sal_Bool SAL_CALL getIsNSSinitialized() override;
+ virtual css::uno::Sequence<css::xml::crypto::NSSProfile> SAL_CALL getNSSProfiles() override;
/* XDigestContextSupplier */
virtual css::uno::Reference< css::xml::crypto::XDigestContext > SAL_CALL getDigestContext( ::sal_Int32 nDigestID, const css::uno::Sequence< css::beans::NamedValue >& aParams ) override;
@@ -55,9 +62,7 @@ public:
/* XServiceInfo */
virtual OUString SAL_CALL getImplementationName() override;
-
virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
-
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
};