From ba4ba32e0fc81879e76d47609ef248d2689f6b4a Mon Sep 17 00:00:00 2001 From: David Keeler Date: Fri, 30 Jan 2015 11:25:24 -0800 Subject: [PATCH] backout cd0ec3afca5a (bug 832837) for mochitest bustage --- CLOBBER | 2 +- dom/html/HTMLFormElement.cpp | 102 ++----- security/manager/boot/public/moz.build | 1 + .../boot/public/nsISecurityWarningDialogs.idl | 32 +++ security/manager/boot/src/moz.build | 1 + security/manager/boot/src/nsBOOTModule.cpp | 5 + .../boot/src/nsSecureBrowserUIImpl.cpp | 255 ++++++++++++++++++ .../manager/boot/src/nsSecureBrowserUIImpl.h | 26 ++ .../boot/src/nsSecurityWarningDialogs.cpp | 162 +++++++++++ .../boot/src/nsSecurityWarningDialogs.h | 45 ++++ .../en-US/chrome/pipnss/security.properties | 7 + security/manager/locales/jar.mn | 1 + .../en-US/chrome/global/browser.properties | 4 - 13 files changed, 558 insertions(+), 85 deletions(-) create mode 100644 security/manager/boot/public/nsISecurityWarningDialogs.idl create mode 100644 security/manager/boot/src/nsSecurityWarningDialogs.cpp create mode 100644 security/manager/boot/src/nsSecurityWarningDialogs.h create mode 100644 security/manager/locales/en-US/chrome/pipnss/security.properties diff --git a/CLOBBER b/CLOBBER index bb1befee796..e0e95faab14 100644 --- a/CLOBBER +++ b/CLOBBER @@ -22,4 +22,4 @@ # changes to stick? As of bug 928195, this shouldn't be necessary! Please # don't change CLOBBER for WebIDL changes any more. -bug 832837 removes nsISecurityWarningDialogs.idl, which requires a clobber according to bug 1114669 +Bug 1109248 - This needed a CLOBBER on Windows and OSX. diff --git a/dom/html/HTMLFormElement.cpp b/dom/html/HTMLFormElement.cpp index 61d5181ab7a..378a7f7e56e 100644 --- a/dom/html/HTMLFormElement.cpp +++ b/dom/html/HTMLFormElement.cpp @@ -20,6 +20,7 @@ #include "nsPresContext.h" #include "nsIDocument.h" #include "nsIFormControlFrame.h" +#include "nsISecureBrowserUI.h" #include "nsError.h" #include "nsContentUtils.h" #include "nsInterfaceHashtable.h" @@ -32,7 +33,6 @@ #include "mozilla/BinarySearch.h" // form submission -#include "mozilla/Telemetry.h" #include "nsIFormSubmitObserver.h" #include "nsIObserverService.h" #include "nsICategoryManager.h" @@ -45,9 +45,6 @@ #include "nsIDocShell.h" #include "nsFormData.h" #include "nsFormSubmissionConstants.h" -#include "nsIPromptService.h" -#include "nsISecurityUITelemetry.h" -#include "nsIStringBundle.h" // radio buttons #include "mozilla/dom/HTMLInputElement.h" @@ -880,79 +877,24 @@ HTMLFormElement::NotifySubmitObservers(nsIURI* aActionURL, // sXBL/XBL2 issue nsCOMPtr window = OwnerDoc()->GetWindow(); - nsCOMPtr principalURI; - nsresult rv = NodePrincipal()->GetURI(getter_AddRefs(principalURI)); - if (NS_FAILED(rv)) { - return rv; - } - bool formIsHTTPS; - rv = principalURI->SchemeIs("https", &formIsHTTPS); - if (NS_FAILED(rv)) { - return rv; - } - bool actionIsHTTPS; - rv = aActionURL->SchemeIs("https", &actionIsHTTPS); - if (NS_FAILED(rv)) { - return rv; - } - bool actionIsJS; - rv = aActionURL->SchemeIs("javascript", &actionIsJS); - if (NS_FAILED(rv)) { - return rv; - } - if (formIsHTTPS && !actionIsHTTPS && !actionIsJS && !aEarlyNotify) { - nsCOMPtr promptSvc = - do_GetService("@mozilla.org/embedcomp/prompt-service;1"); - if (!promptSvc) { - return NS_ERROR_FAILURE; + // Notify the secure browser UI, if any, that the form is being submitted. + nsCOMPtr docshell = OwnerDoc()->GetDocShell(); + if (docshell && !aEarlyNotify) { + nsCOMPtr secureUI; + docshell->GetSecurityUI(getter_AddRefs(secureUI)); + nsCOMPtr formSubmitObserver = + do_QueryInterface(secureUI); + if (formSubmitObserver) { + nsresult rv = formSubmitObserver->Notify(this, + window, + aActionURL, + aCancelSubmit); + NS_ENSURE_SUCCESS(rv, rv); + + if (*aCancelSubmit) { + return NS_OK; + } } - nsCOMPtr stringBundle; - nsCOMPtr stringBundleService = - mozilla::services::GetStringBundleService(); - if (!stringBundleService) { - return NS_ERROR_FAILURE; - } - rv = stringBundleService->CreateBundle( - "chrome://global/locale/browser.properties", - getter_AddRefs(stringBundle)); - if (NS_FAILED(rv)) { - return rv; - } - nsAutoString title; - nsAutoString message; - nsAutoString cont; - stringBundle->GetStringFromName( - MOZ_UTF16("formPostSecureToInsecureWarning.title"), getter_Copies(title)); - stringBundle->GetStringFromName( - MOZ_UTF16("formPostSecureToInsecureWarning.message"), - getter_Copies(message)); - stringBundle->GetStringFromName( - MOZ_UTF16("formPostSecureToInsecureWarning.continue"), - getter_Copies(cont)); - int32_t buttonPressed; - bool checkState; // this is unused (ConfirmEx requires this parameter) - rv = promptSvc->ConfirmEx(window, title.get(), message.get(), - (nsIPromptService::BUTTON_TITLE_IS_STRING * - nsIPromptService::BUTTON_POS_0) + - (nsIPromptService::BUTTON_TITLE_CANCEL * - nsIPromptService::BUTTON_POS_1), - cont.get(), nullptr, nullptr, nullptr, - &checkState, &buttonPressed); - if (NS_FAILED(rv)) { - return rv; - } - *aCancelSubmit = (buttonPressed == 1); - uint32_t telemetryBucket = - nsISecurityUITelemetry::WARNING_CONFIRM_POST_TO_INSECURE_FROM_SECURE; - mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI, - telemetryBucket); - // Return early if the submission is cancelled. - if (*aCancelSubmit) { - return NS_OK; - } - // The user opted to continue, so note that in the next telemetry bucket. - mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI, - telemetryBucket + 1); } // Notify observers that the form is being submitted. @@ -962,10 +904,10 @@ HTMLFormElement::NotifySubmitObservers(nsIURI* aActionURL, return NS_ERROR_FAILURE; nsCOMPtr theEnum; - rv = service->EnumerateObservers(aEarlyNotify ? - NS_EARLYFORMSUBMIT_SUBJECT : - NS_FORMSUBMIT_SUBJECT, - getter_AddRefs(theEnum)); + nsresult rv = service->EnumerateObservers(aEarlyNotify ? + NS_EARLYFORMSUBMIT_SUBJECT : + NS_FORMSUBMIT_SUBJECT, + getter_AddRefs(theEnum)); NS_ENSURE_SUCCESS(rv, rv); if (theEnum) { diff --git a/security/manager/boot/public/moz.build b/security/manager/boot/public/moz.build index b0879c6d99a..5f841e1c1d1 100644 --- a/security/manager/boot/public/moz.build +++ b/security/manager/boot/public/moz.build @@ -8,6 +8,7 @@ XPIDL_SOURCES += [ 'nsIBufEntropyCollector.idl', 'nsICertBlocklist.idl', 'nsISecurityUITelemetry.idl', + 'nsISecurityWarningDialogs.idl', 'nsISSLStatusProvider.idl', ] diff --git a/security/manager/boot/public/nsISecurityWarningDialogs.idl b/security/manager/boot/public/nsISecurityWarningDialogs.idl new file mode 100644 index 00000000000..d6c812abf43 --- /dev/null +++ b/security/manager/boot/public/nsISecurityWarningDialogs.idl @@ -0,0 +1,32 @@ +/* -*- 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" + +interface nsIInterfaceRequestor; + +/** + * Functions that display warnings for transitions between secure + * and insecure pages, posts to insecure servers etc. + */ +[scriptable, uuid(a9561631-5964-4d3f-b372-9f23504054b1)] +interface nsISecurityWarningDialogs : nsISupports +{ + /** + * Inform the user: Although the currently displayed + * page was loaded using a secure connection, and the UI probably + * currently indicates a secure page, + * that information is being submitted to an insecure page. + * + * @param ctx A user interface context. + * + * @return true if the user confirms to submit. + */ + boolean confirmPostToInsecureFromSecure(in nsIInterfaceRequestor ctx); +}; + +%{C++ +#define NS_SECURITYWARNINGDIALOGS_CONTRACTID "@mozilla.org/nsSecurityWarningDialogs;1" +%} diff --git a/security/manager/boot/src/moz.build b/security/manager/boot/src/moz.build index e181f84ff67..71078d16f0c 100644 --- a/security/manager/boot/src/moz.build +++ b/security/manager/boot/src/moz.build @@ -15,6 +15,7 @@ UNIFIED_SOURCES += [ 'nsEntropyCollector.cpp', 'nsSecureBrowserUIImpl.cpp', 'nsSecurityHeaderParser.cpp', + 'nsSecurityWarningDialogs.cpp', 'nsSiteSecurityService.cpp', 'PublicKeyPinningService.cpp', 'RootCertificateTelemetryUtils.cpp', diff --git a/security/manager/boot/src/nsBOOTModule.cpp b/security/manager/boot/src/nsBOOTModule.cpp index 52f1a5d2893..62e1b6374a3 100644 --- a/security/manager/boot/src/nsBOOTModule.cpp +++ b/security/manager/boot/src/nsBOOTModule.cpp @@ -8,20 +8,24 @@ #include "CertBlocklist.h" #include "nsEntropyCollector.h" #include "nsSecureBrowserUIImpl.h" +#include "nsSecurityWarningDialogs.h" #include "nsSiteSecurityService.h" NS_GENERIC_FACTORY_CONSTRUCTOR(nsEntropyCollector) NS_GENERIC_FACTORY_CONSTRUCTOR(nsSecureBrowserUIImpl) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(CertBlocklist, Init) +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSecurityWarningDialogs, Init) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSiteSecurityService, Init) NS_DEFINE_NAMED_CID(NS_ENTROPYCOLLECTOR_CID); +NS_DEFINE_NAMED_CID(NS_SECURITYWARNINGDIALOGS_CID); NS_DEFINE_NAMED_CID(NS_SECURE_BROWSER_UI_CID); NS_DEFINE_NAMED_CID(NS_SITE_SECURITY_SERVICE_CID); NS_DEFINE_NAMED_CID(NS_CERT_BLOCKLIST_CID); static const mozilla::Module::CIDEntry kBOOTCIDs[] = { { &kNS_ENTROPYCOLLECTOR_CID, false, nullptr, nsEntropyCollectorConstructor }, + { &kNS_SECURITYWARNINGDIALOGS_CID, false, nullptr, nsSecurityWarningDialogsConstructor }, { &kNS_SECURE_BROWSER_UI_CID, false, nullptr, nsSecureBrowserUIImplConstructor }, { &kNS_SITE_SECURITY_SERVICE_CID, false, nullptr, nsSiteSecurityServiceConstructor }, { &kNS_CERT_BLOCKLIST_CID, false, nullptr, CertBlocklistConstructor}, @@ -30,6 +34,7 @@ static const mozilla::Module::CIDEntry kBOOTCIDs[] = { static const mozilla::Module::ContractIDEntry kBOOTContracts[] = { { NS_ENTROPYCOLLECTOR_CONTRACTID, &kNS_ENTROPYCOLLECTOR_CID }, + { NS_SECURITYWARNINGDIALOGS_CONTRACTID, &kNS_SECURITYWARNINGDIALOGS_CID }, { NS_SECURE_BROWSER_UI_CONTRACTID, &kNS_SECURE_BROWSER_UI_CID }, { NS_SSSERVICE_CONTRACTID, &kNS_SITE_SECURITY_SERVICE_CID }, { NS_CERTBLOCKLIST_CONTRACTID, &kNS_CERT_BLOCKLIST_CID }, diff --git a/security/manager/boot/src/nsSecureBrowserUIImpl.cpp b/security/manager/boot/src/nsSecureBrowserUIImpl.cpp index a5b6bd9907d..132855f3ebb 100644 --- a/security/manager/boot/src/nsSecureBrowserUIImpl.cpp +++ b/security/manager/boot/src/nsSecureBrowserUIImpl.cpp @@ -9,13 +9,17 @@ #include "nsISecureBrowserUI.h" #include "nsSecureBrowserUIImpl.h" #include "nsCOMPtr.h" +#include "nsIInterfaceRequestor.h" +#include "nsIInterfaceRequestorUtils.h" #include "nsIServiceManager.h" #include "nsCURILoader.h" #include "nsIDocShell.h" #include "nsIDocShellTreeItem.h" #include "nsIDocument.h" +#include "nsIPrincipal.h" #include "nsIDOMElement.h" #include "nsPIDOMWindow.h" +#include "nsIContent.h" #include "nsIWebProgress.h" #include "nsIWebProgressListener.h" #include "nsIChannel.h" @@ -27,6 +31,9 @@ #include "nsISSLStatus.h" #include "nsIURI.h" #include "nsISecurityEventSink.h" +#include "nsIPrompt.h" +#include "nsIFormSubmitObserver.h" +#include "nsISecurityWarningDialogs.h" #include "nsISecurityInfoProvider.h" #include "imgIRequest.h" #include "nsThreadUtils.h" @@ -134,6 +141,7 @@ nsSecureBrowserUIImpl::~nsSecureBrowserUIImpl() NS_IMPL_ISUPPORTS(nsSecureBrowserUIImpl, nsISecureBrowserUI, nsIWebProgressListener, + nsIFormSubmitObserver, nsISupportsWeakReference, nsISSLStatusProvider) @@ -303,6 +311,25 @@ nsSecureBrowserUIImpl::SetDocShell(nsIDocShell *aDocShell) return rv; } +static nsresult IsChildOfDomWindow(nsIDOMWindow *parent, nsIDOMWindow *child, + bool* value) +{ + *value = false; + + if (parent == child) { + *value = true; + return NS_OK; + } + + nsCOMPtr childsParent; + child->GetParent(getter_AddRefs(childsParent)); + + if (childsParent && childsParent.get() != child) + IsChildOfDomWindow(parent, childsParent, value); + + return NS_OK; +} + static uint32_t GetSecurityStateFromSecurityInfoAndRequest(nsISupports* info, nsIRequest* request) { @@ -356,6 +383,72 @@ static uint32_t GetSecurityStateFromSecurityInfoAndRequest(nsISupports* info, } +NS_IMETHODIMP +nsSecureBrowserUIImpl::Notify(nsIDOMHTMLFormElement* aDOMForm, + nsIDOMWindow* aWindow, nsIURI* actionURL, + bool* cancelSubmit) +{ + // Return NS_OK unless we want to prevent this form from submitting. + *cancelSubmit = false; + if (!aWindow || !actionURL || !aDOMForm) + return NS_OK; + + nsCOMPtr formNode = do_QueryInterface(aDOMForm); + + nsCOMPtr document = formNode->GetComposedDoc(); + if (!document) return NS_OK; + + nsIPrincipal *principal = formNode->NodePrincipal(); + + if (!principal) + { + *cancelSubmit = true; + return NS_OK; + } + + nsCOMPtr formURL; + if (NS_FAILED(principal->GetURI(getter_AddRefs(formURL))) || + !formURL) + { + formURL = document->GetDocumentURI(); + } + + nsCOMPtr postingWindow = + do_QueryInterface(document->GetWindow()); + // We can't find this document's window, cancel it. + if (!postingWindow) + { + NS_WARNING("If you see this and can explain why it should be allowed, note in Bug 332324"); + *cancelSubmit = true; + return NS_OK; + } + + nsCOMPtr window; + { + ReentrantMonitorAutoEnter lock(mReentrantMonitor); + window = do_QueryReferent(mWindow); + + // The window was destroyed, so we assume no form was submitted within it. + if (!window) + return NS_OK; + } + + bool isChild; + IsChildOfDomWindow(window, postingWindow, &isChild); + + // This notify call is not for our window, ignore it. + if (!isChild) + return NS_OK; + + bool okayToPost; + nsresult res = CheckPost(formURL, actionURL, &okayToPost); + + if (NS_SUCCEEDED(res) && !okayToPost) + *cancelSubmit = true; + + return res; +} + // nsIWebProgressListener NS_IMETHODIMP nsSecureBrowserUIImpl::OnProgressChange(nsIWebProgress* aWebProgress, @@ -1415,3 +1508,165 @@ nsSecureBrowserUIImpl::GetSSLStatus(nsISSLStatus** _result) return NS_OK; } + +nsresult +nsSecureBrowserUIImpl::IsURLHTTPS(nsIURI* aURL, bool* value) +{ + *value = false; + + if (!aURL) + return NS_OK; + + return aURL->SchemeIs("https", value); +} + +nsresult +nsSecureBrowserUIImpl::IsURLJavaScript(nsIURI* aURL, bool* value) +{ + *value = false; + + if (!aURL) + return NS_OK; + + return aURL->SchemeIs("javascript", value); +} + +nsresult +nsSecureBrowserUIImpl::CheckPost(nsIURI *formURL, nsIURI *actionURL, bool *okayToPost) +{ + bool formSecure, actionSecure, actionJavaScript; + *okayToPost = true; + + nsresult rv = IsURLHTTPS(formURL, &formSecure); + if (NS_FAILED(rv)) + return rv; + + rv = IsURLHTTPS(actionURL, &actionSecure); + if (NS_FAILED(rv)) + return rv; + + rv = IsURLJavaScript(actionURL, &actionJavaScript); + if (NS_FAILED(rv)) + return rv; + + // If we are posting to a secure link, all is okay. + // It doesn't matter whether the currently viewed page is secure or not, + // because the data will be sent to a secure URL. + if (actionSecure) { + return NS_OK; + } + + // Action is a JavaScript call, not an actual post. That's okay too. + if (actionJavaScript) { + return NS_OK; + } + + // posting to insecure webpage from a secure webpage. + if (formSecure) { + *okayToPost = ConfirmPostToInsecureFromSecure(); + } + + return NS_OK; +} + +// +// Implementation of an nsIInterfaceRequestor for use +// as context for NSS calls +// +class nsUIContext : public nsIInterfaceRequestor +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIINTERFACEREQUESTOR + + explicit nsUIContext(nsIDOMWindow *window); + +protected: + virtual ~nsUIContext(); + +private: + nsCOMPtr mWindow; +}; + +NS_IMPL_ISUPPORTS(nsUIContext, nsIInterfaceRequestor) + +nsUIContext::nsUIContext(nsIDOMWindow *aWindow) +: mWindow(aWindow) +{ +} + +nsUIContext::~nsUIContext() +{ +} + +/* void getInterface (in nsIIDRef uuid, [iid_is (uuid), retval] out nsQIResult result); */ +NS_IMETHODIMP nsUIContext::GetInterface(const nsIID & uuid, void * *result) +{ + NS_ENSURE_TRUE(mWindow, NS_ERROR_FAILURE); + nsresult rv; + + if (uuid.Equals(NS_GET_IID(nsIPrompt))) { + nsCOMPtr window = do_QueryInterface(mWindow, &rv); + if (NS_FAILED(rv)) return rv; + + nsIPrompt *prompt; + + rv = window->GetPrompter(&prompt); + *result = prompt; + } else if (uuid.Equals(NS_GET_IID(nsIDOMWindow))) { + *result = mWindow; + NS_ADDREF ((nsISupports*) *result); + rv = NS_OK; + } else { + rv = NS_ERROR_NO_INTERFACE; + } + + return rv; +} + +bool +nsSecureBrowserUIImpl::GetNSSDialogs(nsCOMPtr & dialogs, + nsCOMPtr & ctx) +{ + if (!NS_IsMainThread()) { + NS_ERROR("nsSecureBrowserUIImpl::GetNSSDialogs called off the main thread"); + return false; + } + + dialogs = do_GetService(NS_SECURITYWARNINGDIALOGS_CONTRACTID); + if (!dialogs) + return false; + + nsCOMPtr window; + { + ReentrantMonitorAutoEnter lock(mReentrantMonitor); + window = do_QueryReferent(mWindow); + NS_ASSERTION(window, "Window has gone away?!"); + } + ctx = new nsUIContext(window); + + return true; +} + +/** + * ConfirmPostToInsecureFromSecure - returns true if + * the user approves the submit (or doesn't care). + * returns false on errors. + */ +bool nsSecureBrowserUIImpl:: +ConfirmPostToInsecureFromSecure() +{ + nsCOMPtr dialogs; + nsCOMPtr ctx; + + if (!GetNSSDialogs(dialogs, ctx)) { + return false; // Should this allow true for unimplemented? + } + + bool result; + + nsresult rv = dialogs->ConfirmPostToInsecureFromSecure(ctx, &result); + if (NS_FAILED(rv)) return false; + + return result; +} diff --git a/security/manager/boot/src/nsSecureBrowserUIImpl.h b/security/manager/boot/src/nsSecureBrowserUIImpl.h index 4dd0792b6ed..5f7b4edda05 100644 --- a/security/manager/boot/src/nsSecureBrowserUIImpl.h +++ b/security/manager/boot/src/nsSecureBrowserUIImpl.h @@ -14,10 +14,12 @@ #include "nsString.h" #include "nsIDOMElement.h" #include "nsIDOMWindow.h" +#include "nsIDOMHTMLFormElement.h" #include "nsISecureBrowserUI.h" #include "nsIDocShell.h" #include "nsIDocShellTreeItem.h" #include "nsIWebProgressListener.h" +#include "nsIFormSubmitObserver.h" #include "nsIURI.h" #include "nsISecurityEventSink.h" #include "nsWeakReference.h" @@ -27,7 +29,10 @@ #include "nsINetUtil.h" class nsISSLStatus; +class nsITransportSecurityInfo; +class nsISecurityWarningDialogs; class nsIChannel; +class nsIInterfaceRequestor; #define NS_SECURE_BROWSER_UI_CID \ { 0xcc75499a, 0x1dd1, 0x11b2, {0x8a, 0x82, 0xca, 0x41, 0x0a, 0xc9, 0x07, 0xb8}} @@ -35,6 +40,7 @@ class nsIChannel; class nsSecureBrowserUIImpl : public nsISecureBrowserUI, public nsIWebProgressListener, + public nsIFormSubmitObserver, public nsSupportsWeakReference, public nsISSLStatusProvider { @@ -45,8 +51,14 @@ public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIWEBPROGRESSLISTENER NS_DECL_NSISECUREBROWSERUI + NS_DECL_NSISSLSTATUSPROVIDER + NS_IMETHOD Notify(nsIDOMHTMLFormElement* formNode, nsIDOMWindow* window, + nsIURI *actionURL, bool* cancelSubmit) MOZ_OVERRIDE; + NS_IMETHOD NotifyInvalidSubmit(nsIDOMHTMLFormElement* formNode, + nsIArray* invalidElements) MOZ_OVERRIDE { return NS_OK; } + protected: virtual ~nsSecureBrowserUIImpl(); @@ -100,6 +112,20 @@ protected: nsCOMPtr mSSLStatus; nsCOMPtr mCurrentToplevelSecurityInfo; + nsresult CheckPost(nsIURI *formURI, nsIURI *actionURL, bool *okayToPost); + nsresult IsURLHTTPS(nsIURI* aURL, bool *value); + nsresult IsURLJavaScript(nsIURI* aURL, bool *value); + + bool ConfirmEnteringSecure(); + bool ConfirmEnteringWeak(); + bool ConfirmLeavingSecure(); + bool ConfirmMixedMode(); + bool ConfirmPostToInsecure(); + bool ConfirmPostToInsecureFromSecure(); + + bool GetNSSDialogs(nsCOMPtr & dialogs, + nsCOMPtr & window); + PLDHashTable mTransferringRequests; }; diff --git a/security/manager/boot/src/nsSecurityWarningDialogs.cpp b/security/manager/boot/src/nsSecurityWarningDialogs.cpp new file mode 100644 index 00000000000..110afc7b92d --- /dev/null +++ b/security/manager/boot/src/nsSecurityWarningDialogs.cpp @@ -0,0 +1,162 @@ +/* -*- 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 "nsSecurityWarningDialogs.h" +#include "nsIComponentManager.h" +#include "nsIServiceManager.h" +#include "nsReadableUtils.h" +#include "nsString.h" +#include "nsIPrompt.h" +#include "nsIInterfaceRequestor.h" +#include "nsIInterfaceRequestorUtils.h" +#include "nsIPrefService.h" +#include "nsIPrefBranch.h" +#include "nsThreadUtils.h" + +#include "mozilla/Telemetry.h" +#include "nsISecurityUITelemetry.h" + +NS_IMPL_ISUPPORTS(nsSecurityWarningDialogs, nsISecurityWarningDialogs) + +#define STRING_BUNDLE_URL "chrome://pipnss/locale/security.properties" + +nsSecurityWarningDialogs::nsSecurityWarningDialogs() +{ +} + +nsSecurityWarningDialogs::~nsSecurityWarningDialogs() +{ +} + +nsresult +nsSecurityWarningDialogs::Init() +{ + nsresult rv; + + mPrefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr service = + do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); + if (NS_FAILED(rv)) return rv; + + rv = service->CreateBundle(STRING_BUNDLE_URL, + getter_AddRefs(mStringBundle)); + return rv; +} + +NS_IMETHODIMP +nsSecurityWarningDialogs::ConfirmPostToInsecureFromSecure(nsIInterfaceRequestor *ctx, bool* _result) +{ + nsresult rv; + + // The Telemetry clickthrough constant is 1 more than the constant for the dialog. + rv = ConfirmDialog(ctx, nullptr, // No preference for this one - it's too important + MOZ_UTF16("PostToInsecureFromSecureMessage"), + nullptr, + nsISecurityUITelemetry::WARNING_CONFIRM_POST_TO_INSECURE_FROM_SECURE, + _result); + + return rv; +} + +nsresult +nsSecurityWarningDialogs::ConfirmDialog(nsIInterfaceRequestor *ctx, const char *prefName, + const char16_t *messageName, + const char16_t *showAgainName, + const uint32_t aBucket, + bool* _result) +{ + nsresult rv; + + // Get user's preference for this alert + // prefName, showAgainName are null if there is no preference for this dialog + bool prefValue = true; + + if (prefName) { + rv = mPrefBranch->GetBoolPref(prefName, &prefValue); + if (NS_FAILED(rv)) prefValue = true; + } + + // Stop if confirm is not requested + if (!prefValue) { + *_result = true; + return NS_OK; + } + + MOZ_ASSERT(NS_IsMainThread()); + mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI, aBucket); + // See AlertDialog() for a description of how showOnce works. + nsAutoCString showOncePref(prefName); + showOncePref += ".show_once"; + + bool showOnce = false; + mPrefBranch->GetBoolPref(showOncePref.get(), &showOnce); + + if (showOnce) + prefValue = false; + + // Get Prompt to use + nsCOMPtr prompt = do_GetInterface(ctx); + if (!prompt) return NS_ERROR_FAILURE; + + // Get messages strings from localization file + nsXPIDLString windowTitle, message, alertMe, cont; + + mStringBundle->GetStringFromName(MOZ_UTF16("Title"), + getter_Copies(windowTitle)); + mStringBundle->GetStringFromName(messageName, + getter_Copies(message)); + if (showAgainName) { + mStringBundle->GetStringFromName(showAgainName, + getter_Copies(alertMe)); + } + mStringBundle->GetStringFromName(MOZ_UTF16("Continue"), + getter_Copies(cont)); + // alertMe is allowed to be null + if (!windowTitle || !message || !cont) return NS_ERROR_FAILURE; + + // Replace # characters with newlines to lay out the dialog. + char16_t* msgchars = message.BeginWriting(); + + uint32_t i = 0; + for (i = 0; msgchars[i] != '\0'; i++) { + if (msgchars[i] == '#') { + msgchars[i] = '\n'; + } + } + + int32_t buttonPressed; + + rv = prompt->ConfirmEx(windowTitle, + message, + (nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_0) + + (nsIPrompt::BUTTON_TITLE_CANCEL * nsIPrompt::BUTTON_POS_1), + cont, + nullptr, + nullptr, + alertMe, + &prefValue, + &buttonPressed); + + if (NS_FAILED(rv)) return rv; + + *_result = (buttonPressed != 1); + if (*_result) { + // For confirmation dialogs, the clickthrough constant is 1 more + // than the constant for the dialog. + mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI, aBucket + 1); + } + + if (!prefValue && prefName) { + mPrefBranch->SetBoolPref(prefName, false); + } else if (prefValue && showOnce) { + mPrefBranch->SetBoolPref(showOncePref.get(), false); + } + + return rv; +} + diff --git a/security/manager/boot/src/nsSecurityWarningDialogs.h b/security/manager/boot/src/nsSecurityWarningDialogs.h new file mode 100644 index 00000000000..0a9313bae92 --- /dev/null +++ b/security/manager/boot/src/nsSecurityWarningDialogs.h @@ -0,0 +1,45 @@ +/* -*- 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/. */ + +#ifndef nsSecurityWarningDialogs_h +#define nsSecurityWarningDialogs_h + +#include "nsISecurityWarningDialogs.h" +#include "nsIPrefBranch.h" +#include "nsIStringBundle.h" +#include "nsCOMPtr.h" + +class nsSecurityWarningDialogs : public nsISecurityWarningDialogs +{ +public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSISECURITYWARNINGDIALOGS + + nsSecurityWarningDialogs(); + + nsresult Init(); + +protected: + virtual ~nsSecurityWarningDialogs(); + + nsresult AlertDialog(nsIInterfaceRequestor *ctx, const char *prefName, + const char16_t *messageName, + const char16_t *showAgainName, + bool aAsync, const uint32_t aBucket); + nsresult ConfirmDialog(nsIInterfaceRequestor *ctx, const char *prefName, + const char16_t *messageName, + const char16_t *showAgainName, const uint32_t aBucket, + bool* _result); + nsCOMPtr mStringBundle; + nsCOMPtr mPrefBranch; +}; + +#define NS_SECURITYWARNINGDIALOGS_CID \ + { /* 8d995d4f-adcc-4159-b7f1-e94af72eeb88 */ \ + 0x8d995d4f, 0xadcc, 0x4159, \ + {0xb7, 0xf1, 0xe9, 0x4a, 0xf7, 0x2e, 0xeb, 0x88} } + +#endif diff --git a/security/manager/locales/en-US/chrome/pipnss/security.properties b/security/manager/locales/en-US/chrome/pipnss/security.properties new file mode 100644 index 00000000000..50af92694e0 --- /dev/null +++ b/security/manager/locales/en-US/chrome/pipnss/security.properties @@ -0,0 +1,7 @@ +# 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/. + +Title=Security Warning +PostToInsecureFromSecureMessage=Although this page is encrypted, the information you have entered is to be sent over an unencrypted connection and could easily be read by a third party.##Are you sure you want to continue sending this information?## +Continue=Continue diff --git a/security/manager/locales/jar.mn b/security/manager/locales/jar.mn index 9b5c2da4461..66c1535f3b6 100644 --- a/security/manager/locales/jar.mn +++ b/security/manager/locales/jar.mn @@ -9,6 +9,7 @@ % locale pippki @AB_CD@ %locale/@AB_CD@/pippki/ locale/@AB_CD@/pipnss/pipnss.properties (%chrome/pipnss/pipnss.properties) locale/@AB_CD@/pipnss/nsserrors.properties (%chrome/pipnss/nsserrors.properties) + locale/@AB_CD@/pipnss/security.properties (%chrome/pipnss/security.properties) locale/@AB_CD@/pippki/pippki.dtd (%chrome/pippki/pippki.dtd) locale/@AB_CD@/pippki/pippki.properties (%chrome/pippki/pippki.properties) locale/@AB_CD@/pippki/certManager.dtd (%chrome/pippki/certManager.dtd) diff --git a/toolkit/locales/en-US/chrome/global/browser.properties b/toolkit/locales/en-US/chrome/global/browser.properties index 2b315062918..0e5409fd1cc 100644 --- a/toolkit/locales/en-US/chrome/global/browser.properties +++ b/toolkit/locales/en-US/chrome/global/browser.properties @@ -8,7 +8,3 @@ browsewithcaret.checkLabel=Pressing F7 turns Caret Browsing on or off. This feat browsewithcaret.checkButtonLabel=Yes plainText.wordWrap=Wrap Long Lines - -formPostSecureToInsecureWarning.title = Security Warning -formPostSecureToInsecureWarning.message = The information you have entered on this page will be sent over an insecure connection and could be read by a third party.\n\nAre you sure you want to send this information? -formPostSecureToInsecureWarning.continue = Continue