1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : *
3 : * ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is mozilla.org code.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Netscape Communications Corporation.
20 : * Portions created by the Initial Developer are Copyright (C) 2001
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Terry Hayes <thayes@netscape.com>
25 : * Javier Delgadillo <javi@netscape.com>
26 : *
27 : * Alternatively, the contents of this file may be used under the terms of
28 : * either the GNU General Public License Version 2 or later (the "GPL"), or
29 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 : * in which case the provisions of the GPL or the LGPL are applicable instead
31 : * of those above. If you wish to allow use of your version of this file only
32 : * under the terms of either the GPL or the LGPL, and not to allow others to
33 : * use your version of this file under the terms of the MPL, indicate your
34 : * decision by deleting the provisions above and replace them with the notice
35 : * and other provisions required by the GPL or the LGPL. If you do not delete
36 : * the provisions above, a recipient may use your version of this file under
37 : * the terms of any one of the MPL, the GPL or the LGPL.
38 : *
39 : * ***** END LICENSE BLOCK ***** */
40 :
41 : #include "nsSecurityWarningDialogs.h"
42 : #include "nsIComponentManager.h"
43 : #include "nsIServiceManager.h"
44 : #include "nsReadableUtils.h"
45 : #include "nsString.h"
46 : #include "nsIPrompt.h"
47 : #include "nsIInterfaceRequestor.h"
48 : #include "nsIInterfaceRequestorUtils.h"
49 : #include "nsIPrefService.h"
50 : #include "nsIPrefBranch.h"
51 : #include "nsThreadUtils.h"
52 : #include "nsAutoPtr.h"
53 :
54 0 : NS_IMPL_THREADSAFE_ISUPPORTS1(nsSecurityWarningDialogs, nsISecurityWarningDialogs)
55 :
56 : #define STRING_BUNDLE_URL "chrome://pipnss/locale/security.properties"
57 :
58 : #define ENTER_SITE_PREF "security.warn_entering_secure"
59 : #define WEAK_SITE_PREF "security.warn_entering_weak"
60 : #define LEAVE_SITE_PREF "security.warn_leaving_secure"
61 : #define MIXEDCONTENT_PREF "security.warn_viewing_mixed"
62 : #define INSECURE_SUBMIT_PREF "security.warn_submit_insecure"
63 :
64 0 : nsSecurityWarningDialogs::nsSecurityWarningDialogs()
65 : {
66 0 : }
67 :
68 0 : nsSecurityWarningDialogs::~nsSecurityWarningDialogs()
69 : {
70 0 : }
71 :
72 : nsresult
73 0 : nsSecurityWarningDialogs::Init()
74 : {
75 : nsresult rv;
76 :
77 0 : mPrefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
78 0 : if (NS_FAILED(rv)) return rv;
79 :
80 : nsCOMPtr<nsIStringBundleService> service =
81 0 : do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
82 0 : if (NS_FAILED(rv)) return rv;
83 :
84 0 : rv = service->CreateBundle(STRING_BUNDLE_URL,
85 0 : getter_AddRefs(mStringBundle));
86 0 : return rv;
87 : }
88 :
89 : NS_IMETHODIMP
90 0 : nsSecurityWarningDialogs::ConfirmEnteringSecure(nsIInterfaceRequestor *ctx, bool *_retval)
91 : {
92 : nsresult rv;
93 :
94 : rv = AlertDialog(ctx, ENTER_SITE_PREF,
95 0 : NS_LITERAL_STRING("EnterSecureMessage").get(),
96 0 : NS_LITERAL_STRING("EnterSecureShowAgain").get(),
97 0 : false);
98 :
99 0 : *_retval = true;
100 0 : return rv;
101 : }
102 :
103 : NS_IMETHODIMP
104 0 : nsSecurityWarningDialogs::ConfirmEnteringWeak(nsIInterfaceRequestor *ctx, bool *_retval)
105 : {
106 : nsresult rv;
107 :
108 : rv = AlertDialog(ctx, WEAK_SITE_PREF,
109 0 : NS_LITERAL_STRING("WeakSecureMessage").get(),
110 0 : NS_LITERAL_STRING("WeakSecureShowAgain").get(),
111 0 : false);
112 :
113 0 : *_retval = true;
114 0 : return rv;
115 : }
116 :
117 : NS_IMETHODIMP
118 0 : nsSecurityWarningDialogs::ConfirmLeavingSecure(nsIInterfaceRequestor *ctx, bool *_retval)
119 : {
120 : nsresult rv;
121 :
122 : rv = AlertDialog(ctx, LEAVE_SITE_PREF,
123 0 : NS_LITERAL_STRING("LeaveSecureMessage").get(),
124 0 : NS_LITERAL_STRING("LeaveSecureShowAgain").get(),
125 0 : false);
126 :
127 0 : *_retval = true;
128 0 : return rv;
129 : }
130 :
131 :
132 : NS_IMETHODIMP
133 0 : nsSecurityWarningDialogs::ConfirmMixedMode(nsIInterfaceRequestor *ctx, bool *_retval)
134 : {
135 : nsresult rv;
136 :
137 : rv = AlertDialog(ctx, MIXEDCONTENT_PREF,
138 0 : NS_LITERAL_STRING("MixedContentMessage").get(),
139 0 : NS_LITERAL_STRING("MixedContentShowAgain").get(),
140 0 : true);
141 :
142 0 : *_retval = true;
143 0 : return rv;
144 : }
145 :
146 : class nsAsyncAlert : public nsRunnable
147 0 : {
148 : public:
149 0 : nsAsyncAlert(nsIPrompt* aPrompt,
150 : const char* aPrefName,
151 : const PRUnichar* aDialogMessageName,
152 : const PRUnichar* aShowAgainName,
153 : nsIPrefBranch* aPrefBranch,
154 : nsIStringBundle* aStringBundle)
155 : : mPrompt(aPrompt), mPrefName(aPrefName),
156 : mDialogMessageName(aDialogMessageName),
157 : mShowAgainName(aShowAgainName), mPrefBranch(aPrefBranch),
158 0 : mStringBundle(aStringBundle) {}
159 : NS_IMETHOD Run();
160 :
161 : protected:
162 : nsCOMPtr<nsIPrompt> mPrompt;
163 : nsCString mPrefName;
164 : nsString mDialogMessageName;
165 : nsString mShowAgainName;
166 : nsCOMPtr<nsIPrefBranch> mPrefBranch;
167 : nsCOMPtr<nsIStringBundle> mStringBundle;
168 : };
169 :
170 : NS_IMETHODIMP
171 0 : nsAsyncAlert::Run()
172 : {
173 : nsresult rv;
174 :
175 : // Get user's preference for this alert
176 : bool prefValue;
177 0 : rv = mPrefBranch->GetBoolPref(mPrefName.get(), &prefValue);
178 0 : if (NS_FAILED(rv)) prefValue = true;
179 :
180 : // Stop if alert is not requested
181 0 : if (!prefValue) return NS_OK;
182 :
183 : // Check for a show-once pref for this dialog.
184 : // If the show-once pref is set to true:
185 : // - The default value of the "show every time" checkbox is unchecked
186 : // - If the user checks the checkbox, we clear the show-once pref.
187 :
188 0 : nsCAutoString showOncePref(mPrefName);
189 0 : showOncePref += ".show_once";
190 :
191 0 : bool showOnce = false;
192 0 : mPrefBranch->GetBoolPref(showOncePref.get(), &showOnce);
193 :
194 0 : if (showOnce)
195 0 : prefValue = false;
196 :
197 : // Get messages strings from localization file
198 0 : nsXPIDLString windowTitle, message, dontShowAgain;
199 :
200 0 : mStringBundle->GetStringFromName(NS_LITERAL_STRING("Title").get(),
201 0 : getter_Copies(windowTitle));
202 0 : mStringBundle->GetStringFromName(mDialogMessageName.get(),
203 0 : getter_Copies(message));
204 0 : mStringBundle->GetStringFromName(mShowAgainName.get(),
205 0 : getter_Copies(dontShowAgain));
206 0 : if (!windowTitle || !message || !dontShowAgain) return NS_ERROR_FAILURE;
207 :
208 0 : rv = mPrompt->AlertCheck(windowTitle, message, dontShowAgain, &prefValue);
209 0 : if (NS_FAILED(rv)) return rv;
210 :
211 0 : if (!prefValue) {
212 0 : mPrefBranch->SetBoolPref(mPrefName.get(), false);
213 0 : } else if (showOnce) {
214 0 : mPrefBranch->SetBoolPref(showOncePref.get(), false);
215 : }
216 :
217 0 : return rv;
218 : }
219 :
220 :
221 : nsresult
222 0 : nsSecurityWarningDialogs::AlertDialog(nsIInterfaceRequestor* aCtx,
223 : const char* aPrefName,
224 : const PRUnichar* aDialogMessageName,
225 : const PRUnichar* aShowAgainName,
226 : bool aAsync)
227 : {
228 : // Get Prompt to use
229 0 : nsCOMPtr<nsIPrompt> prompt = do_GetInterface(aCtx);
230 0 : if (!prompt) return NS_ERROR_FAILURE;
231 :
232 : nsRefPtr<nsAsyncAlert> alert = new nsAsyncAlert(prompt,
233 : aPrefName,
234 : aDialogMessageName,
235 : aShowAgainName,
236 : mPrefBranch,
237 0 : mStringBundle);
238 0 : NS_ENSURE_TRUE(alert, NS_ERROR_OUT_OF_MEMORY);
239 0 : return aAsync ? NS_DispatchToCurrentThread(alert) : alert->Run();
240 : }
241 :
242 :
243 :
244 : NS_IMETHODIMP
245 0 : nsSecurityWarningDialogs::ConfirmPostToInsecure(nsIInterfaceRequestor *ctx, bool* _result)
246 : {
247 : nsresult rv;
248 :
249 : rv = ConfirmDialog(ctx, INSECURE_SUBMIT_PREF,
250 0 : NS_LITERAL_STRING("PostToInsecureFromInsecureMessage").get(),
251 0 : NS_LITERAL_STRING("PostToInsecureFromInsecureShowAgain").get(),
252 0 : _result);
253 :
254 0 : return rv;
255 : }
256 :
257 : NS_IMETHODIMP
258 0 : nsSecurityWarningDialogs::ConfirmPostToInsecureFromSecure(nsIInterfaceRequestor *ctx, bool* _result)
259 : {
260 : nsresult rv;
261 :
262 : rv = ConfirmDialog(ctx, nsnull, // No preference for this one - it's too important
263 0 : NS_LITERAL_STRING("PostToInsecureFromSecureMessage").get(),
264 : nsnull,
265 0 : _result);
266 :
267 0 : return rv;
268 : }
269 :
270 : nsresult
271 0 : nsSecurityWarningDialogs::ConfirmDialog(nsIInterfaceRequestor *ctx, const char *prefName,
272 : const PRUnichar *messageName,
273 : const PRUnichar *showAgainName,
274 : bool* _result)
275 : {
276 : nsresult rv;
277 :
278 : // Get user's preference for this alert
279 : // prefName, showAgainName are null if there is no preference for this dialog
280 0 : bool prefValue = true;
281 :
282 0 : if (prefName != nsnull) {
283 0 : rv = mPrefBranch->GetBoolPref(prefName, &prefValue);
284 0 : if (NS_FAILED(rv)) prefValue = true;
285 : }
286 :
287 : // Stop if confirm is not requested
288 0 : if (!prefValue) {
289 0 : *_result = true;
290 0 : return NS_OK;
291 : }
292 :
293 : // See AlertDialog() for a description of how showOnce works.
294 0 : nsCAutoString showOncePref(prefName);
295 0 : showOncePref += ".show_once";
296 :
297 0 : bool showOnce = false;
298 0 : mPrefBranch->GetBoolPref(showOncePref.get(), &showOnce);
299 :
300 0 : if (showOnce)
301 0 : prefValue = false;
302 :
303 : // Get Prompt to use
304 0 : nsCOMPtr<nsIPrompt> prompt = do_GetInterface(ctx);
305 0 : if (!prompt) return NS_ERROR_FAILURE;
306 :
307 : // Get messages strings from localization file
308 0 : nsXPIDLString windowTitle, message, alertMe, cont;
309 :
310 0 : mStringBundle->GetStringFromName(NS_LITERAL_STRING("Title").get(),
311 0 : getter_Copies(windowTitle));
312 0 : mStringBundle->GetStringFromName(messageName,
313 0 : getter_Copies(message));
314 0 : if (showAgainName != nsnull) {
315 0 : mStringBundle->GetStringFromName(showAgainName,
316 0 : getter_Copies(alertMe));
317 : }
318 0 : mStringBundle->GetStringFromName(NS_LITERAL_STRING("Continue").get(),
319 0 : getter_Copies(cont));
320 : // alertMe is allowed to be null
321 0 : if (!windowTitle || !message || !cont) return NS_ERROR_FAILURE;
322 :
323 : // Replace # characters with newlines to lay out the dialog.
324 0 : PRUnichar* msgchars = message.BeginWriting();
325 :
326 0 : PRUint32 i = 0;
327 0 : for (i = 0; msgchars[i] != '\0'; i++) {
328 0 : if (msgchars[i] == '#') {
329 0 : msgchars[i] = '\n';
330 : }
331 : }
332 :
333 : PRInt32 buttonPressed;
334 :
335 0 : rv = prompt->ConfirmEx(windowTitle,
336 : message,
337 : (nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_0) +
338 : (nsIPrompt::BUTTON_TITLE_CANCEL * nsIPrompt::BUTTON_POS_1),
339 : cont,
340 : nsnull,
341 : nsnull,
342 : alertMe,
343 : &prefValue,
344 0 : &buttonPressed);
345 :
346 0 : if (NS_FAILED(rv)) return rv;
347 :
348 0 : *_result = (buttonPressed != 1);
349 :
350 0 : if (!prefValue && prefName != nsnull) {
351 0 : mPrefBranch->SetBoolPref(prefName, false);
352 0 : } else if (prefValue && showOnce) {
353 0 : mPrefBranch->SetBoolPref(showOncePref.get(), false);
354 : }
355 :
356 0 : return rv;
357 : }
358 :
|