Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 616533 Details for
Bug 851089
SSL protocol errros in Thunderbird 17 should give feedback to the user
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
patch v9 for Mozilla 17
p-aurora-785426 (text/plain), 34.80 KB, created by
Kai Engert (:kaie) (inactive account)
on 2012-09-24 12:15:01 UTC
(
hide
)
Description:
patch v9 for Mozilla 17
Filename:
MIME Type:
Creator:
Kai Engert (:kaie) (inactive account)
Created:
2012-09-24 12:15:01 UTC
Size:
34.80 KB
patch
obsolete
>diff --git a/security/manager/ssl/public/Makefile.in b/security/manager/ssl/public/Makefile.in >--- a/security/manager/ssl/public/Makefile.in >+++ b/security/manager/ssl/public/Makefile.in >@@ -21,16 +21,17 @@ SDK_XPIDLSRCS = \ > nsIX509Cert.idl \ > nsIX509CertDB.idl \ > nsIX509CertValidity.idl \ > nsINSSVersion.idl \ > $(NULL) > > XPIDLSRCS = \ > nsISSLCertErrorDialog.idl \ >+ nsISSLErrorAction.idl \ > nsIBadCertListener2.idl \ > nsISSLErrorListener.idl \ > nsIIdentityInfo.idl \ > nsIAssociatedContentSecurity.idl \ > nsICertOverrideService.idl \ > nsIRecentBadCertsService.idl \ > nsIFormSigningDialog.idl \ > nsIX509Cert2.idl \ >diff --git a/security/manager/ssl/public/nsISSLErrorAction.idl b/security/manager/ssl/public/nsISSLErrorAction.idl >new file mode 100644 >--- /dev/null >+++ b/security/manager/ssl/public/nsISSLErrorAction.idl >@@ -0,0 +1,134 @@ >+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- >+ * >+ * 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/. */ >+ >+#include "nsISupports.idl" >+#include "nsISSLStatus.idl" >+#include "nsIX509Cert.idl" >+#include "nsIInterfaceRequestor.idl" >+ >+/** >+ * What shall happen if an error on a SSL/TLS socket occurrs? >+ * >+ * An application may have registered a socket-specific >+ * nsIBadCertListener2 (for problems with a certificate) >+ * or >+ * nsISSLErrorListener (for protocol errors) >+ * and might decide "suppress error message". >+ * >+ * This interface nsISSLErrorAction defines the fallback behaviour, >+ * for all of the following scenarios: >+ * - nsIBadCertListener2::notifyCertProblem or >+ * nsISSLErrorListener::notifySSLError says "don't suppress the error" >+ * - any potential equivalent listener decides "don't suppress the error" >+ * - no listener is installed at all >+ * >+ * In addition, this interface also defines whether or not the >+ * error should be logged as a message to the global error console. >+ * >+ * This interface is NOT implemented by Mozilla's shared platform code. >+ * >+ * The default fallback behaviour is implemented in the core >+ * SSL code (security/manager/ssl). >+ * >+ * Implementing this interface is optional. >+ * An application not implementing this interface will get the >+ * default fallback behaviour. >+ * >+ * An application that wants to override core's default behaviour shall >+ * provide an implementation of this interface with contract ID >+ * "@mozilla.org/nsSSLErrorAction;1" >+ * >+ * The core SSL platform code will read the implementation provided value >+ * of "attribute promptBehaviour" and will show or not show a prompt accordingly. >+ */ >+[scriptable, uuid(5a2da46e-9361-4afb-a457-95abe834b72e)] >+interface nsISSLErrorAction : nsISupports { >+ >+ /** >+ * If true the error will be logged to the error console. >+ */ >+ readonly attribute boolean logToConsole; >+ >+ /** >+ * Returns one of the behaviour constant values. >+ */ >+ readonly attribute short promptBehaviour; >+ >+ /** >+ * PROMPT_DEFAULT means: Use core's default behaviour. >+ * Returning this value is equivalent to not providing an implementation. >+ */ >+ const unsigned short PROMPT_DEFAULT = 0; >+ >+ /** >+ * PROMPT_ALLOWED means: Showing the fallback prompt is allowed. >+ */ >+ const unsigned short PROMPT_ALLOWED = 1; >+ >+ /** >+ * PROMPT_SUPPRESS means: Showing the fallback prompt is forbidden. >+ */ >+ const unsigned short PROMPT_SUPPRESS = 2; >+ >+ /** >+ * DETECT_DOCSHELL means: >+ * The core SSL code shall attempt an automatic detection of the >+ * SSL socket's context. >+ * >+ * If the socket is associated to a docshell, then it's assumed that >+ * the document shell will care for reporting of errors as part of the >+ * document presentation; suppress the fallback prompt. >+ * >+ * If the socket isn't associated to a docshell, >+ * then showing the fallback prompt is allowed >+ * >+ */ >+ const unsigned short DETECT_DOCSHELL = 3; >+ >+ /** >+ * Called if core security code decides that a SSL connection protocol error >+ * SHOULD be reported to the user. >+ * Only called if socket listeners didn't ask to suppress the error. >+ * >+ * @param suggestedMessage A plain text error message. >+ * @param hostName The error occurred when connecting to this hostName. >+ * @param port The error occurred when connecting to this port. >+ * @param error The code associated with the error. >+ * @param socketInfo A network communication context that can be used to obtain >+ * more information about the active connection. >+ */ >+ void executeProtocolErrorUserFeedback(in AString suggestedMessage, >+ in ACString hostName, >+ in int32_t port, >+ in int32_t error, >+ in nsIInterfaceRequestor socketInfo); >+ >+ /** >+ * Called if core security code decides that a problem with a site certificate >+ * SHOULD be reported to the user. >+ * Only called if socket listeners didn't ask to suppress the error. >+ * >+ * @param suggestedMessage A plain text error message. >+ * @param hostName The error occurred when connecting to this hostName. >+ * @param port The error occurred when connecting to this port. >+ * @param error The code associated with the error. >+ * @param status The SSL status object that describes the problem(s). >+ * @param cert The certificate that this error is about >+ * @param socketInfo A network communication context that can be used to obtain >+ * more information about the active connection. >+ */ >+ void executeCertErrorUserFeedback(in AString suggestedMessage, >+ in ACString hostName, >+ in int32_t port, >+ in int32_t error, >+ in nsISSLStatus status, >+ in nsIX509Cert cert, >+ in nsIInterfaceRequestor socketInfo); >+}; >+ >+%{C++ >+#define NS_SSLERRORACTION_CONTRACTID "@mozilla.org/nsSSLErrorAction;1" >+%} >diff --git a/security/manager/ssl/src/SSLServerCertVerification.cpp b/security/manager/ssl/src/SSLServerCertVerification.cpp >--- a/security/manager/ssl/src/SSLServerCertVerification.cpp >+++ b/security/manager/ssl/src/SSLServerCertVerification.cpp >@@ -97,16 +97,17 @@ > #include "SSLServerCertVerification.h" > #include "nsIBadCertListener2.h" > #include "nsICertOverrideService.h" > #include "nsIStrictTransportSecurityService.h" > #include "nsNSSComponent.h" > #include "nsNSSCleaner.h" > #include "nsRecentBadCerts.h" > #include "nsNSSIOLayer.h" >+#include "nsISSLCertErrorDialog.h" > > #include "mozilla/Assertions.h" > #include "nsIThreadPool.h" > #include "nsXPCOMCIDInternal.h" > #include "nsComponentManagerUtils.h" > #include "nsServiceManagerUtils.h" > #include "nsIConsoleService.h" > #include "PSMRunnable.h" >@@ -178,56 +179,81 @@ void StopSSLServerCertVerificationThread > gCertVerificationThreadPool->Shutdown(); > NS_RELEASE(gCertVerificationThreadPool); > } > } > > namespace { > > void >-LogInvalidCertError(TransportSecurityInfo *socketInfo, >- const nsACString &host, >- const nsACString &hostWithPort, >- PRInt32 port, >- PRErrorCode errorCode, >- ::mozilla::psm::SSLErrorMessageType errorMessageType, >- nsIX509Cert* ix509) >+nsHandleInvalidCertError(bool showPrompt, >+ bool logToConsole, >+ nsISSLErrorAction *errorActionHandler, >+ TransportSecurityInfo *socketInfo, >+ const nsACString &host, >+ const nsACString &hostWithPort, >+ PRInt32 port, >+ PRErrorCode errorCode, >+ ::mozilla::psm::SSLErrorMessageType errorMessageType, >+ nsIX509Cert* ix509) > { > nsString message; > socketInfo->GetErrorLogMessage(errorCode, errorMessageType, message); >+ if (message.IsEmpty()) >+ return; > >- if (!message.IsEmpty()) { >+ if (logToConsole) { > nsCOMPtr<nsIConsoleService> console; > console = do_GetService(NS_CONSOLESERVICE_CONTRACTID); > if (console) { > console->LogStringMessage(message.get()); > } > } >+ >+ if (!showPrompt) >+ return; >+ >+ if (errorActionHandler) { >+ nsPSMUITracker tracker; >+ if (!tracker.isUIForbidden()) { >+ nsCOMPtr<nsISSLStatus> status; >+ socketInfo->GetSSLStatus(getter_AddRefs(status)); >+ errorActionHandler->ExecuteCertErrorUserFeedback(message, >+ host, >+ port, >+ errorCode, >+ status, >+ ix509, >+ socketInfo); >+ } >+ } > } > > // Dispatched to the STS thread to notify the infoObject of the verification > // result. > // > // This will cause the PR_Poll in the STS thread to return, so things work > // correctly even if the STS thread is blocked polling (only) on the file > // descriptor that is waiting for this result. > class SSLServerCertVerificationResult : public nsRunnable > { > public: > NS_DECL_NSIRUNNABLE > > SSLServerCertVerificationResult(TransportSecurityInfo * infoObject, >+ bool alreadyReportedAsPrompt, > PRErrorCode errorCode, > SSLErrorMessageType errorMessageType = > PlainErrorMessage); > > void Dispatch(); > private: > const nsRefPtr<TransportSecurityInfo> mInfoObject; > public: >+ const bool mSuppressPrompt; > const PRErrorCode mErrorCode; > const SSLErrorMessageType mErrorMessageType; > }; > > class CertErrorRunnable : public SyncRunnableBase > { > public: > CertErrorRunnable(const void * fdForLogging, >@@ -265,17 +291,17 @@ private: > SSLServerCertVerificationResult * > CertErrorRunnable::CheckCertOverrides() > { > PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p][%p] top of CheckCertOverrides\n", > mFdForLogging, this)); > > if (!NS_IsMainThread()) { > NS_ERROR("CertErrorRunnable::CheckCertOverrides called off main thread"); >- return new SSLServerCertVerificationResult(mInfoObject, >+ return new SSLServerCertVerificationResult(mInfoObject, false, > mDefaultErrorCodeToReport); > } > > int32_t port; > mInfoObject->GetPort(&port); > > nsCString hostWithPortString; > hostWithPortString.AppendASCII(mInfoObject->GetHostName()); >@@ -292,17 +318,17 @@ CertErrorRunnable::CheckCertOverrides() > bool strictTransportSecurityEnabled = false; > nsCOMPtr<nsIStrictTransportSecurityService> stss > = do_GetService(NS_STSSERVICE_CONTRACTID, &nsrv); > if (NS_SUCCEEDED(nsrv)) { > nsrv = stss->IsStsHost(mInfoObject->GetHostName(), > &strictTransportSecurityEnabled); > } > if (NS_FAILED(nsrv)) { >- return new SSLServerCertVerificationResult(mInfoObject, >+ return new SSLServerCertVerificationResult(mInfoObject, false, > mDefaultErrorCodeToReport); > } > > if (!strictTransportSecurityEnabled) { > nsCOMPtr<nsICertOverrideService> overrideService = > do_GetService(NS_CERTOVERRIDE_CONTRACTID); > // it is fine to continue without the nsICertOverrideService > >@@ -325,49 +351,55 @@ CertErrorRunnable::CheckCertOverrides() > } > } > > if (!remaining_display_errors) { > // all errors are covered by override rules, so let's accept the cert > PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, > ("[%p][%p] All errors covered by override rules\n", > mFdForLogging, this)); >- return new SSLServerCertVerificationResult(mInfoObject, 0); >+ return new SSLServerCertVerificationResult(mInfoObject, false, 0); > } > } else { > PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, > ("[%p][%p] Strict-Transport-Security is violated: untrusted " > "transport layer\n", mFdForLogging, this)); > } > > PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, > ("[%p][%p] Certificate error was not overridden\n", > mFdForLogging, this)); > > // Ok, this is a full stop. > // First, deliver the technical details of the broken SSL status. > >+ bool listenerAskedToSuppress = false; > // Try to get a nsIBadCertListener2 implementation from the socket consumer. > nsCOMPtr<nsISSLSocketControl> sslSocketControl = do_QueryInterface( > NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, mInfoObject)); > if (sslSocketControl) { > nsCOMPtr<nsIInterfaceRequestor> cb; > sslSocketControl->GetNotificationCallbacks(getter_AddRefs(cb)); > if (cb) { > nsCOMPtr<nsIBadCertListener2> bcl = do_GetInterface(cb); > if (bcl) { > nsIInterfaceRequestor *csi > = static_cast<nsIInterfaceRequestor*>(mInfoObject); >- bool suppressMessage = false; // obsolete, ignored > nsrv = bcl->NotifyCertProblem(csi, mInfoObject->SSLStatus(), >- hostWithPortString, &suppressMessage); >+ hostWithPortString, &listenerAskedToSuppress); > } > } > } > >+ // Save the current preference for this socket, >+ // because this value will be changed once we call SetCanceled >+ bool suppressPromptsOnSocket = mInfoObject->GetSuppressErrorPrompt(); >+ bool logToConsole = mInfoObject->GetLogErrorToConsole(); >+ nsCOMPtr<nsISSLErrorAction> errHandler = mInfoObject->GetErrorActionHandler(); >+ > nsCOMPtr<nsIRecentBadCertsService> recentBadCertsService = > do_GetService(NS_RECENTBADCERTS_CONTRACTID); > > if (recentBadCertsService) { > NS_ConvertUTF8toUTF16 hostWithPortStringUTF16(hostWithPortString); > recentBadCertsService->AddBadCert(hostWithPortStringUTF16, > mInfoObject->SSLStatus()); > } >@@ -375,35 +407,41 @@ CertErrorRunnable::CheckCertOverrides() > // pick the error code to report by priority > PRErrorCode errorCodeToReport = mErrorCodeTrust ? mErrorCodeTrust > : mErrorCodeMismatch ? mErrorCodeMismatch > : mErrorCodeExpired ? mErrorCodeExpired > : mDefaultErrorCodeToReport; > > SSLServerCertVerificationResult *result = > new SSLServerCertVerificationResult(mInfoObject, >+ true, // prevent our caller from showing another prompt > errorCodeToReport, > OverridableCertErrorMessage); > >- LogInvalidCertError(mInfoObject, >- nsDependentCString(mInfoObject->GetHostName()), >- hostWithPortString, >- port, >- result->mErrorCode, >- result->mErrorMessageType, >- mCert); >+ bool showPrompt = !listenerAskedToSuppress && !suppressPromptsOnSocket; >+ nsHandleInvalidCertError(showPrompt, >+ logToConsole, >+ errHandler, >+ mInfoObject, >+ nsDependentCString(mInfoObject->GetHostName()), >+ hostWithPortString, >+ port, >+ result->mErrorCode, >+ result->mErrorMessageType, >+ mCert); > > return result; > } > > void > CertErrorRunnable::RunOnTargetThread() > { > MOZ_ASSERT(NS_IsMainThread()); > >+ mInfoObject->ObtainSSLErrorAction(); > mResult = CheckCertOverrides(); > > MOZ_ASSERT(mResult); > } > > // Returns null with the error code (PR_GetError()) set if it does not create > // the CertErrorRunnable. > CertErrorRunnable * >@@ -1035,17 +1073,17 @@ SSLServerCertVerificationJob::Run() > error = SEC_ERROR_USER_CANCELLED; > } else { > // Reset the error code here so we can detect if AuthCertificate fails to > // set the error code if/when it fails. > PR_SetError(0, 0); > SECStatus rv = AuthCertificate(mInfoObject, mCert); > if (rv == SECSuccess) { > nsRefPtr<SSLServerCertVerificationResult> restart >- = new SSLServerCertVerificationResult(mInfoObject, 0); >+ = new SSLServerCertVerificationResult(mInfoObject, false, 0); > restart->Dispatch(); > return NS_OK; > } > > error = PR_GetError(); > if (error != 0) { > nsRefPtr<CertErrorRunnable> runnable = CreateCertErrorRunnable( > error, mInfoObject, mCert, mFdForLogging); >@@ -1080,17 +1118,17 @@ SSLServerCertVerificationJob::Run() > } > > if (error == 0) { > NS_NOTREACHED("no error set during certificate validation failure"); > error = PR_INVALID_STATE_ERROR; > } > > nsRefPtr<SSLServerCertVerificationResult> failure >- = new SSLServerCertVerificationResult(mInfoObject, error); >+ = new SSLServerCertVerificationResult(mInfoObject, false, error); > failure->Dispatch(); > return NS_OK; > } > > } // unnamed namespace > > // Extracts whatever information we need out of fd (using SSL_*) and passes it > // to SSLServerCertVerificationJob::Dispatch. SSLServerCertVerificationJob should >@@ -1193,35 +1231,39 @@ AuthCertificateHook(void *arg, PRFileDes > return SECSuccess; // cert error override occurred. > } > > // We must call SetCanceled here to set the error message type > // in case it isn't PlainErrorMessage, which is what we would > // default to if we just called > // PR_SetError(runnable->mResult->mErrorCode, 0) and returned > // SECFailure without doing this. >- socketInfo->SetCanceled(runnable->mResult->mErrorCode, >+ socketInfo->SetCanceled(runnable->mResult->mSuppressPrompt, >+ runnable->mResult->mErrorCode, > runnable->mResult->mErrorMessageType); > error = runnable->mResult->mErrorCode; > } > } > > if (error == 0) { > NS_ERROR("error code not set"); > error = PR_UNKNOWN_ERROR; > } > > PR_SetError(error, 0); > return SECFailure; > } > > SSLServerCertVerificationResult::SSLServerCertVerificationResult( >- TransportSecurityInfo * infoObject, PRErrorCode errorCode, >+ TransportSecurityInfo * infoObject, >+ bool suppressPrompt, >+ PRErrorCode errorCode, > SSLErrorMessageType errorMessageType) > : mInfoObject(infoObject) >+ , mSuppressPrompt(suppressPrompt) > , mErrorCode(errorCode) > , mErrorMessageType(errorMessageType) > { > } > > void > SSLServerCertVerificationResult::Dispatch() > { >@@ -1236,13 +1278,14 @@ SSLServerCertVerificationResult::Dispatc > } > > NS_IMETHODIMP > SSLServerCertVerificationResult::Run() > { > // TODO: Assert that we're on the socket transport thread > // XXX: This cast will be removed by the next patch > ((nsNSSSocketInfo *) mInfoObject.get()) >- ->SetCertVerificationResult(mErrorCode, mErrorMessageType); >+ ->SetCertVerificationResult(mSuppressPrompt, >+ mErrorCode, mErrorMessageType); > return NS_OK; > } > > } } // namespace mozilla::psm >diff --git a/security/manager/ssl/src/TransportSecurityInfo.cpp b/security/manager/ssl/src/TransportSecurityInfo.cpp >--- a/security/manager/ssl/src/TransportSecurityInfo.cpp >+++ b/security/manager/ssl/src/TransportSecurityInfo.cpp >@@ -2,28 +2,32 @@ > * > * 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/. */ > > #include "TransportSecurityInfo.h" > #include "nsNSSComponent.h" > #include "nsIWebProgressListener.h" >+#include "nsIDocShell.h" >+#include "nsIDocShellTreeItem.h" > #include "nsNSSCertificate.h" > #include "nsIX509CertValidity.h" > #include "nsIDateTimeFormat.h" > #include "nsDateTimeFormatCID.h" > #include "nsICertOverrideService.h" > #include "nsIObjectInputStream.h" > #include "nsIObjectOutputStream.h" > #include "nsNSSCertHelper.h" > #include "nsNSSCleaner.h" >+#include "nsISecureBrowserUI.h" > #include "nsIProgrammingLanguage.h" > #include "nsIArray.h" > #include "PSMRunnable.h" >+#include "nsISSLErrorAction.h" > > #include "secerr.h" > > //#define DEBUG_SSL_VERBOSE //Enable this define to get minimal > //reports when doing SSL read/write > > //#define DUMP_BUFFER //Enable this define along with > //DEBUG_SSL_VERBOSE to dump SSL >@@ -46,16 +50,17 @@ TransportSecurityInfo::TransportSecurity > : mMutex("TransportSecurityInfo::mMutex"), > mSecurityState(nsIWebProgressListener::STATE_IS_INSECURE), > mSubRequestsHighSecurity(0), > mSubRequestsLowSecurity(0), > mSubRequestsBrokenSecurity(0), > mSubRequestsNoSecurity(0), > mErrorCode(0), > mErrorMessageType(PlainErrorMessage), >+ mSuppressErrorPrompt(false), > mPort(0), > mIsCertIssuerBlacklisted(false) > { > } > > TransportSecurityInfo::~TransportSecurityInfo() > { > nsNSSShutDownPreventionLock locker; >@@ -110,26 +115,91 @@ PRErrorCode > TransportSecurityInfo::GetErrorCode() const > { > MutexAutoLock lock(mMutex); > > return mErrorCode; > } > > void >-TransportSecurityInfo::SetCanceled(PRErrorCode errorCode, >+TransportSecurityInfo::SetCanceled(bool suppressPrompt, >+ PRErrorCode errorCode, > SSLErrorMessageType errorMessageType) > { > MutexAutoLock lock(mMutex); > >+ if (suppressPrompt) { >+ mSuppressErrorPrompt = suppressPrompt; >+ } > mErrorCode = errorCode; > mErrorMessageType = errorMessageType; > mErrorMessageCached.Truncate(); > } > >+void >+TransportSecurityInfo::ObtainSSLErrorAction() >+{ >+ if (!NS_IsMainThread()) { >+ NS_ERROR("TransportSecurityInfo::ObtainSSLErrorAction called off main thread"); >+ return; >+ } >+ >+ if (mErrorActionHandler) // already done >+ return; >+ >+ PRInt16 fepb = nsISSLErrorAction::PROMPT_SUPPRESS; >+ >+ nsresult rv; >+ mErrorActionHandler = do_GetService(NS_SSLERRORACTION_CONTRACTID, &rv); >+ >+ if (NS_SUCCEEDED(rv) && mErrorActionHandler) { >+ if (NS_FAILED(mErrorActionHandler->GetLogToConsole(&mLogErrorToConsole))) >+ mLogErrorToConsole = PR_TRUE; >+ >+ PRInt16 obtained; >+ rv = mErrorActionHandler->GetPromptBehaviour(&obtained); >+ if (NS_SUCCEEDED(rv)) { >+ fepb = obtained; >+ } >+ } >+ >+ switch (fepb) { >+ case nsISSLErrorAction::DETECT_DOCSHELL: >+ { >+ mSuppressErrorPrompt = false; >+ nsCOMPtr<nsIDocShellTreeItem> item(do_GetInterface(mCallbacks)); >+ if (item) { >+ nsCOMPtr<nsIDocShellTreeItem> rootItem; >+ item->GetSameTypeRootTreeItem(getter_AddRefs(rootItem)); >+ nsCOMPtr<nsIDocShell> docshell; >+ docshell = do_QueryInterface(rootItem); >+ NS_ASSERTION(docshell, "rootItem do_QI is null"); >+ if (docshell) { >+ nsCOMPtr<nsISecureBrowserUI> secureUI; >+ docshell->GetSecurityUI(getter_AddRefs(secureUI)); >+ if (secureUI) { >+ mSuppressErrorPrompt = true; >+ } >+ } >+ } >+ } >+ break; >+ >+ case nsISSLErrorAction::PROMPT_DEFAULT: >+ case nsISSLErrorAction::PROMPT_SUPPRESS: >+ mSuppressErrorPrompt = true; >+ break; >+ >+ case nsISSLErrorAction::PROMPT_ALLOWED: >+ default: >+ mSuppressErrorPrompt = false; >+ break; >+ } >+} >+ > NS_IMETHODIMP > TransportSecurityInfo::GetSecurityState(uint32_t* state) > { > *state = mSecurityState; > return NS_OK; > } > > nsresult >diff --git a/security/manager/ssl/src/TransportSecurityInfo.h b/security/manager/ssl/src/TransportSecurityInfo.h >--- a/security/manager/ssl/src/TransportSecurityInfo.h >+++ b/security/manager/ssl/src/TransportSecurityInfo.h >@@ -8,16 +8,17 @@ > #define _MOZILLA_PSM_TRANSPORTSECURITYINFO_H > > #include "certt.h" > #include "mozilla/Mutex.h" > #include "nsIInterfaceRequestor.h" > #include "nsITransportSecurityInfo.h" > #include "nsSSLStatus.h" > #include "nsISSLStatusProvider.h" >+#include "nsISSLErrorAction.h" > #include "nsIAssociatedContentSecurity.h" > #include "nsNSSShutDown.h" > #include "nsDataHashtable.h" > > namespace mozilla { namespace psm { > > enum SSLErrorMessageType { > OverridableCertErrorMessage = 1, // for *overridable* certificate errors >@@ -59,47 +60,55 @@ public: > nsresult SetPort(int32_t aPort); > > PRErrorCode GetErrorCode() const; > > void GetErrorLogMessage(PRErrorCode errorCode, > ::mozilla::psm::SSLErrorMessageType errorMessageType, > nsString &result); > >- void SetCanceled(PRErrorCode errorCode, >+ void SetCanceled(bool suppressPrompt, >+ PRErrorCode errorCode, > ::mozilla::psm::SSLErrorMessageType errorMessageType); >+ bool GetSuppressErrorPrompt() { return mSuppressErrorPrompt; } >+ bool GetLogErrorToConsole() { return mLogErrorToConsole; } >+ nsISSLErrorAction* GetErrorActionHandler() { return mErrorActionHandler; } > > /* Set SSL Status values */ > nsresult SetSSLStatus(nsSSLStatus *aSSLStatus); > nsSSLStatus* SSLStatus() { return mSSLStatus; } > void SetStatusErrorBits(nsIX509Cert & cert, uint32_t collected_errors); > > bool IsCertIssuerBlacklisted() const { > return mIsCertIssuerBlacklisted; > } > void SetCertIssuerBlacklisted() { > mIsCertIssuerBlacklisted = true; > } > >+ void ObtainSSLErrorAction(); > private: > mutable ::mozilla::Mutex mMutex; > > protected: > nsCOMPtr<nsIInterfaceRequestor> mCallbacks; > > private: > uint32_t mSecurityState; > int32_t mSubRequestsHighSecurity; > int32_t mSubRequestsLowSecurity; > int32_t mSubRequestsBrokenSecurity; > int32_t mSubRequestsNoSecurity; > nsString mShortDesc; > > PRErrorCode mErrorCode; > ::mozilla::psm::SSLErrorMessageType mErrorMessageType; >+ nsCOMPtr<nsISSLErrorAction> mErrorActionHandler; >+ bool mSuppressErrorPrompt; >+ bool mLogErrorToConsole; > nsString mErrorMessageCached; > nsresult formatErrorMessage(::mozilla::MutexAutoLock const & proofOfLock, > PRErrorCode errorCode, > ::mozilla::psm::SSLErrorMessageType errorMessageType, > bool wantsHtml, bool suppressPort443, > nsString &result); > > int32_t mPort; >diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp >--- a/security/manager/ssl/src/nsNSSIOLayer.cpp >+++ b/security/manager/ssl/src/nsNSSIOLayer.cpp >@@ -390,17 +390,18 @@ nsNSSSocketInfo::SetCertVerificationWait > mCertVerificationState = waiting_for_cert_verification; > } > > // Be careful that SetCertVerificationResult does NOT get called while we are > // processing a SSL callback function, because SSL_AuthCertificateComplete will > // attempt to acquire locks that are already held by libssl when it calls > // callbacks. > void >-nsNSSSocketInfo::SetCertVerificationResult(PRErrorCode errorCode, >+nsNSSSocketInfo::SetCertVerificationResult(bool suppressPrompt, >+ PRErrorCode errorCode, > SSLErrorMessageType errorMessageType) > { > NS_ASSERTION(mCertVerificationState == waiting_for_cert_verification, > "Invalid state transition to cert_verification_finished"); > > if (mFd) { > SECStatus rv = SSL_AuthCertificateComplete(mFd, errorCode); > // Only replace errorCode if there was originally no error >@@ -410,17 +411,17 @@ nsNSSSocketInfo::SetCertVerificationResu > if (errorCode == 0) { > NS_ERROR("SSL_AuthCertificateComplete didn't set error code"); > errorCode = PR_INVALID_STATE_ERROR; > } > } > } > > if (errorCode) { >- SetCanceled(errorCode, errorMessageType); >+ SetCanceled(suppressPrompt, errorCode, errorMessageType); > } > > mCertVerificationState = after_cert_verification; > } > > void nsNSSSocketInfo::SetHandshakeInProgress(bool aIsIn) > { > mHandshakeInProgress = aIsIn; >@@ -481,75 +482,89 @@ void nsSSLIOLayerHelpers::Cleanup() > > if (mutex) { > delete mutex; > mutex = nullptr; > } > } > > static void >-nsHandleSSLError(nsNSSSocketInfo *socketInfo, >+nsHandleSSLError(bool suppressPromptsOnSocket, >+ bool logToConsole, >+ nsISSLErrorAction *errorActionHandler, >+ nsNSSSocketInfo *socketInfo, > ::mozilla::psm::SSLErrorMessageType errtype, > PRErrorCode err) > { > if (!NS_IsMainThread()) { > NS_ERROR("nsHandleSSLError called off the main thread"); > return; > } > > // SetCanceled is only called by the main thread or the socket transport > // thread. Whenever this function is called on the main thread, the SSL > // thread is blocked on it. So, no mutex is necessary for > // SetCanceled()/GetError*(). >- if (socketInfo->GetErrorCode()) { >- // If the socket has been flagged as canceled, >- // the code who did was responsible for setting the error code. >- return; >- } > > nsresult rv; > NS_DEFINE_CID(nssComponentCID, NS_NSSCOMPONENT_CID); > nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(nssComponentCID, &rv)); > if (NS_FAILED(rv)) > return; > > nsXPIDLCString hostName; > socketInfo->GetHostName(getter_Copies(hostName)); > > int32_t port; > socketInfo->GetPort(&port); > >+ bool suppressMessage = false; > // Try to get a nsISSLErrorListener implementation from the socket consumer. > nsCOMPtr<nsIInterfaceRequestor> cb; > socketInfo->GetNotificationCallbacks(getter_AddRefs(cb)); > if (cb) { > nsCOMPtr<nsISSLErrorListener> sel = do_GetInterface(cb); > if (sel) { > nsIInterfaceRequestor *csi = static_cast<nsIInterfaceRequestor*>(socketInfo); > nsCString hostWithPortString = hostName; > hostWithPortString.AppendLiteral(":"); > hostWithPortString.AppendInt(port); > >- bool suppressMessage = false; // obsolete, ignored > rv = sel->NotifySSLError(csi, err, hostWithPortString, &suppressMessage); >+ if (NS_FAILED(rv)) >+ suppressMessage = false; > } > } > > // We must cancel first, which sets the error code. >- socketInfo->SetCanceled(err, PlainErrorMessage); >+ socketInfo->SetCanceled(suppressMessage, err, PlainErrorMessage); > nsXPIDLString errorString; > socketInfo->GetErrorLogMessage(err, errtype, errorString); > >- if (!errorString.IsEmpty()) { >+ if (errorString.IsEmpty()) >+ return; >+ >+ if (logToConsole) { > nsCOMPtr<nsIConsoleService> console; > console = do_GetService(NS_CONSOLESERVICE_CONTRACTID); > if (console) { > console->LogStringMessage(errorString.get()); > } > } >+ >+ if (!suppressMessage && !socketInfo->GetSuppressErrorPrompt()) { >+ nsPSMUITracker tracker; >+ if (!tracker.isUIForbidden()) { >+ errorActionHandler->ExecuteProtocolErrorUserFeedback(errorString, >+ hostName, >+ port, >+ err, >+ socketInfo); >+ } >+ } > } > > namespace { > > enum Operation { reading, writing, not_reading_or_writing }; > > int32_t checkHandshake(int32_t bytesTransfered, bool wasReading, > PRFileDesc* ssl_layer_fd, >@@ -826,17 +841,22 @@ class SSLErrorRunnable : public SyncRunn > : mInfoObject(infoObject) > , mErrType(errtype) > , mErrorCode(errorCode) > { > } > > virtual void RunOnTargetThread() > { >- nsHandleSSLError(mInfoObject, mErrType, mErrorCode); >+ mInfoObject->ObtainSSLErrorAction(); >+ bool suppressPromptsOnSocket = mInfoObject->GetSuppressErrorPrompt(); >+ bool logToConsole = mInfoObject->GetLogErrorToConsole(); >+ nsCOMPtr<nsISSLErrorAction> errHandler = mInfoObject->GetErrorActionHandler(); >+ nsHandleSSLError(suppressPromptsOnSocket, logToConsole, errHandler, >+ mInfoObject, mErrType, mErrorCode); > } > > nsRefPtr<nsNSSSocketInfo> mInfoObject; > ::mozilla::psm::SSLErrorMessageType mErrType; > const PRErrorCode mErrorCode; > }; > > namespace { >@@ -902,17 +922,18 @@ int32_t checkHandshake(int32_t bytesTran > // > // The socketInfo->GetErrorCode() check is here to ensure we don't try to > // do the synchronous dispatch to the main thread unnecessarily after we've > // already handled a certificate error. (SSLErrorRunnable calls > // nsHandleSSLError, which has logic to avoid replacing the error message, > // so without the !socketInfo->GetErrorCode(), it would just be an > // expensive no-op.) > if (!wantRetry && (IS_SSL_ERROR(err) || IS_SEC_ERROR(err)) && >- !socketInfo->GetErrorCode()) { >+ !socketInfo->GetErrorCode() >+ && !socketInfo->GetSuppressErrorPrompt()) { > nsRefPtr<SyncRunnableBase> runnable = new SSLErrorRunnable(socketInfo, > PlainErrorMessage, > err); > (void) runnable->DispatchToMainThreadAndWait(); > } > } > else if (wasReading && 0 == bytesTransfered) // zero bytes on reading, socket closed > { >@@ -988,17 +1009,17 @@ nsSSLIOLayerPoll(PRFileDesc * fd, int16_ > > // See comments in HandshakeTimeout before moving and/or changing this block > if (socketInfo->HandshakeTimeout()) { > NS_WARNING("SSL handshake timed out"); > PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p] handshake timed out\n", fd)); > NS_ASSERTION(in_flags & PR_POLL_EXCEPT, > "caller did not poll for EXCEPT (handshake timeout)"); > *out_flags = in_flags | PR_POLL_EXCEPT; >- socketInfo->SetCanceled(PR_CONNECT_RESET_ERROR, PlainErrorMessage); >+ socketInfo->SetCanceled(false, PR_CONNECT_RESET_ERROR, PlainErrorMessage); > return in_flags; > } > > // We want the handshake to continue during certificate validation, so we > // don't need to do anything special here. libssl automatically blocks when > // it reaches any point that would be unsafe to send/receive something before > // cert validation is complete. > int16_t result = fd->lower->methods->poll(fd->lower, in_flags, out_flags); >diff --git a/security/manager/ssl/src/nsNSSIOLayer.h b/security/manager/ssl/src/nsNSSIOLayer.h >--- a/security/manager/ssl/src/nsNSSIOLayer.h >+++ b/security/manager/ssl/src/nsNSSIOLayer.h >@@ -60,17 +60,18 @@ public: > enum CertVerificationState { > before_cert_verification, > waiting_for_cert_verification, > after_cert_verification > }; > void SetCertVerificationWaiting(); > // Use errorCode == 0 to indicate success; in that case, errorMessageType is > // ignored. >- void SetCertVerificationResult(PRErrorCode errorCode, >+ void SetCertVerificationResult(bool suppressPrompt, >+ PRErrorCode errorCode, > ::mozilla::psm::SSLErrorMessageType errorMessageType); > > // for logging only > PRBool IsWaitingForCertVerification() const > { > return mCertVerificationState == waiting_for_cert_verification; > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 851089
:
606511
|
606512
| 616533