aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--embed/mozilla/GtkNSSClientAuthDialogs.cpp19
-rw-r--r--embed/mozilla/GtkNSSDialogs.cpp664
-rw-r--r--embed/mozilla/GtkNSSDialogs.h55
-rw-r--r--embed/mozilla/GtkNSSKeyPairDialogs.cpp16
-rw-r--r--lib/Makefile.am3
-rw-r--r--lib/ephy-password-dialog.c707
-rw-r--r--lib/ephy-password-dialog.h102
8 files changed, 1218 insertions, 362 deletions
diff --git a/ChangeLog b/ChangeLog
index 47f2fb63e..b99c077e3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
2006-06-22 Christian Persch <chpe@cvs.gnome.org>
+ * embed/mozilla/GtkNSSClientAuthDialogs.cpp:
+ * embed/mozilla/GtkNSSDialogs.cpp:
+ * embed/mozilla/GtkNSSDialogs.h:
+ * embed/mozilla/GtkNSSKeyPairDialogs.cpp:
+ * embed/mozilla/MozRegisterComponents.cpp:
+ * lib/Makefile.am:
+ A lib/ephy-password-dialog.c:
+ A lib/ephy-password-dialog.h:
+
+ Implement nsITokenPasswordDialogs. Misc cleanups and mozilla string
+ simplification now that we depend on gecko 1.8.
+
+2006-06-22 Christian Persch <chpe@cvs.gnome.org>
+
* m4/gecko.m4:
Fix 'unknown gecko' error output.
diff --git a/embed/mozilla/GtkNSSClientAuthDialogs.cpp b/embed/mozilla/GtkNSSClientAuthDialogs.cpp
index 26ed934d9..d6765c15e 100644
--- a/embed/mozilla/GtkNSSClientAuthDialogs.cpp
+++ b/embed/mozilla/GtkNSSClientAuthDialogs.cpp
@@ -197,14 +197,9 @@ GtkNSSClientAuthDialogs::ChooseCertificate (nsIInterfaceRequestor *ctx,
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
gtk_widget_show (label);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
-
-
- nsCString utf8_cn;
- NS_UTF16ToCString (nsString (cn),
- NS_CSTRING_ENCODING_UTF8, utf8_cn);
msg = g_markup_printf_escaped (_("Choose a certificate to present as identification to “%s”."),
- utf8_cn.get());
+ NS_ConvertUTF16toUTF8 (cn).get());
markup_text = g_strdup_printf ("<span weight=\"bold\" size=\"larger\">%s</span>\n\n%s",
_("Select a certificate to identify yourself."),
msg);
@@ -216,18 +211,10 @@ GtkNSSClientAuthDialogs::ChooseCertificate (nsIInterfaceRequestor *ctx,
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
for (i = 0; i < count; i++)
{
- nsCString certnick;
- nsCString certdetail;
-
- NS_UTF16ToCString (nsString (certNickList[i]),
- NS_CSTRING_ENCODING_UTF8, certnick);
- NS_UTF16ToCString (nsString (certDetailsList[i]),
- NS_CSTRING_ENCODING_UTF8, certdetail);
-
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
- 0, certnick.get(),
- 1, certdetail.get(),
+ 0, NS_ConvertUTF16toUTF8 (certNickList[i]).get(),
+ 1, NS_ConvertUTF16toUTF8 (certDetailsList[i]).get(),
-1);
}
diff --git a/embed/mozilla/GtkNSSDialogs.cpp b/embed/mozilla/GtkNSSDialogs.cpp
index 8bae2e8e8..e3c9b5bcc 100644
--- a/embed/mozilla/GtkNSSDialogs.cpp
+++ b/embed/mozilla/GtkNSSDialogs.cpp
@@ -1,7 +1,6 @@
/*
- * GtkNSSDialogs.cpp
- *
* Copyright (C) 2003 Crispin Flowerday <gnome@flowerday.cx>
+ * Copyright (C) 2006 Christian Persch
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -67,6 +66,10 @@
#include <nsIDOMWindow.h>
#include <nsIInterfaceRequestor.h>
#include <nsIInterfaceRequestorUtils.h>
+#include <nsIPKCS11ModuleDB.h>
+#include <nsIPKCS11Slot.h>
+#include <nsIPK11Token.h>
+#include <nsIPK11TokenDB.h>
#include <nsIServiceManager.h>
#include <nsISimpleEnumerator.h>
#include <nsIX509CertDB.h>
@@ -81,6 +84,7 @@
#include "ephy-file-helpers.h"
#include "ephy-gui.h"
+#include "ephy-password-dialog.h"
#include "AutoJSContextStack.h"
#include "EphyUtils.h"
@@ -103,9 +107,19 @@ GtkNSSDialogs::~GtkNSSDialogs ()
{
}
-NS_IMPL_THREADSAFE_ISUPPORTS2 (GtkNSSDialogs,
+NS_IMPL_THREADSAFE_ISUPPORTS5 (GtkNSSDialogs,
nsICertificateDialogs,
- nsIBadCertListener)
+ nsIBadCertListener,
+ nsITokenPasswordDialogs,
+ nsITokenDialogs,
+ nsIDOMCryptoDialogs)
+
+/* There's also nsICertPickDialogs which is implemented in mozilla
+ * but has no callers. So we don't implement it.
+ * Same for nsIUserCertPicker which is only used in mailnews.
+ *
+ * We should implement nsIFormSigningDialog, however.
+ */
/**
* Call the mozilla service to display a certificate
@@ -301,6 +315,74 @@ display_cert_warning_box (nsIInterfaceRequestor *ctx,
}
+/* Helper functions */
+
+nsresult
+GtkNSSDialogs::GetTokenAndSlotFromName (const PRUnichar *aName,
+ nsIPK11Token **aToken,
+ nsIPKCS11Slot **aSlot)
+{
+ nsresult rv = NS_ERROR_FAILURE;
+ *aToken = nsnull;
+ *aSlot = nsnull;
+
+ nsCOMPtr<nsIPK11TokenDB> tokenDB = do_GetService("@mozilla.org/security/pk11tokendb;1");
+ nsCOMPtr<nsIPKCS11ModuleDB> pkcs11DB = do_GetService("@mozilla.org/security/pkcs11moduledb;1");
+ if (!tokenDB || !pkcs11DB) return rv;
+
+ rv = tokenDB->FindTokenByName (aName, aToken);
+ NS_ENSURE_TRUE (NS_SUCCEEDED (rv) && *aToken, rv);
+
+ pkcs11DB->FindSlotByName (aName, aSlot);
+
+ NS_ENSURE_TRUE (*aSlot, NS_ERROR_FAILURE);
+
+#ifdef GNOME_ENABLE_DEBUG
+ /* Dump some info about this token */
+ nsIPK11Token *token = *aToken;
+ PRUnichar *tName, *tLabel, *tManID, *tHWVersion, *tFWVersion, *tSN;
+ PRInt32 minPwdLen;
+ PRBool needsInit, isHW, needsLogin, isFriendly;
+
+ token->GetTokenName(&tName);
+ token->GetTokenLabel(&tLabel);
+ token->GetTokenManID(&tManID);
+ token->GetTokenHWVersion(&tHWVersion);
+ token->GetTokenFWVersion(&tFWVersion);
+ token->GetTokenSerialNumber(&tSN);
+ token->GetMinimumPasswordLength(&minPwdLen);
+ token->GetNeedsUserInit(&needsInit);
+ token->IsHardwareToken(&isHW);
+ token->NeedsLogin(&needsLogin);
+ token->IsFriendly(&isFriendly);
+
+ g_print ("Token '%s' has \nName: %s\nLabel: %s\nManID: %s\nHWversion: %s\nFWVersion: %s\nSN: %s\n"
+ "MinPwdLen: %d\nNeedsUserInit: %d\nIsHWToken: %d\nNeedsLogin: %d\nIsFriendly: %d\n\n",
+ NS_ConvertUTF16toUTF8(aName).get(),
+
+ NS_ConvertUTF16toUTF8(tName).get(),
+ NS_ConvertUTF16toUTF8(tLabel).get(),
+ NS_ConvertUTF16toUTF8(tManID).get(),
+ NS_ConvertUTF16toUTF8(tHWVersion).get(),
+ NS_ConvertUTF16toUTF8(tFWVersion).get(),
+ NS_ConvertUTF16toUTF8(tSN).get(),
+ minPwdLen,
+ needsInit,
+ isHW,
+ needsLogin,
+ isFriendly);
+
+ nsIPKCS11Slot *slot = *aSlot;
+ PRUnichar*slDesc;
+ slot->GetDesc(&slDesc);
+ g_print ("Slot description: %s\n", NS_ConvertUTF16toUTF8 (slDesc).get());
+#endif
+
+ return NS_OK;
+}
+
+/* nsICertificateDialogs */
+
NS_IMETHODIMP
GtkNSSDialogs::ConfirmMismatchDomain (nsIInterfaceRequestor *ctx,
const nsACString &targetURL,
@@ -312,9 +394,7 @@ GtkNSSDialogs::ConfirmMismatchDomain (nsIInterfaceRequestor *ctx,
nsString commonName;
cert->GetCommonName (commonName);
- nsCString cCommonName;
- NS_UTF16ToCString (commonName,
- NS_CSTRING_ENCODING_UTF8, cCommonName);
+ NS_ConvertUTF16toUTF8 cCommonName (commonName);
nsCString cTargetUrl (targetURL);
@@ -355,9 +435,7 @@ GtkNSSDialogs::ConfirmUnknownIssuer (nsIInterfaceRequestor *ctx,
nsString commonName;
cert->GetCommonName (commonName);
- nsCString cCommonName;
- NS_UTF16ToCString (commonName,
- NS_CSTRING_ENCODING_UTF8, cCommonName);
+ NS_ConvertUTF16toUTF8 cCommonName (commonName);
secondary = g_markup_printf_escaped
(_("It was not possible to automatically trust “%s”. "
@@ -452,9 +530,7 @@ GtkNSSDialogs::ConfirmCertExpired (nsIInterfaceRequestor *ctx,
nsString commonName;
cert->GetCommonName (commonName);
- nsCString cCommonName;
- NS_UTF16ToCString (commonName,
- NS_CSTRING_ENCODING_UTF8, cCommonName);
+ NS_ConvertUTF16toUTF8 cCommonName (commonName);
LL_DIV (normalizedTime, timeToUse, PR_USEC_PER_SEC);
LL_L2UI (t, normalizedTime);
@@ -463,6 +539,7 @@ GtkNSSDialogs::ConfirmCertExpired (nsIInterfaceRequestor *ctx,
* strftime(3) */
strftime (formattedDate, sizeof(formattedDate), _("%a %d %b %Y"),
localtime_r (&t, &tm));
+ /* FIXME! this isn't actually correct, LC_CTIME codeset could be different than locale codeset! */
fdate = g_locale_to_utf8 (formattedDate, -1, NULL, NULL, NULL);
secondary = g_markup_printf_escaped (text, cCommonName.get(), fdate);
@@ -483,59 +560,39 @@ GtkNSSDialogs::ConfirmCertExpired (nsIInterfaceRequestor *ctx,
}
/* void notifyCrlNextupdate (in nsIInterfaceRequestor socketInfo,
- in AUTF8String targetURL, in nsIX509Cert cert); */
+ in AUTF8String targetURL,
+ in nsIX509Cert cert); */
NS_IMETHODIMP
GtkNSSDialogs::NotifyCrlNextupdate (nsIInterfaceRequestor *ctx,
- const nsACString & targetURL, nsIX509Cert *cert)
+ const nsACString & targetURL,
+ nsIX509Cert *cert)
{
- GtkWidget *dialog, *label;
- char *msg, *primary, *secondary;
-
nsCOMPtr<nsIDOMWindow> parent = do_GetInterface (ctx);
GtkWidget *gparent = EphyUtils::FindGtkParent (parent);
- dialog = gtk_dialog_new_with_buttons ("",
- GTK_WINDOW (gparent),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_OK,
- GTK_RESPONSE_OK,
- (char *) NULL);
-
- gtk_window_set_icon_name (GTK_WINDOW (dialog), "web-browser");
-
- higgy_setup_dialog (GTK_DIALOG (dialog), GTK_STOCK_DIALOG_ERROR,
- &label, NULL);
+ nsCString cTargetUrl (targetURL);
nsString commonName;
cert->GetCommonName (commonName);
- nsCString cCommonName;
- NS_UTF16ToCString (commonName,
- NS_CSTRING_ENCODING_UTF8, cCommonName);
-
- nsCString cTargetUrl (targetURL);
-
- primary = g_markup_printf_escaped (_("Cannot establish connection to “%s”."),
- cTargetUrl.get());
-
- secondary = g_markup_printf_escaped (_("The certificate revocation list (CRL) from “%s” "
- "needs to be updated."),
- cCommonName.get());
- msg = g_strdup_printf ("<span weight=\"bold\" size=\"larger\">%s</span>\n\n%s\n\n%s",
- primary, secondary,
- _("Please ask your system administrator for assistance."));
-
- gtk_label_set_markup (GTK_LABEL (label), msg);
-
- g_free (primary);
- g_free (secondary);
- g_free (msg);
-
- gtk_widget_show_all (dialog);
+ GtkWidget *dialog = gtk_message_dialog_new
+ (GTK_WINDOW (gparent),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ _("Cannot establish connection to “%s”"),
+ cTargetUrl.get ());
+
+ gtk_message_dialog_format_secondary_text
+ (GTK_MESSAGE_DIALOG (dialog),
+ _("The certificate revocation list (CRL) from “%s” "
+ "needs to be updated.\n\n"
+ "Please ask your system administrator for assistance."),
+ NS_ConvertUTF16toUTF8 (commonName).get ());
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), "web-browser");
- g_signal_connect (G_OBJECT (dialog),
- "response",
- (GCallback)gtk_widget_destroy, NULL);
+ g_signal_connect (dialog, "response",
+ (GCallback) gtk_widget_destroy, NULL);
gtk_widget_show_all (dialog);
return NS_OK;
@@ -581,9 +638,7 @@ GtkNSSDialogs::ConfirmDownloadCACert(nsIInterfaceRequestor *ctx,
nsString commonName;
cert->GetCommonName (commonName);
- nsCString cCommonName;
- NS_UTF16ToCString (commonName,
- NS_CSTRING_ENCODING_UTF8, cCommonName);
+ NS_ConvertUTF16toUTF8 cCommonName (commonName);
primary = g_markup_printf_escaped (_("Trust new Certificate Authority “%s” to identify web sites?"),
cCommonName.get());
@@ -674,97 +729,13 @@ GtkNSSDialogs::NotifyCACertExists (nsIInterfaceRequestor *ctx)
return NS_OK;
}
-struct SetPasswordCallback
-{
- GtkWidget *entry1;
- GtkWidget *entry2;
- GtkWidget *widget;
-};
-
-
-static void
-set_password_entry_changed_cb (GtkEditable *editable, void * _data)
-{
- SetPasswordCallback * data = (SetPasswordCallback*)_data;
- gchar * text1 = gtk_editable_get_chars
- (GTK_EDITABLE(data->entry1), 0, -1);
- gchar * text2 = gtk_editable_get_chars
- (GTK_EDITABLE(data->entry2), 0, -1);
-
- if (strcmp (text1, text2) == 0)
- {
- gtk_widget_set_sensitive (data->widget, TRUE);
- }
- else
- {
- gtk_widget_set_sensitive (data->widget, FALSE);
- }
-
- g_free (text1);
- g_free (text2);
-}
-
-
-/**
- * Calculate the quality of a password. The algorithm used is taken
- * directly from mozilla in:
- * $MOZSRC/security/manager/pki/resources/content/password.js
- */
-static void
-password_quality_meter_cb (GtkEditable *editable, GtkWidget *progress)
-{
- gchar * text = gtk_editable_get_chars (editable, 0, -1);
-
- /* Get the length */
- glong length = g_utf8_strlen (text, -1);
-
- /* Count the number of number, symbols and uppercase chars */
- gint uppercase = 0;
- gint symbols = 0;
- gint numbers = 0;
- for( const gchar * p = text; *p; p = g_utf8_find_next_char (p, NULL) )
- {
- gunichar uc = g_utf8_get_char(p);
- if (g_unichar_isdigit (uc))
- {
- numbers++;
- }
- else if (g_unichar_isupper (uc))
- {
- uppercase++;
- }
- else if (g_unichar_islower (uc))
- {
- /* Not counted */
- }
- else if (g_unichar_isgraph (uc))
- {
- symbols++;
- }
- }
-
- if (length > 5) length = 5;
- if (numbers > 3) numbers = 3;
- if (symbols > 3) symbols = 3;
- if (uppercase > 3) uppercase = 3;
-
- gint strength = ((length*10)-20) + (numbers*10) + (symbols*15) + (uppercase*10);
- if (strength < 0) strength = 0;
- if (strength > 100) strength = 100;
-
- gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress), (strength/100.0));
-
- g_free (text);
-}
-
-
+/* FIXME: This interface sucks! There is way to know the name of the certificate! */
NS_IMETHODIMP
GtkNSSDialogs::SetPKCS12FilePassword(nsIInterfaceRequestor *ctx,
nsAString &_password,
PRBool *_retval)
{
- GtkWidget *dialog, *table, *entry1, *entry2, *button, *label, *vbox;
- GtkWidget *progress;
+ GtkWidget *dialog;
char *msg;
nsresult rv;
@@ -773,112 +744,38 @@ GtkNSSDialogs::SetPKCS12FilePassword(nsIInterfaceRequestor *ctx,
if (NS_FAILED (rv)) return rv;
nsCOMPtr<nsIDOMWindow> parent = do_GetInterface (ctx);
- GtkWindow *gparent = GTK_WINDOW (EphyUtils::FindGtkParent (parent));
-
- dialog = gtk_dialog_new_with_buttons ("", gparent,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_CANCEL,
- (char *) NULL);
-
- if (gparent)
- {
- gtk_window_group_add_window (ephy_gui_ensure_window_group (gparent),
- GTK_WINDOW (dialog));
- }
-
- gtk_window_set_icon_name (GTK_WINDOW (dialog), "web-browser");
+ GtkWidget *gparent = EphyUtils::FindGtkParent (parent);
- higgy_setup_dialog (GTK_DIALOG (dialog), GTK_STOCK_DIALOG_QUESTION,
- &label, &vbox);
+ dialog = ephy_password_dialog_new (gparent,
+ _("Select Password"),
+ EphyPasswordDialogFlags(EPHY_PASSWORD_DIALOG_FLAGS_SHOW_NEW_PASSWORD |
+ EPHY_PASSWORD_DIALOG_FLAGS_SHOW_QUALITY_METER));
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+ gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
- /* Translators: this is the action of the certificate being exported to a backup file */
- button = gtk_button_new_with_mnemonic (_("_Back Up Certificate"));
- gtk_widget_show (button);
- gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_OK);
- GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ /* FIXME: set accept button text to (_("_Back Up Certificate") ?
+ * That's not actually correct, since this function is also called from other places!
+ */
- msg = g_strdup_printf ("<span weight=\"bold\" size=\"larger\">%s</span>\n\n%s",
- _("Select password."),
- _("Select a password to protect this certificate."));
- gtk_label_set_markup (GTK_LABEL (label), msg);
+ msg = g_markup_printf_escaped (_("Select a password to protect this certificate"));
+ gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), msg);
g_free (msg);
- table = gtk_table_new (3, 3, FALSE);
- gtk_table_set_row_spacings (GTK_TABLE (table), 6);
- gtk_table_set_col_spacings (GTK_TABLE (table), 12);
- gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
-
- label = gtk_label_new (NULL);
- entry1 = gtk_entry_new ();
- entry2 = gtk_entry_new ();
- gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), _("_Password:"));
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry1);
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- gtk_entry_set_visibility (GTK_ENTRY (entry1), FALSE);
- g_signal_connect_swapped (entry1, "activate",
- (GCallback)gtk_widget_grab_focus,
- entry2);
-
- gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
- GTK_FILL, GTK_FILL, 0, 0 );
- gtk_table_attach (GTK_TABLE (table), entry1, 1, 2, 0, 1,
- GTK_FILL, GTK_FILL, 0, 0 );
-
- label = gtk_label_new (NULL);
- gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), _("Con_firm password:"));
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry2);
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- gtk_entry_set_visibility (GTK_ENTRY (entry2), FALSE);
- gtk_entry_set_activates_default (GTK_ENTRY (entry2), TRUE);
-
- gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
- GTK_FILL, GTK_FILL, 0, 0 );
- gtk_table_attach (GTK_TABLE (table), entry2, 1, 2, 1, 2,
- GTK_FILL, GTK_FILL, 0, 0 );
-
- /* TODO: We need a better password quality meter */
- label = gtk_label_new (_("Password quality:"));
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- progress = gtk_progress_bar_new ();
- gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress), 0.0);
-
- gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
- GTK_FILL, GTK_FILL, 0, 0 );
- gtk_table_attach (GTK_TABLE (table), progress, 1, 2, 2, 3,
- GTK_FILL, GTK_FILL, 0, 0 );
-
- SetPasswordCallback callback_data = { entry1, entry2, button };
- g_signal_connect (entry1, "changed",
- (GCallback)set_password_entry_changed_cb,
- &callback_data);
-
- g_signal_connect (entry1, "changed",
- (GCallback)password_quality_meter_cb,
- progress);
-
- g_signal_connect (entry2, "changed",
- (GCallback)set_password_entry_changed_cb,
- &callback_data);
-
-
- gtk_widget_show_all (dialog);
- int ret = gtk_dialog_run (GTK_DIALOG (dialog));
-
- if (ret != GTK_RESPONSE_OK)
- {
- *_retval = PR_FALSE;
- }
- else
+ int response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_hide (dialog);
+
+ if (response == GTK_RESPONSE_ACCEPT)
{
- gchar *text = gtk_editable_get_chars (GTK_EDITABLE (entry1), 0, -1);
- NS_CStringToUTF16 (nsCString (text),
+ const char *text = ephy_password_dialog_get_new_password (EPHY_PASSWORD_DIALOG (dialog));
+ g_return_val_if_fail (text != NULL, NS_ERROR_FAILURE);
+ NS_CStringToUTF16 (nsDependentCString (text),
NS_CSTRING_ENCODING_UTF8, _password);
- g_free (text);
- *_retval = PR_TRUE;
}
+
+ *_retval = response == GTK_RESPONSE_ACCEPT;
+
gtk_widget_destroy (dialog);
+
return NS_OK;
}
@@ -887,8 +784,7 @@ GtkNSSDialogs::GetPKCS12FilePassword(nsIInterfaceRequestor *ctx,
nsAString &_password,
PRBool *_retval)
{
- GtkWidget *dialog, *hbox, *label, *entry, *vbox;
- char *msg;
+ g_print ("GtkNSSDialogs::GetPKCS12FilePassword\n");
nsresult rv;
AutoJSContextStack stack;
@@ -896,61 +792,33 @@ GtkNSSDialogs::GetPKCS12FilePassword(nsIInterfaceRequestor *ctx,
if (NS_FAILED (rv)) return rv;
nsCOMPtr<nsIDOMWindow> parent = do_GetInterface (ctx);
- GtkWindow *gparent = GTK_WINDOW (EphyUtils::FindGtkParent (parent));
-
- dialog = gtk_dialog_new_with_buttons ("", gparent,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- _("I_mport Certificate"), GTK_RESPONSE_OK,
- (char *) NULL);
-
- if (gparent)
- {
- gtk_window_group_add_window (ephy_gui_ensure_window_group (gparent),
- GTK_WINDOW (dialog));
- }
+ GtkWidget *gparent = EphyUtils::FindGtkParent (parent);
- gtk_window_set_icon_name (GTK_WINDOW (dialog), "web-browser");
+ GtkWidget *dialog = ephy_password_dialog_new
+ (gparent,
+ "",
+ EphyPasswordDialogFlags (EPHY_PASSWORD_DIALOG_FLAGS_SHOW_PASSWORD));
+ EphyPasswordDialog *password_dialog = EPHY_PASSWORD_DIALOG (dialog);
+ /* FIXME: set accept button text to _("I_mport Certificate") ? */
- higgy_setup_dialog (GTK_DIALOG (dialog), GTK_STOCK_DIALOG_QUESTION,
- &label, &vbox);
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
- msg = g_strdup_printf ("<span weight=\"bold\" size=\"larger\">%s</span>\n\n%s",
- _("Password required."),
- _("Enter the password for this certificate."));
- gtk_label_set_markup (GTK_LABEL (label), msg);
+ /* FIXME: mozilla sucks, no way to get the name of the certificate / cert file! */
+ char *msg = g_markup_printf_escaped (_("Enter the password for this certificate"));
+ gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), msg);
g_free (msg);
+
+ int response = gtk_dialog_run (GTK_DIALOG (dialog));
- hbox = gtk_hbox_new (FALSE, 6);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-
- label = gtk_label_new (NULL);
- entry = gtk_entry_new ();
-
- gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), _("_Password:"));
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
- gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
- gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
-
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
-
- gtk_widget_show_all (dialog);
- int ret = gtk_dialog_run (GTK_DIALOG (dialog));
-
- if (ret != GTK_RESPONSE_OK)
+ if (response == GTK_RESPONSE_ACCEPT)
{
- *_retval = PR_FALSE;
- }
- else
- {
- gchar * text = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
- NS_CStringToUTF16 (nsCString (text),
- NS_CSTRING_ENCODING_UTF8, _password);
- g_free (text);
- *_retval = PR_TRUE;
+ const char *pwd = ephy_password_dialog_get_password (password_dialog);
+ NS_CStringToUTF16 (nsDependentCString (pwd),
+ NS_CSTRING_ENCODING_UTF8, _password);
}
+
+ *_retval = response == GTK_RESPONSE_ACCEPT;
+
gtk_widget_destroy (dialog);
return NS_OK;
@@ -1036,17 +904,11 @@ GtkNSSDialogs::CrlImportStatusDialog(nsIInterfaceRequestor *ctx, nsICRLInfo *crl
if (NS_FAILED(rv)) return rv;
int row = 0;
- nsCString cOrg;
- NS_UTF16ToCString (org, NS_CSTRING_ENCODING_UTF8, cOrg);
- set_table_row (table, row, _("Organization:"), cOrg.get ());
+ set_table_row (table, row, _("Organization:"), NS_ConvertUTF16toUTF8 (org).get ());
- nsCString cOrgUnit;
- NS_UTF16ToCString (orgUnit, NS_CSTRING_ENCODING_UTF8, cOrgUnit);
- set_table_row (table, row, _("Unit:"), cOrgUnit.get ());
+ set_table_row (table, row, _("Unit:"), NS_ConvertUTF16toUTF8 (orgUnit).get ());
- nsCString cNextUpdate;
- NS_UTF16ToCString (nextUpdate, NS_CSTRING_ENCODING_UTF8, cNextUpdate);
- set_table_row (table, row, _("Next Update:"), cNextUpdate.get ());
+ set_table_row (table, row, _("Next Update:"), NS_ConvertUTF16toUTF8 (nextUpdate).get ());
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
@@ -1079,10 +941,8 @@ set_label_cert_attribute (GladeXML* gxml, const char* label_id, nsAString &value
}
else
{
- nsCString cValue;
- NS_UTF16ToCString (value, NS_CSTRING_ENCODING_UTF8, cValue);
gtk_label_set_use_markup (GTK_LABEL (label), FALSE);
- gtk_label_set_text (GTK_LABEL (label), cValue.get());
+ gtk_label_set_text (GTK_LABEL (label), NS_ConvertUTF16toUTF8 (value).get());
}
}
@@ -1116,8 +976,7 @@ fill_cert_chain_tree (GtkTreeView *treeview, nsIArray *certChain)
rv = nsCert->GetCommonName (value);
if (NS_FAILED(rv)) return FALSE;
- nsCString cValue;
- NS_UTF16ToCString (value, NS_CSTRING_ENCODING_UTF8, cValue);
+ NS_ConvertUTF16toUTF8 cValue (value);
nsIX509Cert *nsCertP = nsCert;
if (value.Length())
@@ -1161,14 +1020,11 @@ add_asn1_object_to_tree(GtkTreeModel *model, nsIASN1Object *object, GtkTreeIter
nsString dispNameU;
object->GetDisplayName(dispNameU);
- nsCString cDispNameU;
- NS_UTF16ToCString (dispNameU, NS_CSTRING_ENCODING_UTF8, cDispNameU);
-
GtkTreeIter iter;
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, parent);
gtk_tree_store_set (GTK_TREE_STORE(model), &iter,
- 0, cDispNameU.get(),
+ 0, NS_ConvertUTF16toUTF8 (dispNameU).get(),
1, object,
-1);
@@ -1243,10 +1099,7 @@ field_tree_view_selection_changed_cb (GtkTreeSelection *selection,
nsString dispValU;
object->GetDisplayValue(dispValU);
- nsCString cDispValU;
- NS_UTF16ToCString (dispValU, NS_CSTRING_ENCODING_UTF8, cDispValU);
-
- gtk_text_buffer_set_text (text_buffer, cDispValU.get(), -1);
+ gtk_text_buffer_set_text (text_buffer, NS_ConvertUTF16toUTF8 (dispValU).get(), -1);
}
else
{
@@ -1427,11 +1280,7 @@ GtkNSSDialogs::ViewCert(nsIInterfaceRequestor *ctx,
GtkWidget *indent;
for (PRUint32 i = 0 ; i < count ; i++)
{
- nsCString msg;
- NS_UTF16ToCString (nsString(usage[i]),
- NS_CSTRING_ENCODING_UTF8, msg);
-
- GtkWidget *label = gtk_label_new(msg.get());
+ GtkWidget *label = gtk_label_new (NS_ConvertUTF16toUTF8 (usage[i]).get());
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
nsMemory::Free (usage[i]);
@@ -1444,7 +1293,6 @@ GtkNSSDialogs::ViewCert(nsIInterfaceRequestor *ctx,
gtk_box_pack_start (GTK_BOX (widget), indent, FALSE, FALSE, 0);
}
-
cert->GetCommonName (value);
set_label_cert_attribute (gxml, "label_cn", value);
@@ -1515,3 +1363,181 @@ GtkNSSDialogs::ViewCert(nsIInterfaceRequestor *ctx,
gtk_widget_destroy (dialog);
return NS_OK;
}
+
+/* nsITokenPasswordDialogs */
+
+/* NOTE: This interface totally sucks, see https://bugzilla.mozilla.org/show_bug.cgi?id=306993 */
+
+/* void setPassword (in nsIInterfaceRequestor ctx, in wstring tokenName, out boolean canceled); */
+NS_IMETHODIMP
+GtkNSSDialogs::SetPassword(nsIInterfaceRequestor *aCtx,
+ const PRUnichar *aTokenName,
+ PRBool *aCancelled)
+{
+ NS_ENSURE_ARG_POINTER(aCancelled);
+
+ nsresult rv;
+ nsCOMPtr<nsIPK11Token> token;
+ nsCOMPtr<nsIPKCS11Slot> slot;
+ rv = GetTokenAndSlotFromName (aTokenName, getter_AddRefs (token),
+ getter_AddRefs (slot));
+ NS_ENSURE_SUCCESS (rv, rv);
+ NS_ENSURE_TRUE (token && slot, NS_ERROR_FAILURE);
+
+ AutoJSContextStack stack;
+ rv = stack.Init ();
+ if (NS_FAILED (rv)) return rv;
+
+ PRUint32 status = nsIPKCS11Slot::SLOT_UNINITIALIZED;
+ slot->GetStatus (&status);
+
+ nsCOMPtr<nsIDOMWindow> parent = do_GetInterface (aCtx);
+ GtkWidget *gparent = EphyUtils::FindGtkParent (parent);
+
+ EphyPasswordDialogFlags flags =
+ EphyPasswordDialogFlags (EPHY_PASSWORD_DIALOG_FLAGS_SHOW_NEW_PASSWORD |
+ EPHY_PASSWORD_DIALOG_FLAGS_SHOW_QUALITY_METER);
+ if (status != nsIPKCS11Slot::SLOT_UNINITIALIZED)
+ flags = EphyPasswordDialogFlags (flags | EPHY_PASSWORD_DIALOG_FLAGS_SHOW_PASSWORD);
+
+ GtkWidget *dialog = ephy_password_dialog_new
+ (gparent,
+ _("Change Token Password"),
+ flags);
+ EphyPasswordDialog *password_dialog = EPHY_PASSWORD_DIALOG (dialog);
+
+ char *message = g_markup_printf_escaped (_("Change the password for the “%s” token"),
+ NS_ConvertUTF16toUTF8 (aTokenName).get ());
+ gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog),
+ message);
+ g_free (message);
+
+ int response;
+ nsString oldPassword;
+ PRBool pwdOk, needsLogin;
+ do {
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (status != nsIPKCS11Slot::SLOT_UNINITIALIZED)
+ {
+ const char *pwd = ephy_password_dialog_get_password (password_dialog);
+ oldPassword = NS_ConvertUTF8toUTF16 (pwd);
+ }
+ } while (response == GTK_RESPONSE_OK &&
+ status != nsIPKCS11Slot::SLOT_UNINITIALIZED &&
+ NS_SUCCEEDED (token->NeedsLogin (&needsLogin)) && needsLogin &&
+ NS_SUCCEEDED (token->CheckPassword (oldPassword.get (), &pwdOk) &&
+ !pwdOk));
+
+ if (response == GTK_RESPONSE_ACCEPT)
+ {
+ const char *pwd = ephy_password_dialog_get_new_password (password_dialog);
+
+ NS_ConvertUTF8toUTF16 newPassword (pwd);
+
+ if (status == nsIPKCS11Slot::SLOT_UNINITIALIZED)
+ {
+ rv = token->InitPassword (newPassword.get ());
+ }
+ else
+ {
+ rv = token->ChangePassword (oldPassword.get (),
+ newPassword.get ());
+ }
+ }
+ else
+ {
+ rv = NS_OK;
+ }
+
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+
+ *aCancelled = response != GTK_RESPONSE_ACCEPT;
+
+ return rv;
+}
+
+/* void getPassword (in nsIInterfaceRequestor ctx, in wstring tokenName, out wstring password, out boolean canceled); */
+NS_IMETHODIMP
+GtkNSSDialogs::GetPassword(nsIInterfaceRequestor *aCtx,
+ const PRUnichar *aTokenName,
+ PRUnichar **aPassword,
+ PRBool *aCancelled)
+{
+ NS_ENSURE_ARG_POINTER(aCancelled);
+
+ nsresult rv;
+ nsCOMPtr<nsIPK11Token> token;
+ nsCOMPtr<nsIPKCS11Slot> slot;
+ rv = GetTokenAndSlotFromName (aTokenName, getter_AddRefs (token),
+ getter_AddRefs (slot));
+ NS_ENSURE_SUCCESS (rv, rv);
+ NS_ENSURE_TRUE (token && slot, NS_ERROR_FAILURE);
+
+ AutoJSContextStack stack;
+ rv = stack.Init ();
+ if (NS_FAILED (rv)) return rv;
+
+ nsCOMPtr<nsIDOMWindow> parent = do_GetInterface (aCtx);
+ GtkWidget *gparent = EphyUtils::FindGtkParent (parent);
+
+ EphyPasswordDialogFlags flags =
+ EphyPasswordDialogFlags (EPHY_PASSWORD_DIALOG_FLAGS_SHOW_PASSWORD);
+
+ GtkWidget *dialog = ephy_password_dialog_new
+ (gparent,
+ _("Get Token Password"), /* FIXME */
+ flags);
+ EphyPasswordDialog *password_dialog = EPHY_PASSWORD_DIALOG (dialog);
+
+ char *message = g_markup_printf_escaped (_("Please enter the password for the “%s” token"),
+ NS_ConvertUTF16toUTF8 (aTokenName).get ());
+ gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog),
+ message);
+ g_free (message);
+
+ int response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (response == GTK_RESPONSE_ACCEPT)
+ {
+ const char *pwd = ephy_password_dialog_get_password (password_dialog);
+ *aPassword = NS_StringCloneData (NS_ConvertUTF8toUTF16 (pwd));
+ }
+
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+
+ *aCancelled = response != GTK_RESPONSE_ACCEPT;
+
+ return NS_OK;
+}
+
+/* nsITokenDialogs */
+
+/* void ChooseToken (in nsIInterfaceRequestor ctx, [array, size_is (count)] in wstring tokenNameList, in unsigned long count, out wstring tokenName, out boolean canceled); */
+NS_IMETHODIMP
+GtkNSSDialogs::ChooseToken (nsIInterfaceRequestor *ctx,
+ const PRUnichar **tokenNameList,
+ PRUint32 count,
+ PRUnichar **tokenName,
+ PRBool *canceled)
+{
+ /* FIXME: implement me! The only caller is from nsKeygenHandler */
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* nsIDOMCryptoDialogs */
+
+/* Note: this interface sucks! See https://bugzilla.mozilla.org/show_bug.cgi?id=341914 */
+
+/* boolean ConfirmKeyEscrow (in nsIX509Cert escrowAuthority); */
+NS_IMETHODIMP
+GtkNSSDialogs::ConfirmKeyEscrow (nsIX509Cert *aEscrowAuthority,
+ PRBool *_retval)
+{
+ /* FIXME: show a dialogue to warn the user! */
+
+ /* Escrow is evil, don't allow it. */
+ *_retval = PR_FALSE;
+
+ return NS_OK;
+}
diff --git a/embed/mozilla/GtkNSSDialogs.h b/embed/mozilla/GtkNSSDialogs.h
index 8825e3ed5..162817850 100644
--- a/embed/mozilla/GtkNSSDialogs.h
+++ b/embed/mozilla/GtkNSSDialogs.h
@@ -1,8 +1,20 @@
/*
- * GtkNSSDialogs.h
+ * Copyright (C) 2003 Crispin Flowerday <gnome@flowerday.cx>
+ * Copyright (C) 2006 Christian Persch
*
- * Copyright (C) 2003 Crispin Flowerday <gnome@flowerday.cx>
- * Available under the terms of the GNU General Public License version 2.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Id$
*/
@@ -12,25 +24,38 @@
#include <nsIBadCertListener.h>
#include <nsICertificateDialogs.h>
+#include <nsITokenPasswordDialogs.h>
+#include <nsITokenDialogs.h>
+#include <nsIDOMCryptoDialogs.h>
+
+class nsIPK11Token;
+class nsIPKCS11Slot;
-// 7a50a10d-9425-4e12-84b1-5822edacd8ce
+/* 7a50a10d-9425-4e12-84b1-5822edacd8ce */
#define GTK_NSSDIALOGS_CID \
{0x7a50a10d, 0x9425, 0x4e12, {0x84, 0xb1, 0x58, 0x22, 0xed, 0xac, 0xd8, 0xce}}
#define GTK_NSSDIALOGS_CLASSNAME "Gtk NSS Dialogs"
-class GtkNSSDialogs
-: public nsIBadCertListener,
- public nsICertificateDialogs
+class GtkNSSDialogs : public nsIBadCertListener,
+ public nsICertificateDialogs,
+ public nsITokenPasswordDialogs,
+ public nsITokenDialogs,
+ public nsIDOMCryptoDialogs
{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIBADCERTLISTENER
- NS_DECL_NSICERTIFICATEDIALOGS
-
- GtkNSSDialogs();
- virtual ~GtkNSSDialogs();
+ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIBADCERTLISTENER
+ NS_DECL_NSICERTIFICATEDIALOGS
+ NS_DECL_NSITOKENPASSWORDDIALOGS
+ NS_DECL_NSITOKENDIALOGS
+ NS_DECL_NSIDOMCRYPTODIALOGS
+
+ GtkNSSDialogs();
+ virtual ~GtkNSSDialogs();
+
+ private:
+ nsresult GetTokenAndSlotFromName(const PRUnichar*, nsIPK11Token**, nsIPKCS11Slot**);
};
-
#endif /* GTKNSSDIALOGS_H */
diff --git a/embed/mozilla/GtkNSSKeyPairDialogs.cpp b/embed/mozilla/GtkNSSKeyPairDialogs.cpp
index f7f1e5eb3..238e183c7 100644
--- a/embed/mozilla/GtkNSSKeyPairDialogs.cpp
+++ b/embed/mozilla/GtkNSSKeyPairDialogs.cpp
@@ -23,16 +23,6 @@
/*
* This file provides Gtk implementations of the mozilla Generating Key Pair
* dialogs.
- *
- * This implementation takes some liberties with the mozilla API. Although the
- * API requires a nsIDomWindowInternal, it only actually calls the Close()
- * function on that class. Therefore we provide a dummy class that only
- * implements that function (it just sets a flag).
- *
- * Periodically we check to see whether the dialog should have been closed. If
- * it should be closed, then the key generation has finished, so close the dialog
- * (using gtk_dialog_response), and return.
- *
*/
#include "mozilla-config.h"
@@ -108,6 +98,8 @@ begin_busy (GtkWidget *widget)
if (!GTK_WIDGET_REALIZED (widget)) gtk_widget_realize (GTK_WIDGET(widget));
gdk_window_set_cursor (GTK_WIDGET (widget)->window, cursor);
+
+ /* Eek! FIXME: AutoJSContextStack! */
while (gtk_events_pending ()) gtk_main_iteration ();
}
@@ -139,8 +131,8 @@ generating_timeout_cb (KeyPairInfo *info)
}
-/* void displayGeneratingKeypairInfo (in nsIInterfaceRequestor ctx, in nsIKeygenTh
-read runnable); */
+/* void displayGeneratingKeypairInfo (in nsIInterfaceRequestor ctx,
+ in nsIKeygenThread runnable); */
NS_IMETHODIMP
GtkNSSKeyPairDialogs::DisplayGeneratingKeypairInfo (nsIInterfaceRequestor *ctx,
nsIKeygenThread *runnable)
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 439c356bb..e6d4bf638 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -19,6 +19,7 @@ NOINST_H_FILES = \
ephy-node-filter.h \
ephy-node-common.h \
ephy-object-helpers.h \
+ ephy-password-dialog.h \
ephy-prefs.h \
ephy-shlib-loader.h \
ephy-signal-accumulator.h \
@@ -29,6 +30,7 @@ NOINST_H_FILES = \
TYPES_H_FILES = \
ephy-adblock.h \
ephy-node.h \
+ ephy-password-dialog.h \
ephy-state.h
INST_H_FILES = \
@@ -57,6 +59,7 @@ libephymisc_la_SOURCES = \
ephy-node-common.h \
ephy-node-db.c \
ephy-object-helpers.c \
+ ephy-password-dialog.c \
ephy-prefs.h \
ephy-shlib-loader.c \
ephy-signal-accumulator.c \
diff --git a/lib/ephy-password-dialog.c b/lib/ephy-password-dialog.c
new file mode 100644
index 000000000..165d7a3ff
--- /dev/null
+++ b/lib/ephy-password-dialog.c
@@ -0,0 +1,707 @@
+/*
+ * Copyright (C) 2003 Crispin Flowerday <gnome@flowerday.cx>
+ * Copyright (C) 2005, 2006 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#ifndef DONT_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#ifdef ENABLE_KEYRING
+#include <gnome-keyring.h>
+#endif
+
+#include "ephy-gui.h"
+#include "ephy-lib-type-builtins.h"
+#include "ephy-state.h"
+
+#include "ephy-password-dialog.h"
+
+enum
+{
+ CHECK_USER = 1 << 0,
+ CHECK_DOMAIN = 1 << 1,
+ CHECK_PWD = 1 << 2,
+ CHECK_PWD_MATCH = 1 << 3,
+ CHECK_PWD_QUALITY = 1 << 4,
+ CHECK_MASK = 0x1f
+};
+
+enum
+{
+ USERNAME_ENTRY,
+ DOMAIN_ENTRY,
+ PASSWORD_ENTRY,
+ NEW_PASSWORD_ENTRY,
+ CONFIRM_PASSWORD_ENTRY,
+ N_ENTRIES
+};
+
+#define EPHY_PASSWORD_DIALOG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_PASSWORD_DIALOG, EphyPasswordDialogPrivate))
+
+struct _EphyPasswordDialogPrivate
+{
+ GtkWidget *entry[N_ENTRIES];
+ GtkWidget *quality_meter;
+ GtkWidget *remember_button[3];
+ gdouble quality_minimum;
+#if 0
+ char *realm;
+ char *keyring;
+
+ gpointer lookup_op;
+
+ guint keyring_enabled : 1;
+#endif
+ EphyPasswordDialogFlags flags;
+ guint checks : 5;
+};
+
+enum
+{
+ PROP_0,
+ PROP_FLAGS,
+ PROP_DOMAIN,
+ PROP_KEYRING,
+ PROP_KEYRING_ENABLED
+};
+
+G_DEFINE_TYPE (EphyPasswordDialog, ephy_password_dialog, GTK_TYPE_MESSAGE_DIALOG)
+
+/**
+ * Calculate the quality of a password. The algorithm used is taken
+ * directly from mozilla:
+ * mozilla/security/manager/pki/resources/content/password.js
+ */
+static gdouble
+password_quality (const char *text)
+{
+ const char *p;
+ gsize length;
+ int uppercase = 0, symbols = 0, numbers = 0, strength;
+ gunichar uc;
+
+ if (text == NULL) return 0.0;
+
+ /* Get the length */
+ length = g_utf8_strlen (text, -1);
+
+ /* Count the number of number, symbols and uppercase chars */
+ for (p = text; *p; p = g_utf8_find_next_char (p, NULL))
+ {
+ uc = g_utf8_get_char (p);
+
+ if (g_unichar_isdigit (uc))
+ {
+ numbers++;
+ }
+ else if (g_unichar_isupper (uc))
+ {
+ uppercase++;
+ }
+ else if (g_unichar_islower (uc))
+ {
+ /* Not counted */
+ }
+ else if (g_unichar_isgraph (uc))
+ {
+ symbols++;
+ }
+ }
+
+ if (length > 5) length = 5;
+ if (numbers > 3) numbers = 3;
+ if (symbols > 3) symbols = 3;
+ if (uppercase > 3) uppercase = 3;
+
+ strength = (length * 10 - 20) + (numbers * 10) + (symbols * 15) + (uppercase * 10);
+ strength = CLAMP (strength, 0, 100);
+
+ return ((gdouble) strength) / 100.0;
+}
+
+static void
+update_responses (EphyPasswordDialog *dialog)
+{
+ EphyPasswordDialogPrivate *priv = dialog->priv;
+
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
+ GTK_RESPONSE_ACCEPT,
+ priv->checks == 0);
+}
+
+static void
+entry_changed_cb (GtkWidget *entry,
+ EphyPasswordDialog *dialog)
+{
+ EphyPasswordDialogPrivate *priv = dialog->priv;
+ guint flag = 0;
+ const char *text;
+
+ if (entry == priv->entry[USERNAME_ENTRY])
+ {
+ flag = CHECK_USER;
+ }
+ else if (entry == priv->entry[DOMAIN_ENTRY])
+ {
+ flag = CHECK_DOMAIN;
+ }
+ else if (entry == priv->entry[PASSWORD_ENTRY])
+ {
+ flag = CHECK_PWD;
+ }
+
+ text = gtk_entry_get_text (GTK_ENTRY (entry));
+ if (text != NULL && text[0] != '\0')
+ {
+ priv->checks &= ~flag;
+ }
+ else
+ {
+ priv->checks |= flag;
+ }
+
+ update_responses (dialog);
+}
+
+static void
+password_entry_changed_cb (GtkWidget *entry,
+ EphyPasswordDialog *dialog)
+{
+ EphyPasswordDialogPrivate *priv = dialog->priv;
+ const char *text1, *text2;
+
+ text1 = gtk_entry_get_text (GTK_ENTRY (priv->entry[NEW_PASSWORD_ENTRY]));
+ text2 = gtk_entry_get_text (GTK_ENTRY (priv->entry[CONFIRM_PASSWORD_ENTRY]));
+
+ if (text1 != NULL && text2 != NULL && strcmp (text1, text2) == 0)
+ {
+ priv->checks &= ~CHECK_PWD_MATCH;
+ }
+ else
+ {
+ priv->checks |= CHECK_PWD_MATCH;
+ }
+
+ if ((priv->flags & EPHY_PASSWORD_DIALOG_FLAGS_SHOW_QUALITY_METER) &&
+ (entry == priv->entry[NEW_PASSWORD_ENTRY]))
+ {
+ gdouble quality;
+
+ quality = password_quality (text1);
+
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->quality_meter),
+ quality);
+
+ if (quality >= priv->quality_minimum)
+ {
+ priv->checks &= ~CHECK_PWD_QUALITY;
+ }
+ else
+ {
+ priv->checks |= CHECK_PWD_QUALITY;
+ }
+ }
+
+ update_responses (dialog);
+}
+
+/* Focuses the next entry */
+static void
+entry_activate_cb (GtkWidget *entry,
+ EphyPasswordDialog *dialog)
+{
+ EphyPasswordDialogPrivate *priv = dialog->priv;
+ int i;
+
+ for (i = 0; i < N_ENTRIES; ++i)
+ if (entry == priv->entry[i]) break;
+ g_assert (i < N_ENTRIES);
+
+ for ( ; i < N_ENTRIES; ++i)
+ if (priv->entry[i] != NULL &&
+ GTK_WIDGET_IS_SENSITIVE (priv->entry[i])) break;
+
+ if (i < N_ENTRIES)
+ gtk_widget_grab_focus (priv->entry[i]);
+ else
+ gtk_window_activate_default (GTK_WINDOW (dialog));
+}
+
+static void
+ephy_password_dialog_init (EphyPasswordDialog *dialog)
+{
+ EphyPasswordDialogPrivate *priv;
+
+ priv = dialog->priv = EPHY_PASSWORD_DIALOG_GET_PRIVATE (dialog);
+
+ priv->checks = 0;
+ priv->quality_minimum = 0.0;
+}
+
+static void
+add_row (GtkTable *table,
+ int row,
+ const char *text,
+ GtkWidget *widget)
+{
+ GtkWidget *label;
+
+ label = gtk_label_new_with_mnemonic (text);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+
+ gtk_table_attach (table, label,
+ 0, 1, row, row + 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_table_attach (table, widget,
+ 1, 2, row, row + 1,
+ GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
+
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
+}
+
+static GtkWidget *
+new_entry (EphyPasswordDialog *dialog,
+ GtkTable *table,
+ int row,
+ const char *text,
+ gboolean editable,
+ gboolean password,
+ GCallback changed_cb)
+{
+ GtkWidget *entry;
+
+ entry = gtk_entry_new ();
+ gtk_entry_set_visibility (GTK_ENTRY (entry), !password);
+ gtk_widget_set_sensitive (entry, editable);
+ g_signal_connect (entry, "changed", changed_cb, dialog);
+ g_signal_connect (entry, "activate",
+ G_CALLBACK (entry_activate_cb), dialog);
+
+ add_row (table, row, text, entry);
+
+ return entry;
+}
+
+#if 0
+static void
+update_capslock_warning (GtkWidget *widget,
+ gboolean show)
+{
+ //EphyPasswordDialog *dialog = EPHY_PASSWORD_DIALOG (dialog);
+ //EphyPasswordDialogPrivate *priv = dialog->priv;
+
+ g_print ("CapsLock is now %s\n", show?"on": "off");
+}
+
+static gboolean
+ephy_password_dialog_key_press (GtkWidget *widget,
+ GdkEventKey *event)
+{
+ /* The documentation says that LOCK_MASK may be either the
+ * Shift or the CapsLock key, but I've only ever seen this set
+ * with CapsLock on. So hopefully this code works ok :)
+ */
+ /* Pressing CapsLock when it was off: state-bit 0 keyval GDK_Caps_Lock
+ * Pressing CapsLock when it was on: state-bit 1 keyval GDK_Caps_Lock
+ * Pressing any key while CapsLock on: state-bit 1
+ */
+ if ((event->state & GDK_LOCK_MASK &&
+ event->keyval != GDK_Caps_Lock) ||
+ event->keyval == GDK_Caps_Lock)
+ {
+ update_capslock_warning (widget, TRUE);
+ }
+ else if ((event->state & GDK_LOCK_MASK) == 0 ||
+ ((event->state & GDK_LOCK_MASK) &&
+ event->keyval == GDK_Caps_Lock))
+ {
+ update_capslock_warning (widget, FALSE);
+ }
+
+ return GTK_WIDGET_CLASS (ephy_password_dialog_parent_class)->key_press_event (widget, event);
+}
+#endif
+
+static GObject *
+ephy_password_dialog_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_params)
+
+{
+ GObject *object;
+ GtkWindow *window;
+ GtkDialog *dialog;
+ GtkMessageDialog *message_dialog;
+ EphyPasswordDialog *password_dialog;
+ EphyPasswordDialogPrivate *priv;
+ GtkWidget *vbox;
+ GtkTable *table;
+ int row = 0;
+
+ object = G_OBJECT_CLASS (ephy_password_dialog_parent_class)->constructor
+ (type, n_construct_properties, construct_params);
+
+ priv = EPHY_PASSWORD_DIALOG (object)->priv;
+ window = GTK_WINDOW (object);
+ dialog = GTK_DIALOG (object);
+ message_dialog = GTK_MESSAGE_DIALOG (object);
+ password_dialog = EPHY_PASSWORD_DIALOG (object);
+
+ gtk_window_set_resizable (window, FALSE);
+ gtk_box_set_spacing (GTK_BOX (dialog->vbox), 2); /* Message has 24, we want 12 = 2 + 2 * 5 */
+
+ // gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
+ gtk_window_set_icon_name (window, "web-browser");
+
+ gtk_image_set_from_icon_name (GTK_IMAGE (message_dialog->image),
+ GTK_STOCK_DIALOG_AUTHENTICATION,
+ GTK_ICON_SIZE_DIALOG);
+
+ vbox = message_dialog->label->parent;
+
+ // fixme resize later
+ table = GTK_TABLE (gtk_table_new (6, 2, FALSE));
+ gtk_table_set_row_spacings (table, 6);
+ gtk_table_set_col_spacings (table, 12);
+ gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (table), FALSE, FALSE, 0);
+
+ if (priv->flags & EPHY_PASSWORD_DIALOG_FLAGS_SHOW_USERNAME)
+ {
+ priv->entry[USERNAME_ENTRY] =
+ new_entry (password_dialog,
+ table,
+ row++,
+ _("_Username:"),
+ priv->flags & EPHY_PASSWORD_DIALOG_FLAGS_EDIT_USERNAME,
+ FALSE,
+ G_CALLBACK (entry_changed_cb));
+
+ priv->checks |= CHECK_USER;
+ }
+
+ if (priv->flags & EPHY_PASSWORD_DIALOG_FLAGS_SHOW_DOMAIN)
+ {
+ priv->entry[DOMAIN_ENTRY] =
+ new_entry (password_dialog,
+ table,
+ row++,
+ _("_Domain:"),
+ priv->flags & EPHY_PASSWORD_DIALOG_FLAGS_EDIT_DOMAIN,
+ FALSE,
+ G_CALLBACK (entry_changed_cb));
+
+ priv->checks |= CHECK_DOMAIN;
+ }
+
+ if (priv->flags & EPHY_PASSWORD_DIALOG_FLAGS_SHOW_PASSWORD)
+ {
+ priv->entry[PASSWORD_ENTRY] =
+ new_entry (password_dialog,
+ table,
+ row++,
+ _("_Password:"),
+ TRUE,
+ TRUE,
+ G_CALLBACK (entry_changed_cb));
+
+ priv->checks |= CHECK_PWD;
+ }
+
+ if (priv->flags & EPHY_PASSWORD_DIALOG_FLAGS_SHOW_NEW_PASSWORD)
+ {
+ priv->entry[NEW_PASSWORD_ENTRY] =
+ new_entry (password_dialog,
+ table,
+ row++,
+ priv->flags & EPHY_PASSWORD_DIALOG_FLAGS_SHOW_PASSWORD ?
+ _("_New password:") :
+ _("_Password:"),
+ TRUE,
+ TRUE,
+ G_CALLBACK (password_entry_changed_cb));
+
+ priv->entry[CONFIRM_PASSWORD_ENTRY] =
+ new_entry (password_dialog,
+ table,
+ row++,
+ _("Con_firm password:"),
+ TRUE,
+ TRUE,
+ G_CALLBACK (password_entry_changed_cb));
+
+ priv->checks |= CHECK_PWD_MATCH;
+ }
+
+ /* Password quality meter */
+ /* TODO: We need a better password quality meter */
+ if (priv->flags & EPHY_PASSWORD_DIALOG_FLAGS_SHOW_NEW_PASSWORD &&
+ priv->flags & EPHY_PASSWORD_DIALOG_FLAGS_SHOW_QUALITY_METER)
+ {
+ priv->quality_meter = gtk_progress_bar_new ();
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->quality_meter), 0.0);
+
+ add_row (table, row++, _("Password quality:"), priv->quality_meter);
+
+ priv->checks |= CHECK_PWD_QUALITY;
+ }
+
+ /* Removed unused table rows */
+ gtk_table_resize (table, row, 2);
+
+ if (priv->flags & EPHY_PASSWORD_DIALOG_FLAGS_SHOW_REMEMBER)
+ {
+ GSList *group = NULL;
+ GtkWidget *rbox;
+
+ rbox = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (vbox), rbox, FALSE, FALSE, 0);
+
+ priv->remember_button[0] = gtk_radio_button_new_with_mnemonic (group, _("Do not remember this password"));
+ gtk_box_pack_start (GTK_BOX (rbox), priv->remember_button[0], FALSE, FALSE, 0);
+ group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (priv->remember_button[0]));
+
+ priv->remember_button[1] = gtk_radio_button_new_with_mnemonic (group, _("_Remember password for this session"));
+ gtk_box_pack_start (GTK_BOX (rbox), priv->remember_button[1], FALSE, FALSE, 0);
+ group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (priv->remember_button[1]));
+
+ priv->remember_button[2] = gtk_radio_button_new_with_mnemonic (group, _("Save password in _keyring"));
+ gtk_box_pack_start (GTK_BOX (rbox), priv->remember_button[2], FALSE, FALSE, 0);
+ }
+
+ gtk_dialog_add_button (dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+ gtk_dialog_add_button (dialog, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
+ gtk_dialog_set_default_response (dialog, GTK_RESPONSE_ACCEPT);
+ update_responses (password_dialog);
+
+ gtk_widget_show_all (vbox);
+
+ return object;
+}
+
+static void
+ephy_password_dialog_finalize (GObject *object)
+{
+// EphyPasswordDialog *dialog = EPHY_PASSWORD_DIALOG (object);
+// EphyPasswordDialogPrivate *priv = dialog->priv;
+
+ G_OBJECT_CLASS (ephy_password_dialog_parent_class)->finalize (object);
+}
+
+static void
+ephy_password_dialog_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ /* no readable properties */
+ g_assert_not_reached ();
+}
+
+static void
+ephy_password_dialog_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EphyPasswordDialogPrivate *priv = EPHY_PASSWORD_DIALOG (object)->priv;
+
+ switch (prop_id)
+ {
+ case PROP_FLAGS:
+ priv->flags = g_value_get_flags (value);
+ break;
+#if 0
+ case PROP_DOMAIN:
+ priv->realm = g_value_dup_string (value);
+ break;
+ case PROP_KEYRING:
+ priv->keyring = g_value_dup_string (value);
+ break;
+ case PROP_KEYRING_ENABLED:
+ priv->keyring_enabeld = g_value_get_boolean (value) != FALSE;
+ break;
+#endif
+ }
+}
+
+static void
+ephy_password_dialog_class_init (EphyPasswordDialogClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+// GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+// GtkDialogClass *dialog_class = GTK_DIALOG_CLASS (klass);
+
+ object_class->constructor = ephy_password_dialog_constructor;
+ object_class->finalize = ephy_password_dialog_finalize;
+ object_class->get_property = ephy_password_dialog_get_property;
+ object_class->set_property = ephy_password_dialog_set_property;
+
+// widget_class->key_press_event = ephy_password_dialog_key_press;
+
+// dialog_class->response = ephy_password_dialog_response;
+
+ g_type_class_add_private (object_class, sizeof (EphyPasswordDialogPrivate));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_FLAGS,
+ g_param_spec_flags ("flags",
+ "flags",
+ "flags",
+ EPHY_TYPE_PASSWORD_DIALOG_FLAGS,
+ EPHY_PASSWORD_DIALOG_FLAGS_DEFAULT,
+ G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB |
+ G_PARAM_CONSTRUCT_ONLY));
+#if 0
+ g_object_class_install_property (object_class,
+ PROP_DOMAIN,
+ g_param_spec_string ("realm",
+ "realm",
+ "realm",
+ NULL,
+ G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (object_class,
+ PROP_KEYRING,
+ g_param_spec_string ("keyring",
+ "keyring",
+ "keyring",
+ NULL,
+ G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (object_class,
+ PROP_KEYRING_ENABLED,
+ g_param_spec_boolean ("keyring-enabled",
+ "keyring-enabled",
+ "keyring-enabled",
+ TRUE,
+ G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB |
+ G_PARAM_CONSTRUCT_ONLY));
+#endif
+}
+
+GtkWidget *
+ephy_password_dialog_new (GtkWidget *parent,
+ const char *title,
+ EphyPasswordDialogFlags flags)
+{
+ return g_object_new (EPHY_TYPE_PASSWORD_DIALOG,
+ "transient-for", parent,
+ "title", title,
+ "message-type", GTK_MESSAGE_OTHER,
+ "flags", flags,
+ (gpointer) NULL);
+}
+
+void
+ephy_password_dialog_set_remember (EphyPasswordDialog *dialog,
+ GnomePasswordDialogRemember remember)
+{
+ EphyPasswordDialogPrivate *priv;
+
+ g_return_if_fail (EPHY_IS_PASSWORD_DIALOG (dialog));
+ g_return_if_fail (remember < GNOME_PASSWORD_DIALOG_REMEMBER_NOTHING ||
+ remember > GNOME_PASSWORD_DIALOG_REMEMBER_FOREVER);
+
+ priv = dialog->priv;
+ g_return_if_fail (priv->flags & EPHY_PASSWORD_DIALOG_FLAGS_SHOW_REMEMBER);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->remember_button[remember]), TRUE);
+}
+
+GnomePasswordDialogRemember
+ephy_password_dialog_get_remember (EphyPasswordDialog *dialog)
+{
+ EphyPasswordDialogPrivate *priv;
+ GnomePasswordDialogRemember remember = GNOME_PASSWORD_DIALOG_REMEMBER_NOTHING;
+
+ g_return_val_if_fail (EPHY_IS_PASSWORD_DIALOG (dialog), remember);
+
+ priv = dialog->priv;
+ g_return_val_if_fail (priv->flags & EPHY_PASSWORD_DIALOG_FLAGS_SHOW_REMEMBER, remember);
+
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->remember_button[0])))
+ remember = GNOME_PASSWORD_DIALOG_REMEMBER_NOTHING;
+ else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->remember_button[1])))
+ remember = GNOME_PASSWORD_DIALOG_REMEMBER_SESSION;
+ else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->remember_button[2])))
+ remember = GNOME_PASSWORD_DIALOG_REMEMBER_FOREVER;
+
+ return remember;
+}
+
+const char *
+ephy_password_dialog_get_username (EphyPasswordDialog *dialog)
+{
+ EphyPasswordDialogPrivate *priv;
+
+ g_return_val_if_fail (EPHY_IS_PASSWORD_DIALOG (dialog), NULL);
+
+ priv = dialog->priv;
+ g_return_val_if_fail (priv->flags & EPHY_PASSWORD_DIALOG_FLAGS_SHOW_USERNAME, NULL);
+
+ return gtk_entry_get_text (GTK_ENTRY (priv->entry[USERNAME_ENTRY]));
+}
+
+const char *
+ephy_password_dialog_get_domain (EphyPasswordDialog *dialog)
+{
+ EphyPasswordDialogPrivate *priv;
+
+ g_return_val_if_fail (EPHY_IS_PASSWORD_DIALOG (dialog), NULL);
+
+ priv = dialog->priv;
+ g_return_val_if_fail (priv->flags & EPHY_PASSWORD_DIALOG_FLAGS_SHOW_DOMAIN, NULL);
+
+ return gtk_entry_get_text (GTK_ENTRY (priv->entry[DOMAIN_ENTRY]));
+}
+
+const char *
+ephy_password_dialog_get_password (EphyPasswordDialog *dialog)
+{
+ EphyPasswordDialogPrivate *priv;
+
+ g_return_val_if_fail (EPHY_IS_PASSWORD_DIALOG (dialog), NULL);
+
+ priv = dialog->priv;
+ g_return_val_if_fail (priv->flags & EPHY_PASSWORD_DIALOG_FLAGS_SHOW_PASSWORD, NULL);
+
+ return gtk_entry_get_text (GTK_ENTRY (priv->entry[PASSWORD_ENTRY]));
+}
+
+const char *
+ephy_password_dialog_get_new_password (EphyPasswordDialog *dialog)
+{
+ EphyPasswordDialogPrivate *priv;
+
+ g_return_val_if_fail (EPHY_IS_PASSWORD_DIALOG (dialog), NULL);
+
+ priv = dialog->priv;
+ g_return_val_if_fail (priv->flags & EPHY_PASSWORD_DIALOG_FLAGS_SHOW_NEW_PASSWORD, NULL);
+
+ return gtk_entry_get_text (GTK_ENTRY (priv->entry[NEW_PASSWORD_ENTRY]));
+}
diff --git a/lib/ephy-password-dialog.h b/lib/ephy-password-dialog.h
new file mode 100644
index 000000000..6da76f12b
--- /dev/null
+++ b/lib/ephy-password-dialog.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2005 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#ifndef EPHY_PASSWORD_DIALOG_H
+#define EPHY_PASSWORD_DIALOG_H
+
+#include <gtk/gtkmessagedialog.h>
+#include <libgnomeui/gnome-password-dialog.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_PASSWORD_DIALOG (ephy_password_dialog_get_type ())
+#define EPHY_PASSWORD_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_PASSWORD_DIALOG, EphyPasswordDialog))
+#define EPHY_PASSWORD_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_PASSWORD_DIALOG, EphyPasswordDialogClass))
+#define EPHY_IS_PASSWORD_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_PASSWORD_DIALOG))
+#define EPHY_IS_PASSWORD_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_PASSWORD_DIALOG))
+#define EPHY_PASSWORD_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_PASSWORD_DIALOG, EphyPasswordDialogClass))
+
+typedef struct _EphyPasswordDialog EphyPasswordDialog;
+typedef struct _EphyPasswordDialogPrivate EphyPasswordDialogPrivate;
+typedef struct _EphyPasswordDialogClass EphyPasswordDialogClass;
+
+struct _EphyPasswordDialog
+{
+ GtkMessageDialog parent_instance;
+
+ /*< private >*/
+ EphyPasswordDialogPrivate *priv;
+};
+
+struct _EphyPasswordDialogClass
+{
+ GtkMessageDialogClass parent_class;
+};
+
+typedef enum
+{
+ EPHY_PASSWORD_DIALOG_FLAGS_SHOW_USERNAME = 1 << 0,
+ EPHY_PASSWORD_DIALOG_FLAGS_EDIT_USERNAME = 1 << 1,
+ EPHY_PASSWORD_DIALOG_FLAGS_SHOW_DOMAIN = 1 << 2,
+ EPHY_PASSWORD_DIALOG_FLAGS_EDIT_DOMAIN = 1 << 3,
+ EPHY_PASSWORD_DIALOG_FLAGS_SHOW_PASSWORD = 1 << 4,
+ EPHY_PASSWORD_DIALOG_FLAGS_SHOW_NEW_PASSWORD = 1 << 5,
+ EPHY_PASSWORD_DIALOG_FLAGS_SHOW_QUALITY_METER = 1 << 6,
+ EPHY_PASSWORD_DIALOG_FLAGS_SHOW_REMEMBER = 1 << 7,
+} EphyPasswordDialogFlags;
+
+#define EPHY_PASSWORD_DIALOG_FLAGS_DEFAULT 0
+
+GType ephy_password_dialog_get_type (void);
+
+GtkWidget *ephy_password_dialog_new (GtkWidget *parent,
+ const char *title,
+ EphyPasswordDialogFlags flags);
+
+void ephy_password_dialog_set_remember (EphyPasswordDialog *dialog,
+ GnomePasswordDialogRemember remember);
+
+GnomePasswordDialogRemember ephy_password_dialog_get_remember (EphyPasswordDialog *dialog);
+
+void ephy_password_dialog_set_label (EphyPasswordDialog *dialog,
+ const char *markup);
+
+GtkWidget *ephy_password_dialog_get_username_entry (EphyPasswordDialog *dialog);
+
+const char *ephy_password_dialog_get_username (EphyPasswordDialog *dialog);
+
+void ephy_password_dialog_set_username (EphyPasswordDialog *dialog,
+ const char *text);
+
+const char *ephy_password_dialog_get_domain (EphyPasswordDialog *dialog);
+
+void ephy_password_dialog_set_domain (EphyPasswordDialog *dialog,
+ const char *text);
+
+const char *ephy_password_dialog_get_password (EphyPasswordDialog *dialog);
+
+void ephy_password_dialog_set_password (EphyPasswordDialog *dialog,
+ const char *text);
+
+const char *ephy_password_dialog_get_new_password (EphyPasswordDialog *dialog);
+
+G_END_DECLS
+
+#endif /* !EPHY_PASSWORD_DIALOG_H */