Line data Source code
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 : /*
8 : * Dialog services for PIP.
9 : */
10 :
11 : #include "nsNSSDialogs.h"
12 :
13 : #include "mozIDOMWindow.h"
14 : #include "nsArray.h"
15 : #include "nsEmbedCID.h"
16 : #include "nsHashPropertyBag.h"
17 : #include "nsIDialogParamBlock.h"
18 : #include "nsIInterfaceRequestor.h"
19 : #include "nsIInterfaceRequestorUtils.h"
20 : #include "nsIKeygenThread.h"
21 : #include "nsIPromptService.h"
22 : #include "nsIProtectedAuthThread.h"
23 : #include "nsIWindowWatcher.h"
24 : #include "nsIX509CertDB.h"
25 : #include "nsIX509Cert.h"
26 : #include "nsNSSDialogHelper.h"
27 : #include "nsPromiseFlatString.h"
28 : #include "nsString.h"
29 : #include "nsVariant.h"
30 :
31 : #define PIPSTRING_BUNDLE_URL "chrome://pippki/locale/pippki.properties"
32 :
33 0 : nsNSSDialogs::nsNSSDialogs()
34 : {
35 0 : }
36 :
37 0 : nsNSSDialogs::~nsNSSDialogs()
38 : {
39 0 : }
40 :
41 0 : NS_IMPL_ISUPPORTS(nsNSSDialogs, nsITokenPasswordDialogs,
42 : nsICertificateDialogs,
43 : nsIClientAuthDialogs,
44 : nsITokenDialogs,
45 : nsIGeneratingKeypairInfoDialogs)
46 :
47 : nsresult
48 0 : nsNSSDialogs::Init()
49 : {
50 : nsresult rv;
51 :
52 : nsCOMPtr<nsIStringBundleService> service =
53 0 : do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
54 0 : if (NS_FAILED(rv)) return rv;
55 :
56 0 : rv = service->CreateBundle(PIPSTRING_BUNDLE_URL,
57 0 : getter_AddRefs(mPIPStringBundle));
58 0 : return rv;
59 : }
60 :
61 : NS_IMETHODIMP
62 0 : nsNSSDialogs::SetPassword(nsIInterfaceRequestor* ctx,
63 : const nsAString& tokenName,
64 : /*out*/ bool* canceled)
65 : {
66 : // |ctx| is allowed to be null.
67 0 : NS_ENSURE_ARG(canceled);
68 :
69 0 : *canceled = false;
70 :
71 : // Get the parent window for the dialog
72 0 : nsCOMPtr<mozIDOMWindowProxy> parent = do_GetInterface(ctx);
73 :
74 : nsCOMPtr<nsIDialogParamBlock> block =
75 0 : do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
76 0 : if (!block) return NS_ERROR_FAILURE;
77 :
78 0 : nsresult rv = block->SetString(1, PromiseFlatString(tokenName).get());
79 0 : if (NS_FAILED(rv)) return rv;
80 :
81 0 : rv = nsNSSDialogHelper::openDialog(parent,
82 : "chrome://pippki/content/changepassword.xul",
83 0 : block);
84 :
85 0 : if (NS_FAILED(rv)) return rv;
86 :
87 : int32_t status;
88 :
89 0 : rv = block->GetInt(1, &status);
90 0 : if (NS_FAILED(rv)) return rv;
91 :
92 0 : *canceled = (status == 0);
93 :
94 0 : return rv;
95 : }
96 :
97 : NS_IMETHODIMP
98 0 : nsNSSDialogs::ConfirmDownloadCACert(nsIInterfaceRequestor* ctx,
99 : nsIX509Cert* cert,
100 : /*out*/ uint32_t* trust,
101 : /*out*/ bool* importConfirmed)
102 : {
103 : // |ctx| is allowed to be null.
104 0 : NS_ENSURE_ARG(cert);
105 0 : NS_ENSURE_ARG(trust);
106 0 : NS_ENSURE_ARG(importConfirmed);
107 :
108 0 : nsCOMPtr<nsIMutableArray> argArray = nsArrayBase::Create();
109 0 : if (!argArray) {
110 0 : return NS_ERROR_FAILURE;
111 : }
112 :
113 0 : nsresult rv = argArray->AppendElement(cert, false);
114 0 : if (NS_FAILED(rv)) {
115 0 : return rv;
116 : }
117 :
118 0 : nsCOMPtr<nsIWritablePropertyBag2> retVals = new nsHashPropertyBag();
119 0 : rv = argArray->AppendElement(retVals, false);
120 0 : if (NS_FAILED(rv)) {
121 0 : return rv;
122 : }
123 :
124 : // Get the parent window for the dialog
125 0 : nsCOMPtr<mozIDOMWindowProxy> parent = do_GetInterface(ctx);
126 0 : rv = nsNSSDialogHelper::openDialog(parent,
127 : "chrome://pippki/content/downloadcert.xul",
128 0 : argArray);
129 0 : if (NS_FAILED(rv)) {
130 0 : return rv;
131 : }
132 :
133 0 : rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("importConfirmed"),
134 0 : importConfirmed);
135 0 : if (NS_FAILED(rv)) {
136 0 : return rv;
137 : }
138 :
139 0 : *trust = nsIX509CertDB::UNTRUSTED;
140 0 : if (!*importConfirmed) {
141 0 : return NS_OK;
142 : }
143 :
144 0 : bool trustForSSL = false;
145 0 : rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("trustForSSL"),
146 0 : &trustForSSL);
147 0 : if (NS_FAILED(rv)) {
148 0 : return rv;
149 : }
150 0 : bool trustForEmail = false;
151 0 : rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("trustForEmail"),
152 0 : &trustForEmail);
153 0 : if (NS_FAILED(rv)) {
154 0 : return rv;
155 : }
156 0 : bool trustForObjSign = false;
157 0 : rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("trustForObjSign"),
158 0 : &trustForObjSign);
159 0 : if (NS_FAILED(rv)) {
160 0 : return rv;
161 : }
162 :
163 0 : *trust |= trustForSSL ? nsIX509CertDB::TRUSTED_SSL : 0;
164 0 : *trust |= trustForEmail ? nsIX509CertDB::TRUSTED_EMAIL : 0;
165 0 : *trust |= trustForObjSign ? nsIX509CertDB::TRUSTED_OBJSIGN : 0;
166 :
167 0 : return NS_OK;
168 : }
169 :
170 : NS_IMETHODIMP
171 0 : nsNSSDialogs::ChooseCertificate(nsIInterfaceRequestor* ctx,
172 : const nsACString& hostname,
173 : int32_t port,
174 : const nsACString& organization,
175 : const nsACString& issuerOrg,
176 : nsIArray* certList,
177 : /*out*/ uint32_t* selectedIndex,
178 : /*out*/ bool* certificateChosen)
179 : {
180 0 : NS_ENSURE_ARG_POINTER(ctx);
181 0 : NS_ENSURE_ARG_POINTER(certList);
182 0 : NS_ENSURE_ARG_POINTER(selectedIndex);
183 0 : NS_ENSURE_ARG_POINTER(certificateChosen);
184 :
185 0 : *certificateChosen = false;
186 :
187 0 : nsCOMPtr<nsIMutableArray> argArray = nsArrayBase::Create();
188 0 : if (!argArray) {
189 0 : return NS_ERROR_FAILURE;
190 : }
191 :
192 0 : nsCOMPtr<nsIWritableVariant> hostnameVariant = new nsVariant();
193 0 : nsresult rv = hostnameVariant->SetAsAUTF8String(hostname);
194 0 : if (NS_FAILED(rv)) {
195 0 : return rv;
196 : }
197 0 : rv = argArray->AppendElement(hostnameVariant, false);
198 0 : if (NS_FAILED(rv)) {
199 0 : return rv;
200 : }
201 :
202 0 : nsCOMPtr<nsIWritableVariant> organizationVariant = new nsVariant();
203 0 : rv = organizationVariant->SetAsAUTF8String(organization);
204 0 : if (NS_FAILED(rv)) {
205 0 : return rv;
206 : }
207 0 : rv = argArray->AppendElement(organizationVariant, false);
208 0 : if (NS_FAILED(rv)) {
209 0 : return rv;
210 : }
211 :
212 0 : nsCOMPtr<nsIWritableVariant> issuerOrgVariant = new nsVariant();
213 0 : rv = issuerOrgVariant->SetAsAUTF8String(issuerOrg);
214 0 : if (NS_FAILED(rv)) {
215 0 : return rv;
216 : }
217 0 : rv = argArray->AppendElement(issuerOrgVariant, false);
218 0 : if (NS_FAILED(rv)) {
219 0 : return rv;
220 : }
221 :
222 0 : nsCOMPtr<nsIWritableVariant> portVariant = new nsVariant();
223 0 : rv = portVariant->SetAsInt32(port);
224 0 : if (NS_FAILED(rv)) {
225 0 : return rv;
226 : }
227 0 : rv = argArray->AppendElement(portVariant, false);
228 0 : if (NS_FAILED(rv)) {
229 0 : return rv;
230 : }
231 :
232 0 : rv = argArray->AppendElement(certList, false);
233 0 : if (NS_FAILED(rv)) {
234 0 : return rv;
235 : }
236 :
237 0 : nsCOMPtr<nsIWritablePropertyBag2> retVals = new nsHashPropertyBag();
238 0 : rv = argArray->AppendElement(retVals, false);
239 0 : if (NS_FAILED(rv)) {
240 0 : return rv;
241 : }
242 :
243 : rv = nsNSSDialogHelper::openDialog(nullptr,
244 : "chrome://pippki/content/clientauthask.xul",
245 0 : argArray);
246 0 : if (NS_FAILED(rv)) {
247 0 : return rv;
248 : }
249 :
250 0 : nsCOMPtr<nsIClientAuthUserDecision> extraResult = do_QueryInterface(ctx);
251 0 : if (extraResult) {
252 0 : bool rememberSelection = false;
253 0 : rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("rememberSelection"),
254 0 : &rememberSelection);
255 0 : if (NS_SUCCEEDED(rv)) {
256 0 : extraResult->SetRememberClientAuthCertificate(rememberSelection);
257 : }
258 : }
259 :
260 0 : rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("certChosen"),
261 0 : certificateChosen);
262 0 : if (NS_FAILED(rv)) {
263 0 : return rv;
264 : }
265 0 : if (*certificateChosen) {
266 0 : rv = retVals->GetPropertyAsUint32(NS_LITERAL_STRING("selectedIndex"),
267 0 : selectedIndex);
268 0 : if (NS_FAILED(rv)) {
269 0 : return rv;
270 : }
271 : }
272 :
273 0 : return NS_OK;
274 : }
275 :
276 : NS_IMETHODIMP
277 0 : nsNSSDialogs::SetPKCS12FilePassword(nsIInterfaceRequestor* ctx,
278 : /*out*/ nsAString& password,
279 : /*out*/ bool* confirmedPassword)
280 : {
281 : // |ctx| is allowed to be null.
282 0 : NS_ENSURE_ARG(confirmedPassword);
283 :
284 : // Get the parent window for the dialog
285 0 : nsCOMPtr<mozIDOMWindowProxy> parent = do_GetInterface(ctx);
286 0 : nsCOMPtr<nsIWritablePropertyBag2> retVals = new nsHashPropertyBag();
287 : nsresult rv =
288 0 : nsNSSDialogHelper::openDialog(parent,
289 : "chrome://pippki/content/setp12password.xul",
290 0 : retVals);
291 0 : if (NS_FAILED(rv)) {
292 0 : return rv;
293 : }
294 :
295 0 : rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("confirmedPassword"),
296 0 : confirmedPassword);
297 0 : if (NS_FAILED(rv)) {
298 0 : return rv;
299 : }
300 :
301 0 : if (!*confirmedPassword) {
302 0 : return NS_OK;
303 : }
304 :
305 0 : return retVals->GetPropertyAsAString(NS_LITERAL_STRING("password"), password);
306 : }
307 :
308 : NS_IMETHODIMP
309 0 : nsNSSDialogs::GetPKCS12FilePassword(nsIInterfaceRequestor* ctx,
310 : nsAString& _password,
311 : bool* _retval)
312 : {
313 0 : *_retval = false;
314 :
315 : nsCOMPtr<nsIPromptService> promptSvc(
316 0 : do_GetService(NS_PROMPTSERVICE_CONTRACTID));
317 0 : if (!promptSvc) {
318 0 : return NS_ERROR_FAILURE;
319 : }
320 :
321 0 : nsAutoString msg;
322 0 : nsresult rv = mPIPStringBundle->GetStringFromName(
323 0 : u"getPKCS12FilePasswordMessage", getter_Copies(msg));
324 0 : if (NS_FAILED(rv)) {
325 0 : return rv;
326 : }
327 :
328 : // Get the parent window for the dialog
329 0 : nsCOMPtr<mozIDOMWindowProxy> parent = do_GetInterface(ctx);
330 0 : bool ignored = false;
331 0 : char16_t* pwTemp = nullptr;
332 0 : rv = promptSvc->PromptPassword(parent, nullptr, msg.get(), &pwTemp, nullptr,
333 0 : &ignored, _retval);
334 0 : if (NS_FAILED(rv)) {
335 0 : return rv;
336 : }
337 :
338 0 : if (*_retval) {
339 0 : _password.Assign(pwTemp);
340 0 : free(pwTemp);
341 : }
342 :
343 0 : return NS_OK;
344 : }
345 :
346 : NS_IMETHODIMP
347 0 : nsNSSDialogs::ViewCert(nsIInterfaceRequestor* ctx, nsIX509Cert* cert)
348 : {
349 : // |ctx| is allowed to be null.
350 0 : NS_ENSURE_ARG(cert);
351 :
352 : // Get the parent window for the dialog
353 0 : nsCOMPtr<mozIDOMWindowProxy> parent = do_GetInterface(ctx);
354 0 : return nsNSSDialogHelper::openDialog(parent,
355 : "chrome://pippki/content/certViewer.xul",
356 : cert,
357 0 : false /*modal*/);
358 : }
359 :
360 : NS_IMETHODIMP
361 0 : nsNSSDialogs::DisplayGeneratingKeypairInfo(nsIInterfaceRequestor *aCtx, nsIKeygenThread *runnable)
362 : {
363 : nsresult rv;
364 :
365 : // Get the parent window for the dialog
366 0 : nsCOMPtr<mozIDOMWindowProxy> parent = do_GetInterface(aCtx);
367 :
368 0 : rv = nsNSSDialogHelper::openDialog(parent,
369 : "chrome://pippki/content/createCertInfo.xul",
370 0 : runnable);
371 0 : return rv;
372 : }
373 :
374 : NS_IMETHODIMP
375 0 : nsNSSDialogs::ChooseToken(nsIInterfaceRequestor* /*aCtx*/,
376 : const char16_t** aTokenList,
377 : uint32_t aCount,
378 : /*out*/ nsAString& aTokenChosen,
379 : /*out*/ bool* aCanceled)
380 : {
381 0 : NS_ENSURE_ARG(aTokenList);
382 0 : NS_ENSURE_ARG(aCanceled);
383 :
384 0 : *aCanceled = false;
385 :
386 : nsCOMPtr<nsIDialogParamBlock> block =
387 0 : do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
388 0 : if (!block) return NS_ERROR_FAILURE;
389 :
390 0 : block->SetNumberStrings(aCount);
391 :
392 : nsresult rv;
393 0 : for (uint32_t i = 0; i < aCount; i++) {
394 0 : rv = block->SetString(i, aTokenList[i]);
395 0 : if (NS_FAILED(rv)) return rv;
396 : }
397 :
398 0 : rv = block->SetInt(0, aCount);
399 0 : if (NS_FAILED(rv)) return rv;
400 :
401 : rv = nsNSSDialogHelper::openDialog(nullptr,
402 : "chrome://pippki/content/choosetoken.xul",
403 0 : block);
404 0 : if (NS_FAILED(rv)) return rv;
405 :
406 : int32_t status;
407 :
408 0 : rv = block->GetInt(0, &status);
409 0 : if (NS_FAILED(rv)) return rv;
410 :
411 0 : *aCanceled = (status == 0);
412 0 : if (!*aCanceled) {
413 : // retrieve the nickname
414 0 : rv = block->GetString(0, getter_Copies(aTokenChosen));
415 : }
416 0 : return rv;
417 : }
418 :
419 : NS_IMETHODIMP
420 0 : nsNSSDialogs::DisplayProtectedAuth(nsIInterfaceRequestor *aCtx, nsIProtectedAuthThread *runnable)
421 : {
422 : // We cannot use nsNSSDialogHelper here. We cannot allow close widget
423 : // in the window because protected authentication is interruptible
424 : // from user interface and changing nsNSSDialogHelper's static variable
425 : // would not be thread-safe
426 :
427 0 : nsresult rv = NS_ERROR_FAILURE;
428 :
429 : // Get the parent window for the dialog
430 0 : nsCOMPtr<mozIDOMWindowProxy> parent = do_GetInterface(aCtx);
431 :
432 : nsCOMPtr<nsIWindowWatcher> windowWatcher =
433 0 : do_GetService("@mozilla.org/embedcomp/window-watcher;1", &rv);
434 0 : if (NS_FAILED(rv))
435 0 : return rv;
436 :
437 0 : if (!parent) {
438 0 : windowWatcher->GetActiveWindow(getter_AddRefs(parent));
439 : }
440 :
441 0 : nsCOMPtr<mozIDOMWindowProxy> newWindow;
442 0 : rv = windowWatcher->OpenWindow(parent,
443 : "chrome://pippki/content/protectedAuth.xul",
444 : "_blank",
445 : "centerscreen,chrome,modal,titlebar,close=no",
446 : runnable,
447 0 : getter_AddRefs(newWindow));
448 :
449 0 : return rv;
450 : }
|