[evolution-ews] Bug #674867 - Change Password Feature for EWS connector
- From: Vibha Yadav <yvibha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews] Bug #674867 - Change Password Feature for EWS connector
- Date: Tue, 22 May 2012 08:26:19 +0000 (UTC)
commit 42388b57936edff49e7aba6bc9689db54690c25a
Author: Vibha Yadav <yvibha suse com>
Date: Tue May 22 13:51:48 2012 +0530
Bug #674867 - Change Password Feature for EWS connector
Note: Add --with-krb5 to configure argument list for enabling the feature.
Also add the realms in krb5.conf file for Kerberos communication
and working feature.
configure.ac | 11 +
m4/evo_krb5_support.m4 | 136 ++++++++
src/account-setup-eplugin/Makefile.am | 2 +
.../exchange-ews-account-setup.c | 7 +-
.../exchange-ews-change-password.c | 364 ++++++++++++++++++++
.../exchange-ews-change-password.h | 25 ++
src/server/Makefile.am | 11 +
src/server/ews-kerberos.c | 195 +++++++++++
src/server/ews-kerberos.h | 33 ++
9 files changed, 783 insertions(+), 1 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index fca79e0..80f4fc3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,7 @@
AC_PREREQ(2.58)
AC_INIT([evolution-ews], [3.5.2], [http://bugzilla.gnome.org/browse.cgi?product=evolution-ews])
AM_INIT_AUTOMAKE([gnu 1.9 dist-xz no-dist-gzip -Wno-portability])
+AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR(README)
AC_CONFIG_HEADERS(config.h)
@@ -166,6 +167,11 @@ dnl ****************************
PKG_CHECK_MODULES(LIBICAL, libical)
dnl ****************************
+dnl Check for kerberos
+dnl ****************************
+EVO_KRB5_SUPPORT
+
+dnl ****************************
dnl Expose version information
dnl ****************************
API_VERSION=1.2
@@ -231,3 +237,8 @@ src/camel/Makefile
po/Makefile.in
])
AC_OUTPUT
+
+AC_MSG_NOTICE([
+ Kerberos 5 : $msg_krb5
+])
+
diff --git a/m4/evo_krb5_support.m4 b/m4/evo_krb5_support.m4
new file mode 100644
index 0000000..ba37e81
--- /dev/null
+++ b/m4/evo_krb5_support.m4
@@ -0,0 +1,136 @@
+dnl EVO_KRB5_SUPPORT(default)
+dnl Add --with-krb5, --with-krb5-libs and --with-krb5-include options.
+dnl --with-krb5 defaults to the given value if not specified.
+#serial 0.2
+AC_DEFUN([EVO_KRB5_SUPPORT],[
+ dnl ******************************
+ dnl Kerberos
+ dnl ******************************
+ default="$1"
+ AC_ARG_WITH([krb5],
+ AS_HELP_STRING([--with-krb5=PATH],
+ [Location of Kerberos 5 install dir]))
+
+ AC_ARG_WITH([krb5-libs],
+ AS_HELP_STRING([--with-krb5-libs=PATH],
+ [Location of Kerberos 5 libraries]))
+
+ AC_ARG_WITH([krb5-includes],
+ AS_HELP_STRING([--with-krb5-includes=PATH],
+ [Location of Kerberos 5 headers]))
+
+ dnl ******************************
+ dnl Kerberos 5
+ dnl ******************************
+ msg_krb5="no"
+ AC_MSG_CHECKING([for Kerberos 5])
+ with_krb5="${with_krb5:=$default}"
+ case $with_krb5 in
+ no|"")
+ with_krb5=no
+ ;;
+ yes)
+ with_krb5=/usr
+ ;;
+ *)
+ with_krb5=$with_krb5
+ ;;
+ esac
+
+ if test "x${with_krb5}" != "xno"; then
+ LIBS_save="$LIBS"
+
+ case $with_krb5_libs in
+ yes|no|"")
+ with_krb5_libs=$with_krb5/lib
+ ;;
+ *)
+ with_krb5_libs=$with_krb5_libs
+ ;;
+ esac
+
+ case $with_krb5_includes in
+ yes|no|"")
+ with_krb5_includes=$with_krb5/include
+ ;;
+ *)
+ with_krb5_includes=$with_krb5_includes
+ ;;
+ esac
+
+ mitlibs="-lkrb5 -lk5crypto -lcom_err -lgssapi_krb5"
+ heimlibs="-lkrb5 -lcrypto -lasn1 -lcom_err -lroken -lgssapi"
+ sunlibs="-lkrb5 -lgss"
+ AC_CACHE_VAL([ac_cv_lib_kerberos5],
+ [
+ LIBS="$LIBS -L$with_krb5_libs $mitlibs"
+ AC_LINK_IFELSE([AC_LANG_CALL([], [krb5_init_context])],
+ [ac_cv_lib_kerberos5="$mitlibs"],
+ [
+ LIBS="$LIBS_save -L$with_krb5_libs $heimlibs"
+ AC_LINK_IFELSE([AC_LANG_CALL([], [krb5_init_context])],
+ [ac_cv_lib_kerberos5="$heimlibs"],
+ [
+ LIBS="$LIBS_save -L$with_krb5_libs $sunlibs"
+ AC_LINK_IFELSE([AC_LANG_CALL([], [krb5_init_context])],
+ [ac_cv_lib_kerberos5="$sunlibs"], [ac_cv_lib_kerberos5="no"])
+ ])
+ ])
+ LIBS="$LIBS_save"
+ ])
+ if test "$ac_cv_lib_kerberos5" != "no"; then
+ AC_DEFINE(HAVE_KRB5,1,[Define if you have Krb5])
+ if test "$ac_cv_lib_kerberos5" = "$mitlibs"; then
+ AC_DEFINE(HAVE_MIT_KRB5,1,[Define if you have MIT Krb5])
+ if test -z "$with_krb5_includes"; then
+ KRB5_CFLAGS="-I$with_krb5/include"
+ else
+ KRB5_CFLAGS="-I$with_krb5_includes"
+ fi
+ msg_krb5="yes (MIT)"
+ else
+ if test "$ac_cv_lib_kerberos5" = "$heimlibs"; then
+ AC_DEFINE(HAVE_HEIMDAL_KRB5,1,[Define if you have Heimdal])
+ if test -z "$with_krb5_includes"; then
+ KRB5_CFLAGS="-I$with_krb5/include/heimdal"
+ else
+ KRB5_CFLAGS="-I$with_krb5_includes"
+ fi
+ msg_krb5="yes (Heimdal)"
+ else
+ AC_DEFINE(HAVE_SUN_KRB5,1,[Define if you have Sun Kerberosv5])
+ if test -z "$with_krb5_includes"; then
+ KRB5_CFLAGS="-I$with_krb5/include/kerberosv5"
+ else
+ KRB5_CFLAGS="-I$with_krb5_includes"
+ fi
+ msg_krb5="yes (Sun)"
+ fi
+ fi
+ KRB5_LIBS="-L$with_krb5_libs $ac_cv_lib_kerberos5"
+ else
+ AC_MSG_ERROR([You specified with krb5, but it was not found.])
+ fi
+ else
+ msg_krb5="no"
+ fi
+ AC_MSG_RESULT([$msg_krb5])
+
+ AM_CONDITIONAL(ENABLE_KRB5, [test "x$with_krb5" != "xno"])
+
+ AC_CHECK_HEADER([et/com_err.h],
+ [AC_DEFINE([HAVE_ET_COM_ERR_H], 1, [Have <et/com_err.h>])],,
+ [[ #if HAVE_ET_COM_ERR_H
+ #include <com_err.h>
+ #endif
+ ]])
+ AC_CHECK_HEADER([com_err.h],
+ [AC_DEFINE([HAVE_COM_ERR_H], 1, [Have <com_err.h>])],,
+ [[ #if HAVE_COM_ERR_H
+ #include <com_err.h>
+ #endif
+ ]])
+
+ AC_SUBST(KRB5_CFLAGS)
+ AC_SUBST(KRB5_LIBS)
+])
diff --git a/src/account-setup-eplugin/Makefile.am b/src/account-setup-eplugin/Makefile.am
index d597335..620b7ed 100644
--- a/src/account-setup-eplugin/Makefile.am
+++ b/src/account-setup-eplugin/Makefile.am
@@ -36,6 +36,8 @@ liborg_gnome_exchange_ews_la_SOURCES = \
exchange-ews-account-listener.h \
exchange-ews-account-out-of-office.c \
exchange-ews-account-out-of-office.h \
+ exchange-ews-change-password.c \
+ exchange-ews-change-password.h \
$(NULL)
liborg_gnome_exchange_ews_la_LIBADD = \
diff --git a/src/account-setup-eplugin/exchange-ews-account-setup.c b/src/account-setup-eplugin/exchange-ews-account-setup.c
index b2682ca..eadc36f 100644
--- a/src/account-setup-eplugin/exchange-ews-account-setup.c
+++ b/src/account-setup-eplugin/exchange-ews-account-setup.c
@@ -50,6 +50,7 @@
#include "exchange-ews-account-out-of-office.h"
#include "exchange-ews-account-setup.h"
+#include "exchange-ews-change-password.h"
#define d(x) x
@@ -744,7 +745,7 @@ org_gnome_ews_settings (EPlugin *epl,
{
EMConfigTargetSettings *target_account;
GtkVBox *vbox_settings;
- GtkWidget *oof;
+ GtkWidget *oof, *chgpwd;
target_account = (EMConfigTargetSettings *) data->config->target;
@@ -767,6 +768,10 @@ org_gnome_ews_settings (EPlugin *epl,
oof = ews_get_outo_office_widget (target_account);
gtk_box_pack_start (GTK_BOX (vbox_settings), oof, FALSE, FALSE, 0);
+ /*Get Change Password widget*/
+ chgpwd = ews_get_change_pwd_widget (target_account);
+ gtk_box_pack_start (GTK_BOX (vbox_settings), chgpwd, FALSE, FALSE, 0);
+
gtk_widget_show_all (GTK_WIDGET (vbox_settings));
gtk_notebook_insert_page (GTK_NOTEBOOK (data->parent), GTK_WIDGET (vbox_settings), gtk_label_new(_("EWS Settings")), 4);
return GTK_WIDGET (vbox_settings);
diff --git a/src/account-setup-eplugin/exchange-ews-change-password.c b/src/account-setup-eplugin/exchange-ews-change-password.c
new file mode 100644
index 0000000..f08536b
--- /dev/null
+++ b/src/account-setup-eplugin/exchange-ews-change-password.c
@@ -0,0 +1,364 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Authors : Vibha Yadav <yvibha suse com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/* exchange-ews-change-password: Change Password code */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "server/e-ews-connection.h"
+#include "server/ews-kerberos.h"
+#include "utils/camel-ews-settings.h"
+#include "mail/em-config.h"
+#include <libedataserverui/e-passwords.h>
+#include <exchange-ews-account-setup.h>
+#include <e-util/e-dialog-utils.h>
+#include <stdlib.h>
+
+#include "exchange-ews-change-password.h"
+#include <gtk/gtk.h>
+
+
+#ifdef HAVE_KRB5
+static void
+entry_changed (GtkEntry *entry,
+ gpointer user_data)
+{
+ GtkEntry *new_entry, *confirm_entry;
+ GtkDialog *pass_dialog;
+ const gchar *text;
+
+ new_entry = GTK_ENTRY (entry);
+ confirm_entry = GTK_ENTRY (user_data);
+ pass_dialog = GTK_DIALOG (g_object_get_data (G_OBJECT (new_entry), "pass_dialog"));
+
+ text = gtk_entry_get_text (new_entry);
+ if (!text || !*text) {
+ gtk_dialog_set_response_sensitive (pass_dialog, GTK_RESPONSE_OK, FALSE);
+ return;
+ }
+
+ text = gtk_entry_get_text (confirm_entry);
+ if (!text || !*text) {
+ gtk_dialog_set_response_sensitive (pass_dialog, GTK_RESPONSE_OK, FALSE);
+ return;
+ }
+
+ gtk_dialog_set_response_sensitive (pass_dialog, GTK_RESPONSE_OK, TRUE);
+}
+
+static gchar *
+get_password (EMConfigTargetSettings *target_account)
+{
+ gchar *key, *password = NULL;
+ CamelSettings *settings;
+ CamelURL *url;
+
+ settings = target_account->storage_settings;
+
+ url = g_malloc0 (sizeof (CamelURL));
+ camel_settings_save_to_url (settings, url);
+ key = camel_url_to_string (url, CAMEL_URL_HIDE_PARAMS);
+ camel_url_free (url);
+
+ password = e_passwords_get_password (EXCHANGE_EWS_PASSWORD_COMPONENT, key);
+ if (!password || !*password) {
+ CamelNetworkSettings *network_settings;
+ const gchar *host;
+ gboolean remember = TRUE;
+ gchar *title;
+
+ network_settings = CAMEL_NETWORK_SETTINGS (settings);
+ host = camel_network_settings_get_host (network_settings);
+
+ g_free (password);
+ title = g_strdup_printf ("Enter Password for %s", host);
+ password = e_passwords_ask_password (title, EXCHANGE_EWS_PASSWORD_COMPONENT, key, title,
+ E_PASSWORDS_REMEMBER_FOREVER | E_PASSWORDS_SECRET,
+ &remember, NULL);
+ g_free (title);
+ }
+
+ if (!password || !*password) {
+ e_passwords_forget_password (EXCHANGE_EWS_PASSWORD_COMPONENT, key);
+ e_notice (NULL, GTK_MESSAGE_ERROR, "%s","Could not get password.");
+ }
+
+ g_free (key);
+
+ return password;
+}
+
+static gboolean
+e_ews_set_password (EMConfigTargetSettings *account,
+ const gchar *old_pwd,
+ const gchar *new_pwd)
+{
+ CamelSettings *settings;
+ CamelNetworkSettings *network_settings;
+ CamelURL *url;
+ EwsKerberosResult result;
+
+ const gchar *user;
+ const gchar *domain;
+ gchar *key;
+
+ /*add up code to call up kerberos set up*/
+ /*Get domain name*/
+ /*pass on username domain name, old and new password to kerberos libraries*/
+ settings = account->storage_settings;
+
+ if (!CAMEL_IS_EWS_SETTINGS (settings))
+ return FALSE;
+
+ /* Verify the storage and transport settings are shared. */
+ g_warn_if_fail (
+ account->storage_settings ==
+ account->transport_settings);
+
+ network_settings = CAMEL_NETWORK_SETTINGS (settings);
+
+ domain = camel_network_settings_get_host (network_settings);
+
+ user = camel_network_settings_get_user (network_settings);
+
+ result = ews_kerberos_change_password (user, domain, old_pwd, new_pwd);
+
+ if(result != EWS_KERBEROS_OK)
+ return FALSE;
+
+ /*On Success add new password to the keyring*/
+
+ url = g_malloc0 (sizeof (CamelURL));
+ camel_settings_save_to_url (settings, url);
+ key = camel_url_to_string (url, CAMEL_URL_HIDE_PARAMS);
+ camel_url_free (url);
+
+ e_passwords_forget_password (EXCHANGE_EWS_PASSWORD_COMPONENT, key);
+ e_passwords_add_password (key, new_pwd);
+ return TRUE;
+}
+#endif
+
+/**
+ * exchange_get_new_password:
+ * @existing_password: The user's current password
+ * @voluntary: %TRUE if the user has chosen "Change Password",
+ * %FALSE if their old password has expired.
+ *
+ * Prompt the user for a new password.
+ */
+gchar *
+e_ews_get_new_password (const gchar *existing_password,
+ gboolean voluntary)
+{
+ gchar *new_pass = NULL;
+#ifdef HAVE_KRB5
+ GtkResponseType response;
+ GtkWidget *pass_dialog;
+ GtkWidget *dialog_vbox1;
+ GtkWidget *pass_label;
+ GtkWidget *table1;
+ GtkWidget *current_pass_label;
+ GtkWidget *new_pass_label;
+ GtkWidget *confirm_pass_label;
+ GtkWidget *current_pass_entry;
+ GtkWidget *new_pass_entry;
+ GtkWidget *confirm_pass_entry;
+
+ pass_dialog = gtk_dialog_new_with_buttons (
+ "Change Password",
+ NULL,
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+
+ dialog_vbox1 = gtk_dialog_get_content_area (GTK_DIALOG (pass_dialog));
+ gtk_widget_show (dialog_vbox1);
+
+ pass_label = gtk_label_new ("Your current password has expired. Please change your password now.");
+ gtk_widget_show (pass_label);
+ gtk_box_pack_start (GTK_BOX (dialog_vbox1), pass_label, FALSE, FALSE, 0);
+ gtk_label_set_justify (GTK_LABEL (pass_label), GTK_JUSTIFY_CENTER);
+ gtk_label_set_line_wrap (GTK_LABEL (pass_label), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (pass_label), 0.52, 0.5);
+ gtk_misc_set_padding (GTK_MISC (pass_label), 0, 6);
+
+ table1 = gtk_table_new (3, 2, FALSE);
+ gtk_widget_show (table1);
+ gtk_box_pack_start (GTK_BOX (dialog_vbox1), table1, TRUE, TRUE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (table1), 6);
+ gtk_table_set_row_spacings (GTK_TABLE (table1), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table1), 6);
+
+ current_pass_label = gtk_label_new_with_mnemonic ("Current _Password:");
+ gtk_widget_show (current_pass_label);
+ gtk_table_attach (GTK_TABLE (table1), current_pass_label, 0, 1, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (current_pass_label), 0, 0.5);
+
+ new_pass_label = gtk_label_new_with_mnemonic ("_New Password:");
+ gtk_widget_show (new_pass_label);
+ gtk_table_attach (GTK_TABLE (table1), new_pass_label, 0, 1, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (new_pass_label), 0, 0.5);
+
+ confirm_pass_label = gtk_label_new_with_mnemonic ("_Confirm Password:");
+ gtk_widget_show (confirm_pass_label);
+ gtk_table_attach (GTK_TABLE (table1), confirm_pass_label, 0, 1, 2, 3,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (confirm_pass_label), 0, 0.5);
+
+ new_pass_entry = gtk_entry_new ();
+ gtk_widget_show (new_pass_entry);
+ gtk_table_attach (GTK_TABLE (table1), new_pass_entry, 1, 2, 1, 2,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_entry_set_visibility (GTK_ENTRY (new_pass_entry), FALSE);
+
+ confirm_pass_entry = gtk_entry_new ();
+ gtk_widget_show (confirm_pass_entry);
+ gtk_table_attach (GTK_TABLE (table1), confirm_pass_entry, 1, 2, 2, 3,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_entry_set_visibility (GTK_ENTRY (confirm_pass_entry), FALSE);
+
+ current_pass_entry = gtk_entry_new ();
+ gtk_widget_show (current_pass_entry);
+ gtk_table_attach (GTK_TABLE (table1), current_pass_entry, 1, 2, 0, 1,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 12);
+ gtk_entry_set_visibility (GTK_ENTRY (current_pass_entry), FALSE);
+
+ g_object_set_data (G_OBJECT (new_pass_entry), "pass_dialog", pass_dialog);
+ g_object_set_data (G_OBJECT (confirm_pass_entry), "pass_dialog", pass_dialog);
+ g_signal_connect (new_pass_entry, "changed", G_CALLBACK (entry_changed), confirm_pass_entry);
+ g_signal_connect (confirm_pass_entry, "changed", G_CALLBACK (entry_changed), new_pass_entry);
+ entry_changed (GTK_ENTRY (new_pass_entry), confirm_pass_entry);
+
+ if (voluntary)
+ gtk_widget_hide (GTK_WIDGET (pass_label));
+
+run_dialog_again:
+ response = gtk_dialog_run (GTK_DIALOG (pass_dialog));
+ if (response == GTK_RESPONSE_OK) {
+ const gchar *cur_pass, *new_pass1, *new_pass2;
+
+ cur_pass = gtk_entry_get_text (GTK_ENTRY (current_pass_entry));
+ new_pass1 = gtk_entry_get_text (GTK_ENTRY (new_pass_entry));
+ new_pass2 = gtk_entry_get_text (GTK_ENTRY (confirm_pass_entry));
+
+ if (existing_password) {
+ if (g_strcmp0 (cur_pass, existing_password) != 0) {
+ /* User entered a wrong existing
+ * password. Prompt him again.
+ */
+ gtk_label_set_text (GTK_LABEL (pass_label), "The current password should not match the existing password for your account. Please enter the correct password");
+ gtk_widget_show (pass_label);
+ goto run_dialog_again;
+ }
+ }
+
+ if (g_strcasecmp (new_pass1, new_pass2) != 0) {
+ gtk_label_set_text (GTK_LABEL (pass_label), "The two passwords do not match. Please re-enter the passwords.");
+ gtk_widget_show (pass_label);
+ goto run_dialog_again;
+ }
+
+ if (g_strcasecmp (existing_password, new_pass1) == 0)
+ {
+ gtk_label_set_text (GTK_LABEL (pass_label), "The new password matches old password. Please re-enter the passwords.");
+ gtk_widget_show (pass_label);
+ goto run_dialog_again;
+ }
+
+ new_pass = g_strdup (new_pass1);
+ } else
+ new_pass = g_strdup(""); /*Don't use NULL it crashes on kerberos libraries*/
+
+ gtk_widget_destroy (pass_dialog);
+#endif
+
+ return new_pass;
+}
+
+
+static void
+btn_chpass_clicked (GtkButton *button,
+ gpointer data)
+{
+#ifdef HAVE_KRB5
+ EMConfigTargetSettings *target_account = (EMConfigTargetSettings *) data;
+ gchar *password, *new_password;
+ password = get_password(target_account);
+ new_password = e_ews_get_new_password ( password, TRUE);
+ g_print("Password is %s \n New password is %s", password, new_password);
+
+ if(e_ews_set_password(target_account, password, new_password))
+ e_notice(button, GTK_MESSAGE_INFO, "Password changed successfully. Please remember the same.");
+ else
+#endif
+ e_notice(button, GTK_MESSAGE_ERROR, "Could not reset password. Please try again.");
+}
+
+GtkWidget *
+ews_get_change_pwd_widget (EMConfigTargetSettings *target_account)
+{
+ GtkFrame *frame;
+ GtkWidget *label;
+ GtkVBox *vbox_auth;
+ GtkTable *tbl_auth;
+ GtkLabel *lbl_chpass;
+ GtkButton *btn_chpass;
+
+ gchar *txt;
+
+ txt = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>", "Security Settings");
+ label = gtk_label_new (NULL);
+ gtk_label_set_markup ((GtkLabel *) label, txt);
+ g_free (txt);
+ frame = (GtkFrame*) g_object_new (GTK_TYPE_FRAME, "label-widget", label, NULL);
+
+ /*Create a VBox*/
+ vbox_auth = (GtkVBox*) g_object_new (GTK_TYPE_VBOX, "homogeneous", FALSE, "spacing", 6, NULL);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox_auth), 6);
+ gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET (vbox_auth));
+
+ /*Table for authentication*/
+ tbl_auth = (GtkTable*) g_object_new (GTK_TYPE_TABLE, "n-rows", 2, "n-columns", 2, "homogeneous", FALSE, "row-spacing", 6, "column-spacing", 6, NULL);
+
+ /*Define label and button for change password*/
+ lbl_chpass = (GtkLabel*) g_object_new (GTK_TYPE_LABEL, "label", "Change the password for Exchange EWS account", NULL);
+ gtk_misc_set_alignment (GTK_MISC (lbl_chpass), 0, 0.5);
+ btn_chpass = (GtkButton*) g_object_new (GTK_TYPE_BUTTON, "label", "Change Password", NULL);
+ g_signal_connect (btn_chpass, "clicked", G_CALLBACK (btn_chpass_clicked), target_account);
+
+ gtk_table_attach_defaults (tbl_auth, GTK_WIDGET (lbl_chpass), 0, 1, 0, 1);
+ gtk_table_attach (tbl_auth, GTK_WIDGET (btn_chpass), 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+
+ gtk_box_pack_start (GTK_BOX (vbox_auth), GTK_WIDGET (tbl_auth), FALSE, FALSE, 0);
+
+ return (GtkWidget *) frame;
+}
diff --git a/src/account-setup-eplugin/exchange-ews-change-password.h b/src/account-setup-eplugin/exchange-ews-change-password.h
new file mode 100644
index 0000000..3c71295
--- /dev/null
+++ b/src/account-setup-eplugin/exchange-ews-change-password.h
@@ -0,0 +1,25 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Authors : Vibha Yadav <yvibha suse com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+#include <gtk/gtk.h>
+#include "mail/em-config.h"
+
+gchar *e_ews_get_new_password (const gchar *existing_password, gboolean voluntary);
+GtkWidget *ews_get_change_pwd_widget (EMConfigTargetSettings *target_account);
diff --git a/src/server/Makefile.am b/src/server/Makefile.am
index 3df8d3e..580967e 100644
--- a/src/server/Makefile.am
+++ b/src/server/Makefile.am
@@ -18,6 +18,14 @@ ews-marshal.c: ews-marshal.h
e-ews-connection.c: $(MARSHAL_GENERATED)
+if ENABLE_KRB5
+KERBEROS_FILES = \
+ ews-kerberos.c \
+ ews-kerberos.h
+else
+KERBEROS_FILES =
+endif
+
libeews_1_2_la_CPPFLAGS = \
$(AM_CPPFLAGS) \
-DG_LOG_DOMAIN=\"libeews\" \
@@ -29,6 +37,7 @@ libeews_1_2_la_CPPFLAGS = \
$(LIBECAL_CFLAGS) \
$(LIBICAL_CFLAGS) \
$(LIBEDATASERVER_CFLAGS) \
+ $(KRB5_CFLAGS) \
$(DEBUG_CFLAGS) \
$(NULL)
@@ -37,6 +46,7 @@ libeews_1_2_la_SOURCES = \
ews-errors.c \
ews-marshal.h \
ews-marshal.c \
+ $(KERBEROS_FILES) \
e-ews-connection.c \
e-ews-connection.h \
e-ews-folder.c \
@@ -54,6 +64,7 @@ libeews_1_2_la_LIBADD = \
$(LIBECAL_LIBS) \
$(LIBICAL_LIBS) \
$(LIBEDATASERVER_LIBS) \
+ $(KRB5_LIBS) \
$(SOCKET_LIBS) \
$(NULL)
diff --git a/src/server/ews-kerberos.c b/src/server/ews-kerberos.c
new file mode 100644
index 0000000..bbececd
--- /dev/null
+++ b/src/server/ews-kerberos.c
@@ -0,0 +1,195 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/* Copyright (C) 2004 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ews-kerberos.h"
+#include <krb5.h>
+
+static krb5_context
+ews_kerberos_context_new (const gchar *domain)
+{
+ krb5_context ctx;
+ gchar *realm;
+
+ if (krb5_init_context (&ctx) != 0)
+ return NULL;
+
+ realm = g_ascii_strup (domain, strlen (domain));
+ krb5_set_default_realm (ctx, realm);
+ g_free (realm);
+
+ return ctx;
+}
+
+static EwsKerberosResult
+krb5_result_to_ews_kerberos_result (gint result)
+{
+ switch (result) {
+ case 0:
+ return EWS_KERBEROS_OK;
+
+ case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
+ return EWS_KERBEROS_USER_UNKNOWN;
+
+ case KRB5KRB_AP_ERR_BAD_INTEGRITY:
+ case KRB5KDC_ERR_PREAUTH_FAILED:
+ case KRB5KDC_ERR_CLIENT_REVOKED:
+ return EWS_KERBEROS_PASSWORD_INCORRECT;
+
+ case KRB5KDC_ERR_KEY_EXP:
+ return EWS_KERBEROS_PASSWORD_EXPIRED;
+
+ case KRB5_KDC_UNREACH:
+ return EWS_KERBEROS_KDC_UNREACHABLE;
+
+ case KRB5KRB_AP_ERR_SKEW:
+ return EWS_KERBEROS_TIME_SKEW;
+
+ default:
+ g_warning ("Unexpected kerberos error %d", result);
+
+ case KRB5_REALM_UNKNOWN:
+ return EWS_KERBEROS_FAILED;
+ }
+}
+
+static EwsKerberosResult
+get_init_cred (krb5_context ctx,
+ const gchar *usr_name,
+ const gchar *passwd,
+ const gchar *in_tkt_service,
+ krb5_creds *cred)
+{
+ krb5_principal principal;
+ krb5_get_init_creds_opt opt;
+ krb5_error_code result;
+
+ result = krb5_parse_name (ctx, usr_name, &principal);
+ if (result)
+ return EWS_KERBEROS_USER_UNKNOWN;
+
+ krb5_get_init_creds_opt_init (&opt);
+ krb5_get_init_creds_opt_set_tkt_life (&opt, 5 *60);
+ krb5_get_init_creds_opt_set_renew_life (&opt, 0);
+ krb5_get_init_creds_opt_set_forwardable (&opt, 0);
+ krb5_get_init_creds_opt_set_proxiable (&opt, 0);
+
+ result = krb5_get_init_creds_password (ctx, cred, principal,
+ (gchar *) passwd,
+ NULL, NULL, 0,
+ (gchar *) in_tkt_service, &opt);
+ krb5_free_principal (ctx, principal);
+
+ return krb5_result_to_ews_kerberos_result (result);
+}
+
+/**
+ * ews_kerberos_change_password
+ * @user: username
+ * @domain: domain name
+ * @old_password: currrent password
+ * @new_password: password to be changed to
+ *
+ * Changes the password for the given user
+ *
+ * Return value: an #EwsKerberosResult
+ **/
+EwsKerberosResult
+ews_kerberos_change_password (const gchar *user,
+ const gchar *domain,
+ const gchar *old_password,
+ const gchar *new_password)
+{
+ krb5_context ctx;
+ krb5_creds creds;
+ krb5_data res_code_string, res_string;
+ EwsKerberosResult result;
+ gint res_code;
+
+ ctx = ews_kerberos_context_new (domain);
+ if (!ctx)
+ return EWS_KERBEROS_FAILED;
+
+ result = get_init_cred (ctx, user, old_password,
+ "kadmin/changepw", &creds);
+ if (result != EWS_KERBEROS_OK) {
+ krb5_free_context (ctx);
+ return result;
+ }
+
+ result = krb5_change_password (ctx, &creds, (gchar *) new_password,
+ &res_code, &res_code_string, &res_string);
+
+ g_print("%s", res_code_string.data);
+ krb5_free_cred_contents (ctx, &creds);
+ krb5_free_data_contents (ctx, &res_code_string);
+ krb5_free_data_contents (ctx, &res_string);
+ krb5_free_context (ctx);
+
+ if (result != 0)
+ return krb5_result_to_ews_kerberos_result (result);
+ else if (res_code != 0)
+ return EWS_KERBEROS_FAILED;
+ else
+ return EWS_KERBEROS_OK;
+ /*Check for res code and pop up res_string*/
+}
+
+/**
+ * ews_kerberos_check_password:
+ * @user: username
+ * @domain: domain name
+ * @password: current password
+ *
+ * Checks if the password is valid, invalid, or expired
+ *
+ * Return value: %EWS_KERBEROS_OK, %EWS_KERBEROS_USER_UNKNOWN,
+ * %EWS_KERBEROS_PASSWORD_INCORRECT, %EWS_KERBEROS_PASSWORD_EXPIRED,
+ * or %EWS_KERBEROS_FAILED (for unknown errors)
+ **/
+EwsKerberosResult
+ews_kerberos_check_password (const gchar *user,
+ const gchar *domain,
+ const gchar *password)
+{
+ krb5_context ctx;
+ krb5_creds creds;
+ EwsKerberosResult result;
+
+ ctx = ews_kerberos_context_new (domain);
+ if (!ctx)
+ return EWS_KERBEROS_FAILED;
+
+ result = get_init_cred (ctx, user, password, NULL, &creds);
+
+ krb5_free_context (ctx);
+ if (result == EWS_KERBEROS_OK)
+ krb5_free_cred_contents (ctx, &creds);
+
+ return result;
+}
diff --git a/src/server/ews-kerberos.h b/src/server/ews-kerberos.h
new file mode 100644
index 0000000..1c82117
--- /dev/null
+++ b/src/server/ews-kerberos.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* Copyright (C) 2004 Novell, Inc. */
+
+#ifndef __EWS_KERBEROS_H__
+#define __EWS_KERBEROS_H__
+
+G_BEGIN_DECLS
+
+typedef enum {
+ EWS_KERBEROS_OK,
+ EWS_KERBEROS_USER_UNKNOWN,
+ EWS_KERBEROS_PASSWORD_INCORRECT,
+ EWS_KERBEROS_PASSWORD_EXPIRED,
+ EWS_KERBEROS_PASSWORD_TOO_WEAK,
+
+ EWS_KERBEROS_KDC_UNREACHABLE,
+ EWS_KERBEROS_TIME_SKEW,
+
+ EWS_KERBEROS_FAILED
+} EwsKerberosResult;
+
+EwsKerberosResult ews_kerberos_check_password (const gchar *user,
+ const gchar *domain,
+ const gchar *password);
+
+EwsKerberosResult ews_kerberos_change_password (const gchar *user,
+ const gchar *domain,
+ const gchar *old_password,
+ const gchar *new_password);
+
+G_END_DECLS
+
+#endif /* __EWS_KERBEROS_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]