backout cd0ec3afca5a (bug 832837) for mochitest bustage
authorDavid Keeler <dkeeler@mozilla.com>
Fri, 30 Jan 2015 11:25:24 -0800
changeset 240223 41e3793d80e2a9a238234f84db67652a168edebc
parent 240222 3b36478f35fd05f902dbadb10af04b4031c9ba61
child 240224 42efd85dcb7d669da5d2da31a04b233fe995d0e3
push id525
push usermartin.thomson@gmail.com
push dateFri, 30 Jan 2015 21:02:41 +0000
bugs832837
milestone38.0a1
backs outcd0ec3afca5a3f969f511da89a2a91264c5d58e6
backout cd0ec3afca5a (bug 832837) for mochitest bustage
CLOBBER
dom/html/HTMLFormElement.cpp
security/manager/boot/public/moz.build
security/manager/boot/public/nsISecurityWarningDialogs.idl
security/manager/boot/src/moz.build
security/manager/boot/src/nsBOOTModule.cpp
security/manager/boot/src/nsSecureBrowserUIImpl.cpp
security/manager/boot/src/nsSecureBrowserUIImpl.h
security/manager/boot/src/nsSecurityWarningDialogs.cpp
security/manager/boot/src/nsSecurityWarningDialogs.h
security/manager/locales/en-US/chrome/pipnss/security.properties
security/manager/locales/jar.mn
toolkit/locales/en-US/chrome/global/browser.properties
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,9 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # 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.
--- a/dom/html/HTMLFormElement.cpp
+++ b/dom/html/HTMLFormElement.cpp
@@ -15,44 +15,41 @@
 #include "mozilla/dom/HTMLFormElementBinding.h"
 #include "mozilla/Move.h"
 #include "nsIHTMLDocument.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
 #include "nsIDocument.h"
 #include "nsIFormControlFrame.h"
+#include "nsISecureBrowserUI.h"
 #include "nsError.h"
 #include "nsContentUtils.h"
 #include "nsInterfaceHashtable.h"
 #include "nsContentList.h"
 #include "nsCOMArray.h"
 #include "nsAutoPtr.h"
 #include "nsTArray.h"
 #include "nsIMutableArray.h"
 #include "nsIFormAutofillContentService.h"
 #include "mozilla/BinarySearch.h"
 
 // form submission
-#include "mozilla/Telemetry.h"
 #include "nsIFormSubmitObserver.h"
 #include "nsIObserverService.h"
 #include "nsICategoryManager.h"
 #include "nsCategoryManagerUtils.h"
 #include "nsISimpleEnumerator.h"
 #include "nsRange.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsNetUtil.h"
 #include "nsIWebProgress.h"
 #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"
 #include "nsIRadioVisitor.h"
 #include "RadioNodeList.h"
 
 #include "nsLayoutUtils.h"
 
@@ -875,102 +872,47 @@ HTMLFormElement::NotifySubmitObservers(n
                                   NS_FIRST_FORMSUBMIT_CATEGORY);
   }
 
   // XXXbz what do the submit observers actually want?  The window
   // of the document this is shown in?  Or something else?
   // sXBL/XBL2 issue
   nsCOMPtr<nsPIDOMWindow> window = OwnerDoc()->GetWindow();
 
