/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
const 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" if (OUString pEnv; osl_getEnvironment(u"MOZILLA_CERTIFICATE_FOLDER"_ustr.pData, &pEnv.pData) == osl_Process_E_None
&& !pEnv.isEmpty())
{
SAL_INFO( "xmlsecurity.xmlsec", "Using Mozilla profile from MOZILLA_CERTIFICATE_FOLDER=" << pEnv);
m_sNSSPath = pEnv;
}
// second, try to get saved user-preference if (m_sNSSPath.isEmpty())
{ try
{
OUString sUserSetCertPath =
officecfg::Office::Common::Security::Scripting::CertDir::get().value_or(OUString());
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 &)
{
TOOLS_WARN_EXCEPTION("xmlsecurity.xmlsec", "getMozillaCurrentProfile:");
}
}
// third, dig around to see if there's one default available
mozilla::MozillaProductType productTypes[3] = {
mozilla::MozillaProductType_Thunderbird,
mozilla::MozillaProductType_Firefox,
mozilla::MozillaProductType_Mozilla };
//Older versions of Firefox (FF), for example FF2, and Thunderbird (TB) 2 write //the roots certificate module (libnssckbi.so), which they use, into the //profile. This module will then already be loaded during NSS_Init (and the //other init functions). This fails in two cases. First, FF3 was used to create //the profile, or possibly used that profile before, and second the profile was //used on a different platform. // //Then one needs to add the roots module oneself. This should be done with //SECMOD_LoadUserModule rather than SECMOD_AddNewModule. The latter would write //the location of the roots module to the profile, which makes FF2 and TB2 use //it instead of their own module. // //When using SYSTEM_NSS then the libnss3.so lib is typically found in /usr/lib. //This folder may, however, NOT contain the roots certificate module. That is, //just providing the library name in SECMOD_LoadUserModule or //SECMOD_AddNewModule will FAIL to load the mozilla unless the LD_LIBRARY_PATH //contains an FF or TB installation. //ATTENTION: DO NOT call this function directly instead use initNSS //return true - whole initialization was successful //param out_nss_init = true: at least the NSS initialization (NSS_InitReadWrite //was successful and therefore NSS_Shutdown should be called when terminating. bool nsscrypto_initialize(css::uno::Reference<css::uno::XComponentContext> const & rxContext, bool & out_nss_init)
{ // this method must be called only once, no need for additional lock
OString sCertDir;
bool bSuccess = false; // there might be no profile if (!sCertDir.isEmpty())
{ if (sCertDir.indexOf(':') == -1) //might be env var with explicit prefix
{
OUString sCertDirURL;
osl::FileBase::getFileURLFromSystemPath(
OStringToOUString(sCertDir, osl_getThreadTextEncoding()),
sCertDirURL);
osl::DirectoryItem item; if (osl::FileBase::E_NOENT != osl::DirectoryItem::get(sCertDirURL + "/cert8.db", item) &&
osl::FileBase::E_NOENT == osl::DirectoryItem::get(sCertDirURL + "/cert9.db", item))
{
SAL_INFO("xmlsecurity.xmlsec", "nsscrypto_initialize: trying to avoid profile migration");
sCertDir = "dbm:" + sCertDir;
}
} if (NSS_InitReadWrite(sCertDir.getStr()) != SECSuccess)
{
SAL_INFO("xmlsecurity.xmlsec", "Initializing NSS with profile failed."); int errlen = PR_GetErrorTextLength(); if (errlen > 0)
{
std::unique_ptr<char[]> const error(newchar[errlen + 1]);
PR_GetErrorText(error.get());
SAL_INFO("xmlsecurity.xmlsec", error.get());
}
} else
{
bSuccess = true;
}
}
if (!bSuccess) // Try to create a database in temp dir
{
SAL_INFO("xmlsecurity.xmlsec", "Initializing NSS with a temporary profile.");
OUString rString = (*getInitNSSPrivate())->getTempDatabasePath();
if (NSS_InitReadWrite(rString.toUtf8().getStr()) != SECSuccess)
{
SAL_INFO("xmlsecurity.xmlsec", "Initializing NSS with a temporary profile."); int errlen = PR_GetErrorTextLength(); if(errlen > 0)
{
std::unique_ptr<char[]> const error(newchar[errlen + 1]);
PR_GetErrorText(error.get());
SAL_INFO("xmlsecurity.xmlsec", error.get());
} returnfalse;
}
}
// Initialize and set empty password if needed // note: it's possible that the first NSS_InitReadWrite() succeeds by // creating a new DB; in this case it may also be necessary to call // PK11_InitPin()
PK11SlotInfo* pSlot = PK11_GetInternalKeySlot(); if (pSlot)
{ if (PK11_NeedUserInit(pSlot))
PK11_InitPin(pSlot, nullptr, nullptr);
PK11_FreeSlot(pSlot);
}
#ifdefined SYSTEM_NSS || defined IOS // The statically linked nss on iOS acts as a "system" nss in this regards if (!SECMOD_HasRootCerts()) #endif
{
deleteRootsModule();
#ifdef IOS // Use statically linked NSS
OUString rootModulePath("NSSCKBI");
if (true) #else #ifdefined SYSTEM_NSS || defined ANDROID
OUString rootModule(u"libnssckbi" SAL_DLLEXTENSION ""_ustr); #else
OUString rootModule("${LO_LIB_DIR}/libnssckbi" SAL_DLLEXTENSION); #endif
::rtl::Bootstrap::expandMacros(rootModule);
// must be extern "C" because we pass the function pointer to atexit extern"C"void nsscrypto_finalize()
{
SECMODModule *RootsModule = SECMOD_FindModule(ROOT_CERTS);
if (RootsModule)
{
if (SECSuccess == SECMOD_UnloadUserModule(RootsModule))
{
SAL_INFO("xmlsecurity.xmlsec", "Unloaded module \"" ROOT_CERTS "\".");
} else
{
SAL_INFO("xmlsecurity.xmlsec", "Failed unloading module \"" ROOT_CERTS "\".");
}
SECMOD_DestroyModule(RootsModule);
} else
{
SAL_INFO("xmlsecurity.xmlsec", "Unloading module \"" ROOT_CERTS "\" failed because it was not found.");
}
PK11_LogoutAll();
(void)NSS_Shutdown();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.