security/manager/pki/src/nsNSSDialogs.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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/. */
     7 /*
     8  * Dialog services for PIP.
     9  */
    10 #include "nsCOMPtr.h"
    11 #include "nsString.h"
    12 #include "nsXPIDLString.h"
    13 #include "nsReadableUtils.h"
    14 #include "nsIDOMWindow.h"
    15 #include "nsIDialogParamBlock.h"
    16 #include "nsIComponentManager.h"
    17 #include "nsIServiceManager.h"
    18 #include "nsIStringBundle.h"
    19 #include "nsIInterfaceRequestor.h"
    20 #include "nsIInterfaceRequestorUtils.h"
    21 #include "nsIX509Cert.h"
    22 #include "nsIX509CertDB.h"
    23 #include "nsIDateTimeFormat.h"
    24 #include "nsDateTimeFormatCID.h"
    25 #include "nsPromiseFlatString.h"
    27 #include "nsNSSDialogs.h"
    28 #include "nsPKIParamBlock.h"
    29 #include "nsIKeygenThread.h"
    30 #include "nsIProtectedAuthThread.h"
    31 #include "nsNSSDialogHelper.h"
    32 #include "nsIWindowWatcher.h"
    33 #include "nsIX509CertValidity.h"
    35 #include "nsEmbedCID.h"
    36 #include "nsIPromptService.h"
    38 #define PIPSTRING_BUNDLE_URL "chrome://pippki/locale/pippki.properties"
    40 /* ==== */
    42 nsNSSDialogs::nsNSSDialogs()
    43 {
    44 }
    46 nsNSSDialogs::~nsNSSDialogs()
    47 {
    48 }
    50 NS_IMPL_ISUPPORTS(nsNSSDialogs, nsITokenPasswordDialogs,
    51                   nsICertificateDialogs,
    52                   nsIClientAuthDialogs,
    53                   nsICertPickDialogs,
    54                   nsITokenDialogs,
    55                   nsIDOMCryptoDialogs,
    56                   nsIGeneratingKeypairInfoDialogs,
    57                   nsISSLCertErrorDialog)
    59 nsresult
    60 nsNSSDialogs::Init()
    61 {
    62   nsresult rv;
    64   nsCOMPtr<nsIStringBundleService> service =
    65            do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
    66   if (NS_FAILED(rv)) return rv;
    68   rv = service->CreateBundle(PIPSTRING_BUNDLE_URL,
    69                              getter_AddRefs(mPIPStringBundle));
    70   return rv;
    71 }
    73 nsresult
    74 nsNSSDialogs::SetPassword(nsIInterfaceRequestor *ctx,
    75                           const char16_t *tokenName, bool* _canceled)
    76 {
    77   nsresult rv;
    79   *_canceled = false;
    81   // Get the parent window for the dialog
    82   nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(ctx);
    84   nsCOMPtr<nsIDialogParamBlock> block =
    85            do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
    86   if (!block) return NS_ERROR_FAILURE;
    88   // void ChangePassword(in wstring tokenName, out int status);
    89   rv = block->SetString(1, tokenName);
    90   if (NS_FAILED(rv)) return rv;
    92   rv = nsNSSDialogHelper::openDialog(parent,
    93                                 "chrome://pippki/content/changepassword.xul",
    94                                 block);
    96   if (NS_FAILED(rv)) return rv;
    98   int32_t status;
   100   rv = block->GetInt(1, &status);
   101   if (NS_FAILED(rv)) return rv;
   103   *_canceled = (status == 0)?true:false;
   105   return rv;
   106 }
   108 nsresult
   109 nsNSSDialogs::GetPassword(nsIInterfaceRequestor *ctx,
   110                           const char16_t *tokenName, 
   111                           char16_t **_password,
   112                           bool* _canceled)
   113 {
   114   nsresult rv;
   115   *_canceled = false;
   116   // Get the parent window for the dialog
   117   nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(ctx);
   118   nsCOMPtr<nsIDialogParamBlock> block = 
   119            do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
   120   if (!block) return NS_ERROR_FAILURE;
   121   // Set the token name in the window
   122   rv = block->SetString(1, tokenName);
   123   if (NS_FAILED(rv)) return rv;
   124   // open up the window
   125   rv = nsNSSDialogHelper::openDialog(parent,
   126                                      "chrome://pippki/content/getpassword.xul",
   127                                      block);
   128   if (NS_FAILED(rv)) return rv;
   129   // see if user canceled
   130   int32_t status;
   131   rv = block->GetInt(1, &status);
   132   if (NS_FAILED(rv)) return rv;
   133   *_canceled = (status == 0) ? true : false;
   134   if (!*_canceled) {
   135     // retrieve the password
   136     rv = block->GetString(2, _password);
   137   }
   138   return rv;
   139 }
   141 NS_IMETHODIMP 
   142 nsNSSDialogs::ConfirmDownloadCACert(nsIInterfaceRequestor *ctx, 
   143                                     nsIX509Cert *cert,
   144                                     uint32_t *_trust,
   145                                     bool *_retval)
   146 {
   147   nsresult rv;
   149   *_retval = true;
   151   // Get the parent window for the dialog
   152   nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(ctx);
   154   nsCOMPtr<nsIPKIParamBlock> block =
   155            do_CreateInstance(NS_PKIPARAMBLOCK_CONTRACTID);
   156   if (!block)
   157     return NS_ERROR_FAILURE;
   159   rv = block->SetISupportAtIndex(1, cert);
   160   if (NS_FAILED(rv))
   161     return rv;
   163   rv = nsNSSDialogHelper::openDialog(parent, 
   164                                      "chrome://pippki/content/downloadcert.xul",
   165                                      block);
   166   if (NS_FAILED(rv)) return rv;
   168   int32_t status;
   169   int32_t ssl, email, objsign;
   171   nsCOMPtr<nsIDialogParamBlock> dlgParamBlock = do_QueryInterface(block);
   173   rv = dlgParamBlock->GetInt(1, &status);
   174   if (NS_FAILED(rv)) return rv;
   175   rv = dlgParamBlock->GetInt(2, &ssl);
   176   if (NS_FAILED(rv)) return rv;
   177   rv = dlgParamBlock->GetInt(3, &email);
   178   if (NS_FAILED(rv)) return rv;
   179   rv = dlgParamBlock->GetInt(4, &objsign);
   180   if (NS_FAILED(rv)) return rv;
   182   *_trust = nsIX509CertDB::UNTRUSTED;
   183   *_trust |= (ssl) ? nsIX509CertDB::TRUSTED_SSL : 0;
   184   *_trust |= (email) ? nsIX509CertDB::TRUSTED_EMAIL : 0;
   185   *_trust |= (objsign) ? nsIX509CertDB::TRUSTED_OBJSIGN : 0;
   187   *_retval = (status == 0)?false:true;
   189   return rv;
   190 }
   193 NS_IMETHODIMP 
   194 nsNSSDialogs::NotifyCACertExists(nsIInterfaceRequestor *ctx)
   195 {
   196   nsresult rv;
   198   nsCOMPtr<nsIPromptService> promptSvc(do_GetService(NS_PROMPTSERVICE_CONTRACTID));
   199   if (!promptSvc)
   200     return NS_ERROR_FAILURE;
   202   // Get the parent window for the dialog
   203   nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(ctx);
   205   nsAutoString title;
   206   rv = mPIPStringBundle->GetStringFromName(MOZ_UTF16("caCertExistsTitle"),
   207                                            getter_Copies(title));
   208   NS_ENSURE_SUCCESS(rv, rv);
   210   nsAutoString msg;
   211   rv = mPIPStringBundle->GetStringFromName(MOZ_UTF16("caCertExistsMessage"),
   212                                            getter_Copies(msg));
   213   NS_ENSURE_SUCCESS(rv, rv);
   215   rv = promptSvc->Alert(parent, title.get(), msg.get());
   217   return rv;
   218 }
   221 NS_IMETHODIMP
   222 nsNSSDialogs::ChooseCertificate(nsIInterfaceRequestor *ctx, const char16_t *cn, const char16_t *organization, const char16_t *issuer, const char16_t **certNickList, const char16_t **certDetailsList, uint32_t count, int32_t *selectedIndex, bool *canceled) 
   223 {
   224   nsresult rv;
   225   uint32_t i;
   227   *canceled = false;
   229   // Get the parent window for the dialog
   230   nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(ctx);
   232   nsCOMPtr<nsIDialogParamBlock> block =
   233            do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
   234   if (!block) return NS_ERROR_FAILURE;
   236   block->SetNumberStrings(4+count*2);
   238   rv = block->SetString(0, cn);
   239   if (NS_FAILED(rv)) return rv;
   241   rv = block->SetString(1, organization);
   242   if (NS_FAILED(rv)) return rv;
   244   rv = block->SetString(2, issuer);
   245   if (NS_FAILED(rv)) return rv;
   247   for (i = 0; i < count; i++) {
   248     rv = block->SetString(i+3, certNickList[i]);
   249     if (NS_FAILED(rv)) return rv;
   250   }
   252   for (i = 0; i < count; i++) {
   253     rv = block->SetString(i+count+3, certDetailsList[i]);
   254     if (NS_FAILED(rv)) return rv;
   255   }
   257   rv = block->SetInt(0, count);
   258   if (NS_FAILED(rv)) return rv;
   260   rv = nsNSSDialogHelper::openDialog(nullptr,
   261                                 "chrome://pippki/content/clientauthask.xul",
   262                                 block);
   263   if (NS_FAILED(rv)) return rv;
   265   int32_t status;
   266   rv = block->GetInt(0, &status);
   267   if (NS_FAILED(rv)) return rv;
   269   nsCOMPtr<nsIClientAuthUserDecision> extraResult = do_QueryInterface(ctx);
   270   if (extraResult) {
   271     int32_t rememberSelection;
   272     rv = block->GetInt(2, &rememberSelection);
   273     if (NS_SUCCEEDED(rv)) {
   274       extraResult->SetRememberClientAuthCertificate(rememberSelection!=0);
   275     }
   276   }
   278   *canceled = (status == 0)?true:false;
   279   if (!*canceled) {
   280     // retrieve the nickname
   281     rv = block->GetInt(1, selectedIndex);
   282   }
   283   return rv;
   284 }
   287 NS_IMETHODIMP
   288 nsNSSDialogs::PickCertificate(nsIInterfaceRequestor *ctx, 
   289                               const char16_t **certNickList, 
   290                               const char16_t **certDetailsList, 
   291                               uint32_t count, 
   292                               int32_t *selectedIndex, 
   293                               bool *canceled) 
   294 {
   295   nsresult rv;
   296   uint32_t i;
   298   *canceled = false;
   300   // Get the parent window for the dialog
   301   nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(ctx);
   303   nsCOMPtr<nsIDialogParamBlock> block =
   304            do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
   305   if (!block) return NS_ERROR_FAILURE;
   307   block->SetNumberStrings(1+count*2);
   309   for (i = 0; i < count; i++) {
   310     rv = block->SetString(i, certNickList[i]);
   311     if (NS_FAILED(rv)) return rv;
   312   }
   314   for (i = 0; i < count; i++) {
   315     rv = block->SetString(i+count, certDetailsList[i]);
   316     if (NS_FAILED(rv)) return rv;
   317   }
   319   rv = block->SetInt(0, count);
   320   if (NS_FAILED(rv)) return rv;
   322   rv = block->SetInt(1, *selectedIndex);
   323   if (NS_FAILED(rv)) return rv;
   325   rv = nsNSSDialogHelper::openDialog(nullptr,
   326                                 "chrome://pippki/content/certpicker.xul",
   327                                 block);
   328   if (NS_FAILED(rv)) return rv;
   330   int32_t status;
   332   rv = block->GetInt(0, &status);
   333   if (NS_FAILED(rv)) return rv;
   335   *canceled = (status == 0)?true:false;
   336   if (!*canceled) {
   337     rv = block->GetInt(1, selectedIndex);
   338   }
   339   return rv;
   340 }
   343 NS_IMETHODIMP 
   344 nsNSSDialogs::SetPKCS12FilePassword(nsIInterfaceRequestor *ctx, 
   345                                     nsAString &_password,
   346                                     bool *_retval)
   347 {
   348   nsresult rv;
   349   *_retval = true;
   350   // Get the parent window for the dialog
   351   nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(ctx);
   352   nsCOMPtr<nsIDialogParamBlock> block =
   353            do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
   354   if (!block) return NS_ERROR_FAILURE;
   355   // open up the window
   356   rv = nsNSSDialogHelper::openDialog(parent,
   357                                   "chrome://pippki/content/setp12password.xul",
   358                                   block);
   359   if (NS_FAILED(rv)) return rv;
   360   // see if user canceled
   361   int32_t status;
   362   rv = block->GetInt(1, &status);
   363   if (NS_FAILED(rv)) return rv;
   364   *_retval = (status == 0) ? false : true;
   365   if (*_retval) {
   366     // retrieve the password
   367     char16_t *pw;
   368     rv = block->GetString(2, &pw);
   369     if (NS_SUCCEEDED(rv)) {
   370       _password = pw;
   371       nsMemory::Free(pw);
   372     }
   373   }
   374   return rv;
   375 }
   377 NS_IMETHODIMP 
   378 nsNSSDialogs::GetPKCS12FilePassword(nsIInterfaceRequestor *ctx, 
   379                                     nsAString &_password,
   380                                     bool *_retval)
   381 {
   382   nsresult rv;
   383   *_retval = true;
   384   // Get the parent window for the dialog
   385   nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(ctx);
   386   nsCOMPtr<nsIDialogParamBlock> block =
   387            do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
   388   if (!block) return NS_ERROR_FAILURE;
   389   // open up the window
   390   rv = nsNSSDialogHelper::openDialog(parent,
   391                                   "chrome://pippki/content/getp12password.xul",
   392                                   block);
   393   if (NS_FAILED(rv)) return rv;
   394   // see if user canceled
   395   int32_t status;
   396   rv = block->GetInt(1, &status);
   397   if (NS_FAILED(rv)) return rv;
   398   *_retval = (status == 0) ? false : true;
   399   if (*_retval) {
   400     // retrieve the password
   401     char16_t *pw;
   402     rv = block->GetString(2, &pw);
   403     if (NS_SUCCEEDED(rv)) {
   404       _password = pw;
   405       nsMemory::Free(pw);
   406     }
   407   }
   408   return rv;
   409 }
   411 /* void viewCert (in nsIX509Cert cert); */
   412 NS_IMETHODIMP 
   413 nsNSSDialogs::ViewCert(nsIInterfaceRequestor *ctx, 
   414                        nsIX509Cert *cert)
   415 {
   416   nsresult rv;
   418   nsCOMPtr<nsIPKIParamBlock> block =
   419            do_CreateInstance(NS_PKIPARAMBLOCK_CONTRACTID);
   420   if (!block)
   421     return NS_ERROR_FAILURE;
   423   rv = block->SetISupportAtIndex(1, cert);
   424   if (NS_FAILED(rv))
   425     return rv;
   427   // Get the parent window for the dialog
   428   nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(ctx);
   430   rv = nsNSSDialogHelper::openDialog(parent,
   431                                      "chrome://pippki/content/certViewer.xul",
   432                                      block,
   433                                      false);
   434   return rv;
   435 }
   437 NS_IMETHODIMP
   438 nsNSSDialogs::DisplayGeneratingKeypairInfo(nsIInterfaceRequestor *aCtx, nsIKeygenThread *runnable) 
   439 {
   440   nsresult rv;
   442   // Get the parent window for the dialog
   443   nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(aCtx);
   445   rv = nsNSSDialogHelper::openDialog(parent,
   446                                      "chrome://pippki/content/createCertInfo.xul",
   447                                      runnable);
   448   return rv;
   449 }
   451 NS_IMETHODIMP
   452 nsNSSDialogs::ChooseToken(nsIInterfaceRequestor *aCtx, const char16_t **aTokenList, uint32_t aCount, char16_t **aTokenChosen, bool *aCanceled) {
   453   nsresult rv;
   454   uint32_t i;
   456   *aCanceled = false;
   458   // Get the parent window for the dialog
   459   nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(aCtx);
   461   nsCOMPtr<nsIDialogParamBlock> block =
   462            do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
   463   if (!block) return NS_ERROR_FAILURE;
   465   block->SetNumberStrings(aCount);
   467   for (i = 0; i < aCount; i++) {
   468     rv = block->SetString(i, aTokenList[i]);
   469     if (NS_FAILED(rv)) return rv;
   470   }
   472   rv = block->SetInt(0, aCount);
   473   if (NS_FAILED(rv)) return rv;
   475   rv = nsNSSDialogHelper::openDialog(nullptr,
   476                                 "chrome://pippki/content/choosetoken.xul",
   477                                 block);
   478   if (NS_FAILED(rv)) return rv;
   480   int32_t status;
   482   rv = block->GetInt(0, &status);
   483   if (NS_FAILED(rv)) return rv;
   485   *aCanceled = (status == 0)?true:false;
   486   if (!*aCanceled) {
   487     // retrieve the nickname
   488     rv = block->GetString(0, aTokenChosen);
   489   }
   490   return rv;
   491 }
   493 /* boolean ConfirmKeyEscrow (in nsIX509Cert escrowAuthority); */
   494 NS_IMETHODIMP 
   495 nsNSSDialogs::ConfirmKeyEscrow(nsIX509Cert *escrowAuthority, bool *_retval)
   497 {
   498   *_retval = false;
   500   nsresult rv;
   502   nsCOMPtr<nsIPKIParamBlock> block =
   503            do_CreateInstance(NS_PKIPARAMBLOCK_CONTRACTID);
   504   if (!block)
   505     return NS_ERROR_FAILURE;
   507   rv = block->SetISupportAtIndex(1, escrowAuthority);
   508   if (NS_FAILED(rv))
   509     return rv;
   511   rv = nsNSSDialogHelper::openDialog(nullptr,
   512                                      "chrome://pippki/content/escrowWarn.xul",
   513                                      block);
   515   if (NS_FAILED(rv))
   516     return rv;
   518   int32_t status=0;
   519   nsCOMPtr<nsIDialogParamBlock> dlgParamBlock = do_QueryInterface(block);
   520   rv = dlgParamBlock->GetInt(1, &status);
   522   if (status) {
   523     *_retval = true;
   524   } 
   525   return rv;
   526 }
   528 NS_IMETHODIMP
   529 nsNSSDialogs::DisplayProtectedAuth(nsIInterfaceRequestor *aCtx, nsIProtectedAuthThread *runnable)
   530 {
   531     // We cannot use nsNSSDialogHelper here. We cannot allow close widget
   532     // in the window because protected authentication is interruptible
   533     // from user interface and changing nsNSSDialogHelper's static variable
   534     // would not be thread-safe
   536     nsresult rv = NS_ERROR_FAILURE;
   538     // Get the parent window for the dialog
   539     nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(aCtx);
   541     nsCOMPtr<nsIWindowWatcher> windowWatcher = 
   542         do_GetService("@mozilla.org/embedcomp/window-watcher;1", &rv);
   543     if (NS_FAILED(rv))
   544         return rv;
   546     if (!parent) {
   547         windowWatcher->GetActiveWindow(getter_AddRefs(parent));
   548     }
   550     nsCOMPtr<nsIDOMWindow> newWindow;
   551     rv = windowWatcher->OpenWindow(parent,
   552         "chrome://pippki/content/protectedAuth.xul",
   553         "_blank",
   554         "centerscreen,chrome,modal,titlebar,close=no",
   555         runnable,
   556         getter_AddRefs(newWindow));
   558     return rv;
   559 }
   561 NS_IMETHODIMP
   562 nsNSSDialogs::ShowCertError(nsIInterfaceRequestor *ctx, 
   563                             nsISSLStatus *status, 
   564                             nsIX509Cert *cert, 
   565                             const nsAString & textErrorMessage, 
   566                             const nsAString & htmlErrorMessage, 
   567                             const nsACString & hostName, 
   568                             uint32_t portNumber)
   569 {
   570   nsCOMPtr<nsIPKIParamBlock> block =
   571            do_CreateInstance(NS_PKIPARAMBLOCK_CONTRACTID);
   572   if (!block)
   573     return NS_ERROR_OUT_OF_MEMORY;
   575   nsCOMPtr<nsIDialogParamBlock> dialogBlock = do_QueryInterface(block);
   577   nsresult rv;
   578   rv = dialogBlock->SetInt(1, portNumber);
   579   if (NS_FAILED(rv))
   580     return rv; 
   582   rv = dialogBlock->SetString(1, NS_ConvertUTF8toUTF16(hostName).get());
   583   if (NS_FAILED(rv))
   584     return rv;
   586   rv = dialogBlock->SetString(2, PromiseFlatString(textErrorMessage).get());
   587   if (NS_FAILED(rv))
   588     return rv;
   590   rv = block->SetISupportAtIndex(1, cert);
   591   if (NS_FAILED(rv))
   592     return rv;
   594   rv = nsNSSDialogHelper::openDialog(nullptr, 
   595                                      "chrome://pippki/content/certerror.xul",
   596                                      block);
   597   return rv;
   598 }

mercurial