-  nsCOMPtr<nsIURI> 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<nsIPromptService> promptSvc =
-      do_GetService("@mozilla.org/embedcomp/prompt-service;1");
-    if (!promptSvc) {
-      return NS_ERROR_FAILURE;
-    }
-    nsCOMPtr<nsIStringBundle> stringBundle;
-    nsCOMPtr<nsIStringBundleService> stringBundleService =
-      mozilla::services::GetStringBundleService();
-    if (!stringBundleService) {
-      return NS_ERROR_FAILURE;
+  // Notify the secure browser UI, if any, that the form is being submitted.
+  nsCOMPtr<nsIDocShell> docshell = OwnerDoc()->GetDocShell();
+  if (docshell && !aEarlyNotify) {
+    nsCOMPtr<nsISecureBrowserUI> secureUI;
+    docshell->GetSecurityUI(getter_AddRefs(secureUI));
+    nsCOMPtr<nsIFormSubmitObserver> formSubmitObserver =
+      do_QueryInterface(secureUI);
+    if (formSubmitObserver) {
+      nsresult rv = formSubmitObserver->Notify(this,
+                                               window,
+                                               aActionURL,
+                                               aCancelSubmit);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      if (*aCancelSubmit) {
+        return NS_OK;
+      }
     }
-    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.
   nsCOMPtr<nsIObserverService> service =
     mozilla::services::GetObserverService();
   if (!service)
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsISimpleEnumerator> 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) {
     nsCOMPtr<nsISupports> inst;
     *aCancelSubmit = false;
 
     bool loop = true;
     while (NS_SUCCEEDED(theEnum->HasMoreElements(&loop)) && loop) {
--- a/security/manager/boot/public/moz.build
+++ b/security/manager/boot/public/moz.build
@@ -3,13 +3,14 @@
 # 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/.
 
 XPIDL_SOURCES += [
     'nsIBufEntropyCollector.idl',
     'nsICertBlocklist.idl',
     'nsISecurityUITelemetry.idl',
+    'nsISecurityWarningDialogs.idl',
     'nsISSLStatusProvider.idl',
 ]
 
 XPIDL_MODULE = 'pipboot'
 
new file mode 100644
--- /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"
+%}
--- a/security/manager/boot/src/moz.build
+++ b/security/manager/boot/src/moz.build
@@ -10,16 +10,17 @@ EXPORTS.mozilla += [
 
 UNIFIED_SOURCES += [
     'CertBlocklist.cpp',
     'DataStorage.cpp',
     'nsBOOTModule.cpp',
     'nsEntropyCollector.cpp',
     'nsSecureBrowserUIImpl.cpp',
     'nsSecurityHeaderParser.cpp',
+    'nsSecurityWarningDialogs.cpp',
     'nsSiteSecurityService.cpp',
     'PublicKeyPinningService.cpp',
     'RootCertificateTelemetryUtils.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '../../../pkix/include',
 ]
--- a/security/manager/boot/src/nsBOOTModule.cpp
+++ b/security/manager/boot/src/nsBOOTModule.cpp
@@ -3,38 +3,43 @@
  * 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 "mozilla/ModuleUtils.h"
 
 #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},
   { nullptr }
 };
 
 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 },
   { nullptr }
 };
 
 static const mozilla::Module kBootModule = {
   mozilla::Module::kVersion,
--- a/security/manager/boot/src/nsSecureBrowserUIImpl.cpp
+++ b/security/manager/boot/src/nsSecureBrowserUIImpl.cpp
@@ -4,34 +4,41 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nspr.h"
 #include "prlog.h"
 
 #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"
 #include "nsIHttpChannel.h"
 #include "nsIFileChannel.h"
 #include "nsIWyciwygChannel.h"
 #include "nsIFTPChannel.h"
 #include "nsITransportSecurityInfo.h"
 #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"
 #include "nsNetUtil.h"
 #include "nsNetCID.h"
 #include "nsCRT.h"
 
 using namespace mozilla;
@@ -129,16 +136,17 @@ nsSecureBrowserUIImpl::~nsSecureBrowserU
   if (mTransferringRequests.IsInitialized()) {
     PL_DHashTableFinish(&mTransferringRequests);
   }
 }
 
 NS_IMPL_ISUPPORTS(nsSecureBrowserUIImpl,
                   nsISecureBrowserUI,
                   nsIWebProgressListener,
+                  nsIFormSubmitObserver,
                   nsISupportsWeakReference,
                   nsISSLStatusProvider)
 
 NS_IMETHODIMP
 nsSecureBrowserUIImpl::Init(nsIDOMWindow *aWindow)
 {
 
 #ifdef PR_LOGGING
@@ -298,16 +306,35 @@ nsSecureBrowserUIImpl::MapInternalToExte
 NS_IMETHODIMP
 nsSecureBrowserUIImpl::SetDocShell(nsIDocShell *aDocShell)
 {
   nsresult rv;
   mDocShell = do_GetWeakReference(aDocShell, &rv);
   return rv;
 }
 
+static nsresult IsChildOfDomWindow(nsIDOMWindow *parent, nsIDOMWindow *child,
+                                   bool* value)
+{
+  *value = false;
+  
+  if (parent == child) {
+    *value = true;
+    return NS_OK;
+  }
+  
+  nsCOMPtr<nsIDOMWindow> 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)
 {
   nsresult res;
   uint32_t securityState;
 
   nsCOMPtr<nsITransportSecurityInfo> psmInfo(do_QueryInterface(info));
   if (!psmInfo) {
@@ -351,16 +378,82 @@ static uint32_t GetSecurityStateFromSecu
   }
 
   PR_LOG(gSecureDocLog, PR_LOG_DEBUG, ("SecureUI: GetSecurityState: - Returning %d\n", 
                                        securityState));
   return securityState;
 }
 
 
+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<nsIContent> formNode = do_QueryInterface(aDOMForm);
+
+  nsCOMPtr<nsIDocument> document = formNode->GetComposedDoc();
+  if (!document) return NS_OK;
+
+  nsIPrincipal *principal = formNode->NodePrincipal();
+  
+  if (!principal)
+  {
+    *cancelSubmit = true;
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsIURI> formURL;
+  if (NS_FAILED(principal->GetURI(getter_AddRefs(formURL))) ||
+      !formURL)
+  {
+    formURL = document->GetDocumentURI();
+  }
+
+  nsCOMPtr<nsIDOMWindow> 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<nsIDOMWindow> 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,
                                         nsIRequest* aRequest,
                                         int32_t aCurSelfProgress,
                                         int32_t aMaxSelfProgress,
                                         int32_t aCurTotalProgress,
                                         int32_t aMaxTotalProgress)
@@ -1410,8 +1503,170 @@ nsSecureBrowserUIImpl::GetSSLStatus(nsIS
       return NS_OK;
   }
  
   *_result = mSSLStatus;
   NS_IF_ADDREF(*_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<nsIDOMWindow> 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<nsIDOMWindow> 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<nsISecurityWarningDialogs> & dialogs,
+                                     nsCOMPtr<nsIInterfaceRequestor> & 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<nsIDOMWindow> 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<nsISecurityWarningDialogs> dialogs;
+  nsCOMPtr<nsIInterfaceRequestor> 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;
+}
--- a/security/manager/boot/src/nsSecureBrowserUIImpl.h
+++ b/security/manager/boot/src/nsSecureBrowserUIImpl.h
@@ -9,49 +9,61 @@
 #ifdef DEBUG
 #include "mozilla/Atomics.h"
 #endif
 #include "mozilla/ReentrantMonitor.h"
 #include "nsCOMPtr.h"
 #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"
 #include "nsISSLStatusProvider.h"
 #include "nsIAssociatedContentSecurity.h"
 #include "pldhash.h"
 #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}}
 
 
 class nsSecureBrowserUIImpl : public nsISecureBrowserUI,
                               public nsIWebProgressListener,
+                              public nsIFormSubmitObserver,
                               public nsSupportsWeakReference,
                               public nsISSLStatusProvider
 {
 public:
   
   nsSecureBrowserUIImpl();
   
   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();
 
   mozilla::ReentrantMonitor mReentrantMonitor;
   
   nsWeakPtr mWindow;
   nsWeakPtr mDocShell;
   nsCOMPtr<nsINetUtil> mIOService;
@@ -95,13 +107,27 @@ protected:
   void UpdateSubrequestMembers(nsISupports* securityInfo, nsIRequest* request);
 
   void ObtainEventSink(nsIChannel *channel, 
                        nsCOMPtr<nsISecurityEventSink> &sink);
 
   nsCOMPtr<nsISSLStatus> mSSLStatus;
   nsCOMPtr<nsISupports> 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<nsISecurityWarningDialogs> & dialogs,
+                     nsCOMPtr<nsIInterfaceRequestor> & window);
+
   PLDHashTable mTransferringRequests;
 };
 
 
 #endif /* nsSecureBrowserUIImpl_h_ */
new file mode 100644
--- /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<nsIStringBundleService> 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<nsIPrompt> 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;
+}
+
new file mode 100644
--- /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<nsIStringBundle> mStringBundle;
+  nsCOMPtr<nsIPrefBranch> mPrefBranch;
+};
+
+#define NS_SECURITYWARNINGDIALOGS_CID \
+ { /* 8d995d4f-adcc-4159-b7f1-e94af72eeb88 */       \
+  0x8d995d4f, 0xadcc, 0x4159,                       \
+ {0xb7, 0xf1, 0xe9, 0x4a, 0xf7, 0x2e, 0xeb, 0x88} }
+
+#endif
new file mode 100644
--- /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
--- a/security/manager/locales/jar.mn
+++ b/security/manager/locales/jar.mn
@@ -4,12 +4,13 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
 @AB_CD@.jar:
 % locale pipnss @AB_CD@ %locale/@AB_CD@/pipnss/
 % 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)
   locale/@AB_CD@/pippki/deviceManager.dtd     (%chrome/pippki/deviceManager.dtd)
--- a/toolkit/locales/en-US/chrome/global/browser.properties
+++ b/toolkit/locales/en-US/chrome/global/browser.properties
@@ -3,12 +3,8 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 browsewithcaret.checkMsg=Do not show me this dialog box again.
 browsewithcaret.checkWindowTitle=Caret Browsing
 browsewithcaret.checkLabel=Pressing F7 turns Caret Browsing on or off. This feature places a moveable cursor in web pages, allowing you to select text with the keyboard. Do you want to turn Caret Browsing on?
 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