зеркало из https://github.com/mozilla/gecko-dev.git
Make PSM make sure to shut down NSS before trying to start it up with theinitial profile on app startup. Fix leak of one of the user modules that waspreventing a clean shutdown. Bug 379582, r=rrelyea, kaie, sr=biesi.
This commit is contained in:
Родитель
383c82c5d9
Коммит
76c4fecf5f
|
@ -770,6 +770,7 @@ nsNSSComponent::InstallLoadableRoots()
|
||||||
|
|
||||||
if (RootsModule) {
|
if (RootsModule) {
|
||||||
// found a module, no need to try other directories
|
// found a module, no need to try other directories
|
||||||
|
SECMOD_DestroyModule(RootsModule);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1863,69 +1864,34 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic,
|
||||||
const PRUnichar *someData)
|
const PRUnichar *someData)
|
||||||
{
|
{
|
||||||
if (nsCRT::strcmp(aTopic, PROFILE_APPROVE_CHANGE_TOPIC) == 0) {
|
if (nsCRT::strcmp(aTopic, PROFILE_APPROVE_CHANGE_TOPIC) == 0) {
|
||||||
if (mShutdownObjectList->isUIActive()) {
|
DoProfileApproveChange(aSubject);
|
||||||
ShowAlert(ai_crypto_ui_active);
|
|
||||||
nsCOMPtr<nsIProfileChangeStatus> status = do_QueryInterface(aSubject);
|
|
||||||
if (status) {
|
|
||||||
status->VetoChange();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (nsCRT::strcmp(aTopic, PROFILE_CHANGE_TEARDOWN_TOPIC) == 0) {
|
else if (nsCRT::strcmp(aTopic, PROFILE_CHANGE_TEARDOWN_TOPIC) == 0) {
|
||||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("in PSM code, receiving change-teardown\n"));
|
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("in PSM code, receiving change-teardown\n"));
|
||||||
|
DoProfileChangeTeardown(aSubject);
|
||||||
PRBool callVeto = PR_FALSE;
|
|
||||||
|
|
||||||
if (!mShutdownObjectList->ifPossibleDisallowUI()) {
|
|
||||||
callVeto = PR_TRUE;
|
|
||||||
ShowAlert(ai_crypto_ui_active);
|
|
||||||
}
|
|
||||||
else if (mShutdownObjectList->areSSLSocketsActive()) {
|
|
||||||
callVeto = PR_TRUE;
|
|
||||||
ShowAlert(ai_sockets_still_active);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (callVeto) {
|
|
||||||
nsCOMPtr<nsIProfileChangeStatus> status = do_QueryInterface(aSubject);
|
|
||||||
if (status) {
|
|
||||||
status->VetoChange();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (nsCRT::strcmp(aTopic, PROFILE_CHANGE_TEARDOWN_VETO_TOPIC) == 0) {
|
else if (nsCRT::strcmp(aTopic, PROFILE_CHANGE_TEARDOWN_VETO_TOPIC) == 0) {
|
||||||
mShutdownObjectList->allowUI();
|
mShutdownObjectList->allowUI();
|
||||||
}
|
}
|
||||||
else if (nsCRT::strcmp(aTopic, PROFILE_BEFORE_CHANGE_TOPIC) == 0) {
|
else if (nsCRT::strcmp(aTopic, PROFILE_BEFORE_CHANGE_TOPIC) == 0) {
|
||||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("receiving profile change topic\n"));
|
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("receiving profile change topic\n"));
|
||||||
NS_ASSERTION(mIsNetworkDown, "nsNSSComponent relies on profile manager to wait for synchronous shutdown of all network activity");
|
DoProfileBeforeChange(aSubject);
|
||||||
|
|
||||||
PRBool needsCleanup = PR_TRUE;
|
|
||||||
|
|
||||||
{
|
|
||||||
nsAutoLock lock(mutex);
|
|
||||||
|
|
||||||
if (!mNSSInitialized) {
|
|
||||||
// Make sure we don't try to cleanup if we have already done so.
|
|
||||||
// This makes sure we behave safely, in case we are notified
|
|
||||||
// multiple times.
|
|
||||||
needsCleanup = PR_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StopCRLUpdateTimer();
|
|
||||||
|
|
||||||
if (needsCleanup) {
|
|
||||||
if (NS_FAILED(ShutdownNSS())) {
|
|
||||||
nsCOMPtr<nsIProfileChangeStatus> status = do_QueryInterface(aSubject);
|
|
||||||
if (status) {
|
|
||||||
status->ChangeFailed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mShutdownObjectList->allowUI();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (nsCRT::strcmp(aTopic, PROFILE_AFTER_CHANGE_TOPIC) == 0) {
|
else if (nsCRT::strcmp(aTopic, PROFILE_AFTER_CHANGE_TOPIC) == 0) {
|
||||||
|
if (someData && NS_LITERAL_STRING("startup").Equals(someData)) {
|
||||||
|
// The application is initializing against a known profile directory for
|
||||||
|
// the first time during process execution.
|
||||||
|
// However, earlier code execution might have already triggered NSS init.
|
||||||
|
// We must ensure that NSS gets shut down prior to any attempt to init
|
||||||
|
// it again. We use the same cleanup functionality used when switching
|
||||||
|
// profiles. The order of function calls must correspond to the order
|
||||||
|
// of notifications sent by Profile Manager (nsProfile).
|
||||||
|
DoProfileApproveChange(aSubject);
|
||||||
|
DoProfileChangeNetTeardown();
|
||||||
|
DoProfileChangeTeardown(aSubject);
|
||||||
|
DoProfileBeforeChange(aSubject);
|
||||||
|
DoProfileChangeNetRestore();
|
||||||
|
}
|
||||||
|
|
||||||
PRBool needsInit = PR_TRUE;
|
PRBool needsInit = PR_TRUE;
|
||||||
|
|
||||||
|
@ -2021,23 +1987,11 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic,
|
||||||
}
|
}
|
||||||
else if (nsCRT::strcmp(aTopic, PROFILE_CHANGE_NET_TEARDOWN_TOPIC) == 0) {
|
else if (nsCRT::strcmp(aTopic, PROFILE_CHANGE_NET_TEARDOWN_TOPIC) == 0) {
|
||||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("receiving network teardown topic\n"));
|
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("receiving network teardown topic\n"));
|
||||||
if (mSSLThread)
|
DoProfileChangeNetTeardown();
|
||||||
mSSLThread->requestExit();
|
|
||||||
if (mCertVerificationThread)
|
|
||||||
mCertVerificationThread->requestExit();
|
|
||||||
mIsNetworkDown = PR_TRUE;
|
|
||||||
}
|
}
|
||||||
else if (nsCRT::strcmp(aTopic, PROFILE_CHANGE_NET_RESTORE_TOPIC) == 0) {
|
else if (nsCRT::strcmp(aTopic, PROFILE_CHANGE_NET_RESTORE_TOPIC) == 0) {
|
||||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("receiving network restore topic\n"));
|
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("receiving network restore topic\n"));
|
||||||
delete mSSLThread;
|
DoProfileChangeNetRestore();
|
||||||
mSSLThread = new nsSSLThread();
|
|
||||||
if (mSSLThread)
|
|
||||||
mSSLThread->startThread();
|
|
||||||
delete mCertVerificationThread;
|
|
||||||
mCertVerificationThread = new nsCertVerificationThread();
|
|
||||||
if (mCertVerificationThread)
|
|
||||||
mCertVerificationThread->startThread();
|
|
||||||
mIsNetworkDown = PR_FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -2232,6 +2186,95 @@ nsNSSComponent::GetErrorMessage(nsresult aXPCOMErrorCode, nsAString &aErrorMessa
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsNSSComponent::DoProfileApproveChange(nsISupports* aSubject)
|
||||||
|
{
|
||||||
|
if (mShutdownObjectList->isUIActive()) {
|
||||||
|
ShowAlert(ai_crypto_ui_active);
|
||||||
|
nsCOMPtr<nsIProfileChangeStatus> status = do_QueryInterface(aSubject);
|
||||||
|
if (status) {
|
||||||
|
status->VetoChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsNSSComponent::DoProfileChangeNetTeardown()
|
||||||
|
{
|
||||||
|
if (mSSLThread)
|
||||||
|
mSSLThread->requestExit();
|
||||||
|
if (mCertVerificationThread)
|
||||||
|
mCertVerificationThread->requestExit();
|
||||||
|
mIsNetworkDown = PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsNSSComponent::DoProfileChangeTeardown(nsISupports* aSubject)
|
||||||
|
{
|
||||||
|
PRBool callVeto = PR_FALSE;
|
||||||
|
|
||||||
|
if (!mShutdownObjectList->ifPossibleDisallowUI()) {
|
||||||
|
callVeto = PR_TRUE;
|
||||||
|
ShowAlert(ai_crypto_ui_active);
|
||||||
|
}
|
||||||
|
else if (mShutdownObjectList->areSSLSocketsActive()) {
|
||||||
|
callVeto = PR_TRUE;
|
||||||
|
ShowAlert(ai_sockets_still_active);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callVeto) {
|
||||||
|
nsCOMPtr<nsIProfileChangeStatus> status = do_QueryInterface(aSubject);
|
||||||
|
if (status) {
|
||||||
|
status->VetoChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsNSSComponent::DoProfileBeforeChange(nsISupports* aSubject)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(mIsNetworkDown, "nsNSSComponent relies on profile manager to wait for synchronous shutdown of all network activity");
|
||||||
|
|
||||||
|
PRBool needsCleanup = PR_TRUE;
|
||||||
|
|
||||||
|
{
|
||||||
|
nsAutoLock lock(mutex);
|
||||||
|
|
||||||
|
if (!mNSSInitialized) {
|
||||||
|
// Make sure we don't try to cleanup if we have already done so.
|
||||||
|
// This makes sure we behave safely, in case we are notified
|
||||||
|
// multiple times.
|
||||||
|
needsCleanup = PR_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StopCRLUpdateTimer();
|
||||||
|
|
||||||
|
if (needsCleanup) {
|
||||||
|
if (NS_FAILED(ShutdownNSS())) {
|
||||||
|
nsCOMPtr<nsIProfileChangeStatus> status = do_QueryInterface(aSubject);
|
||||||
|
if (status) {
|
||||||
|
status->ChangeFailed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mShutdownObjectList->allowUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsNSSComponent::DoProfileChangeNetRestore()
|
||||||
|
{
|
||||||
|
delete mSSLThread;
|
||||||
|
mSSLThread = new nsSSLThread();
|
||||||
|
if (mSSLThread)
|
||||||
|
mSSLThread->startThread();
|
||||||
|
delete mCertVerificationThread;
|
||||||
|
mCertVerificationThread = new nsCertVerificationThread();
|
||||||
|
if (mCertVerificationThread)
|
||||||
|
mCertVerificationThread->startThread();
|
||||||
|
mIsNetworkDown = PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------
|
//---------------------------------------------
|
||||||
// Implementing nsICryptoHash
|
// Implementing nsICryptoHash
|
||||||
//---------------------------------------------
|
//---------------------------------------------
|
||||||
|
|
|
@ -257,6 +257,15 @@ private:
|
||||||
nsresult PostCRLImportEvent(const nsCSubstring &urlString, nsIStreamListener *psmDownloader);
|
nsresult PostCRLImportEvent(const nsCSubstring &urlString, nsIStreamListener *psmDownloader);
|
||||||
nsresult getParamsForNextCrlToDownload(nsAutoString *url, PRTime *time, nsAutoString *key);
|
nsresult getParamsForNextCrlToDownload(nsAutoString *url, PRTime *time, nsAutoString *key);
|
||||||
nsresult DispatchEventToWindow(nsIDOMWindow *domWin, const nsAString &eventType, const nsAString &token);
|
nsresult DispatchEventToWindow(nsIDOMWindow *domWin, const nsAString &eventType, const nsAString &token);
|
||||||
|
|
||||||
|
// Methods that we use to handle the profile change notifications (and to
|
||||||
|
// synthesize a full profile change when we're just doing a profile startup):
|
||||||
|
void DoProfileApproveChange(nsISupports* aSubject);
|
||||||
|
void DoProfileChangeNetTeardown();
|
||||||
|
void DoProfileChangeTeardown(nsISupports* aSubject);
|
||||||
|
void DoProfileBeforeChange(nsISupports* aSubject);
|
||||||
|
void DoProfileChangeNetRestore();
|
||||||
|
|
||||||
PRLock *mutex;
|
PRLock *mutex;
|
||||||
|
|
||||||
nsCOMPtr<nsIScriptSecurityManager> mScriptSecurityManager;
|
nsCOMPtr<nsIScriptSecurityManager> mScriptSecurityManager;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче