|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * |
|
3 * This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #include "nsSecurityWarningDialogs.h" |
|
8 #include "nsIComponentManager.h" |
|
9 #include "nsIServiceManager.h" |
|
10 #include "nsReadableUtils.h" |
|
11 #include "nsString.h" |
|
12 #include "nsIPrompt.h" |
|
13 #include "nsIInterfaceRequestor.h" |
|
14 #include "nsIInterfaceRequestorUtils.h" |
|
15 #include "nsIPrefService.h" |
|
16 #include "nsIPrefBranch.h" |
|
17 #include "nsThreadUtils.h" |
|
18 |
|
19 #include "mozilla/Telemetry.h" |
|
20 #include "nsISecurityUITelemetry.h" |
|
21 |
|
22 NS_IMPL_ISUPPORTS(nsSecurityWarningDialogs, nsISecurityWarningDialogs) |
|
23 |
|
24 #define STRING_BUNDLE_URL "chrome://pipnss/locale/security.properties" |
|
25 |
|
26 nsSecurityWarningDialogs::nsSecurityWarningDialogs() |
|
27 { |
|
28 } |
|
29 |
|
30 nsSecurityWarningDialogs::~nsSecurityWarningDialogs() |
|
31 { |
|
32 } |
|
33 |
|
34 nsresult |
|
35 nsSecurityWarningDialogs::Init() |
|
36 { |
|
37 nsresult rv; |
|
38 |
|
39 mPrefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); |
|
40 if (NS_FAILED(rv)) return rv; |
|
41 |
|
42 nsCOMPtr<nsIStringBundleService> service = |
|
43 do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); |
|
44 if (NS_FAILED(rv)) return rv; |
|
45 |
|
46 rv = service->CreateBundle(STRING_BUNDLE_URL, |
|
47 getter_AddRefs(mStringBundle)); |
|
48 return rv; |
|
49 } |
|
50 |
|
51 NS_IMETHODIMP |
|
52 nsSecurityWarningDialogs::ConfirmPostToInsecureFromSecure(nsIInterfaceRequestor *ctx, bool* _result) |
|
53 { |
|
54 nsresult rv; |
|
55 |
|
56 // The Telemetry clickthrough constant is 1 more than the constant for the dialog. |
|
57 rv = ConfirmDialog(ctx, nullptr, // No preference for this one - it's too important |
|
58 MOZ_UTF16("PostToInsecureFromSecureMessage"), |
|
59 nullptr, |
|
60 nsISecurityUITelemetry::WARNING_CONFIRM_POST_TO_INSECURE_FROM_SECURE, |
|
61 _result); |
|
62 |
|
63 return rv; |
|
64 } |
|
65 |
|
66 nsresult |
|
67 nsSecurityWarningDialogs::ConfirmDialog(nsIInterfaceRequestor *ctx, const char *prefName, |
|
68 const char16_t *messageName, |
|
69 const char16_t *showAgainName, |
|
70 const uint32_t aBucket, |
|
71 bool* _result) |
|
72 { |
|
73 nsresult rv; |
|
74 |
|
75 // Get user's preference for this alert |
|
76 // prefName, showAgainName are null if there is no preference for this dialog |
|
77 bool prefValue = true; |
|
78 |
|
79 if (prefName) { |
|
80 rv = mPrefBranch->GetBoolPref(prefName, &prefValue); |
|
81 if (NS_FAILED(rv)) prefValue = true; |
|
82 } |
|
83 |
|
84 // Stop if confirm is not requested |
|
85 if (!prefValue) { |
|
86 *_result = true; |
|
87 return NS_OK; |
|
88 } |
|
89 |
|
90 MOZ_ASSERT(NS_IsMainThread()); |
|
91 mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI, aBucket); |
|
92 // See AlertDialog() for a description of how showOnce works. |
|
93 nsAutoCString showOncePref(prefName); |
|
94 showOncePref += ".show_once"; |
|
95 |
|
96 bool showOnce = false; |
|
97 mPrefBranch->GetBoolPref(showOncePref.get(), &showOnce); |
|
98 |
|
99 if (showOnce) |
|
100 prefValue = false; |
|
101 |
|
102 // Get Prompt to use |
|
103 nsCOMPtr<nsIPrompt> prompt = do_GetInterface(ctx); |
|
104 if (!prompt) return NS_ERROR_FAILURE; |
|
105 |
|
106 // Get messages strings from localization file |
|
107 nsXPIDLString windowTitle, message, alertMe, cont; |
|
108 |
|
109 mStringBundle->GetStringFromName(MOZ_UTF16("Title"), |
|
110 getter_Copies(windowTitle)); |
|
111 mStringBundle->GetStringFromName(messageName, |
|
112 getter_Copies(message)); |
|
113 if (showAgainName) { |
|
114 mStringBundle->GetStringFromName(showAgainName, |
|
115 getter_Copies(alertMe)); |
|
116 } |
|
117 mStringBundle->GetStringFromName(MOZ_UTF16("Continue"), |
|
118 getter_Copies(cont)); |
|
119 // alertMe is allowed to be null |
|
120 if (!windowTitle || !message || !cont) return NS_ERROR_FAILURE; |
|
121 |
|
122 // Replace # characters with newlines to lay out the dialog. |
|
123 char16_t* msgchars = message.BeginWriting(); |
|
124 |
|
125 uint32_t i = 0; |
|
126 for (i = 0; msgchars[i] != '\0'; i++) { |
|
127 if (msgchars[i] == '#') { |
|
128 msgchars[i] = '\n'; |
|
129 } |
|
130 } |
|
131 |
|
132 int32_t buttonPressed; |
|
133 |
|
134 rv = prompt->ConfirmEx(windowTitle, |
|
135 message, |
|
136 (nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_0) + |
|
137 (nsIPrompt::BUTTON_TITLE_CANCEL * nsIPrompt::BUTTON_POS_1), |
|
138 cont, |
|
139 nullptr, |
|
140 nullptr, |
|
141 alertMe, |
|
142 &prefValue, |
|
143 &buttonPressed); |
|
144 |
|
145 if (NS_FAILED(rv)) return rv; |
|
146 |
|
147 *_result = (buttonPressed != 1); |
|
148 if (*_result) { |
|
149 // For confirmation dialogs, the clickthrough constant is 1 more |
|
150 // than the constant for the dialog. |
|
151 mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI, aBucket + 1); |
|
152 } |
|
153 |
|
154 if (!prefValue && prefName) { |
|
155 mPrefBranch->SetBoolPref(prefName, false); |
|
156 } else if (prefValue && showOnce) { |
|
157 mPrefBranch->SetBoolPref(showOncePref.get(), false); |
|
158 } |
|
159 |
|
160 return rv; |
|
161 } |
|
162 |