From 2f8390928641951691bc6d5b86a4310b2d81fc3d Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Wed, 1 Dec 2010 14:37:40 +0000 Subject: configure: depend on tp-glib >= 0.13.7 for tp-glib codegen Signed-off-by: Jonny Lamb --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 20de382b9..4ed8d9e24 100644 --- a/configure.ac +++ b/configure.ac @@ -39,7 +39,7 @@ KEYRING_REQUIRED=2.26.0 LIBCANBERRA_GTK_REQUIRED=0.25 LIBNOTIFY_REQUIRED=0.7.0 TELEPATHY_FARSIGHT_REQUIRED=0.0.14 -TELEPATHY_GLIB_REQUIRED=0.13.1.1 +TELEPATHY_GLIB_REQUIRED=0.13.7 TELEPATHY_LOGGER=0.1.5 # Optional deps -- cgit v1.2.3 From a76960e927b5f32387c17bb580d360669d6aace8 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Wed, 1 Dec 2010 14:39:00 +0000 Subject: debug: add SASL debug flag and key Signed-off-by: Jonny Lamb --- libempathy/empathy-debug.c | 1 + libempathy/empathy-debug.h | 1 + 2 files changed, 2 insertions(+) diff --git a/libempathy/empathy-debug.c b/libempathy/empathy-debug.c index dd507bc42..4f624f8e1 100644 --- a/libempathy/empathy-debug.c +++ b/libempathy/empathy-debug.c @@ -53,6 +53,7 @@ static GDebugKey keys[] = { { "Tests", EMPATHY_DEBUG_TESTS }, { "Voip", EMPATHY_DEBUG_VOIP }, { "Tls", EMPATHY_DEBUG_TLS }, + { "Sasl", EMPATHY_DEBUG_SASL }, { 0, } }; diff --git a/libempathy/empathy-debug.h b/libempathy/empathy-debug.h index ece3af73c..44e197792 100644 --- a/libempathy/empathy-debug.h +++ b/libempathy/empathy-debug.h @@ -47,6 +47,7 @@ typedef enum EMPATHY_DEBUG_TESTS = 1 << 12, EMPATHY_DEBUG_VOIP = 1 << 13, EMPATHY_DEBUG_TLS = 1 << 14, + EMPATHY_DEBUG_SASL = 1 << 15, } EmpathyDebugFlags; gboolean empathy_debug_flag_is_set (EmpathyDebugFlags flag); -- cgit v1.2.3 From 53ead42832d2af12c9487a6f8b370787442940f9 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Wed, 1 Dec 2010 14:39:48 +0000 Subject: auth-factory: also handle auth channels Signed-off-by: Jonny Lamb --- data/Empathy.Auth.client | 4 ++++ libempathy/empathy-auth-factory.c | 13 ++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/data/Empathy.Auth.client b/data/Empathy.Auth.client index 4c6adc0de..1fbf10368 100644 --- a/data/Empathy.Auth.client +++ b/data/Empathy.Auth.client @@ -4,3 +4,7 @@ Interfaces=org.freedesktop.Telepathy.Client.Handler [org.freedesktop.Telepathy.Client.Handler.HandlerChannelFilter 0] org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.ServerTLSConnection org.freedesktop.Telepathy.Channel.TargetHandleType u=0 + +[org.freedesktop.Telepathy.Client.Handler.HandlerChannelFilter 1] +org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.ServerAuthentication +org.freedesktop.Telepathy.Channel.Type.ServerAuthentication s=org.freedesktop.Telepathy.Channel.Interface.SASLAuthentication diff --git a/libempathy/empathy-auth-factory.c b/libempathy/empathy-auth-factory.c index fa2b7dcd1..fa706d5fd 100644 --- a/libempathy/empathy-auth-factory.c +++ b/libempathy/empathy-auth-factory.c @@ -218,12 +218,23 @@ empathy_auth_factory_init (EmpathyAuthFactory *self) FALSE, handle_channels_cb, self, NULL); tp_base_client_take_handler_filter (priv->handler, tp_asv_new ( + /* ChannelType */ TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, EMP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION, + /* AuthenticationMethod */ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_NONE, NULL)); - g_object_unref (bus); + tp_base_client_take_handler_filter (priv->handler, tp_asv_new ( + /* ChannelType */ + TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, + TP_IFACE_CHANNEL_TYPE_SERVER_AUTHENTICATION, + /* AuthenticationMethod */ + TP_PROP_CHANNEL_TYPE_SERVER_AUTHENTICATION_AUTHENTICATION_METHOD, + G_TYPE_STRING, TP_IFACE_CHANNEL_INTERFACE_SASL_AUTHENTICATION, + NULL)); + + g_object_unref (bus); } static void -- cgit v1.2.3 From fcd80516f561eec897df4c750a1d15573bbdeb91 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Wed, 1 Dec 2010 14:40:35 +0000 Subject: auth-factory: add EmpathyAuthFactory::new-server-sasl-handler Signed-off-by: Jonny Lamb --- libempathy/empathy-auth-factory.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libempathy/empathy-auth-factory.c b/libempathy/empathy-auth-factory.c index fa706d5fd..5b338516d 100644 --- a/libempathy/empathy-auth-factory.c +++ b/libempathy/empathy-auth-factory.c @@ -41,6 +41,7 @@ typedef struct { enum { NEW_SERVER_TLS_HANDLER, + NEW_SERVER_SASL_HANDLER, LAST_SIGNAL, }; @@ -270,6 +271,15 @@ empathy_auth_factory_class_init (EmpathyAuthFactoryClass *klass) g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, EMPATHY_TYPE_SERVER_TLS_HANDLER); + + signals[NEW_SERVER_SASL_HANDLER] = + g_signal_new ("new-server-sasl-handler", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, 0, + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, EMPATHY_TYPE_SERVER_SASL_HANDLER); } EmpathyAuthFactory * -- cgit v1.2.3 From 2aef97996f1b3e033ad886cc80f66a0e3b4e1957 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Wed, 1 Dec 2010 14:46:44 +0000 Subject: server-sasl-handler: added Signed-off-by: Jonny Lamb --- libempathy/Makefile.am | 2 + libempathy/empathy-server-sasl-handler.c | 264 +++++++++++++++++++++++++++++++ libempathy/empathy-server-sasl-handler.h | 71 +++++++++ 3 files changed, 337 insertions(+) create mode 100644 libempathy/empathy-server-sasl-handler.c create mode 100644 libempathy/empathy-server-sasl-handler.h diff --git a/libempathy/Makefile.am b/libempathy/Makefile.am index 9b0dcfb92..5122e073d 100644 --- a/libempathy/Makefile.am +++ b/libempathy/Makefile.am @@ -49,6 +49,7 @@ libempathy_headers = \ empathy-irc-server.h \ empathy-location.h \ empathy-message.h \ + empathy-server-sasl-handler.h \ empathy-server-tls-handler.h \ empathy-status-presets.h \ empathy-time.h \ @@ -87,6 +88,7 @@ libempathy_la_SOURCES = \ empathy-irc-network.c \ empathy-irc-server.c \ empathy-message.c \ + empathy-server-sasl-handler.c \ empathy-server-tls-handler.c \ empathy-status-presets.c \ empathy-time.c \ diff --git a/libempathy/empathy-server-sasl-handler.c b/libempathy/empathy-server-sasl-handler.c new file mode 100644 index 000000000..5c1e9d203 --- /dev/null +++ b/libempathy/empathy-server-sasl-handler.c @@ -0,0 +1,264 @@ +/* + * empathy-server-sasl-handler.c - Source for EmpathyServerSASLHandler + * Copyright (C) 2010 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "empathy-server-sasl-handler.h" + +#include + +#define DEBUG_FLAG EMPATHY_DEBUG_SASL +#include "empathy-debug.h" +#include "empathy-utils.h" + +enum { + PROP_CHANNEL = 1, + LAST_PROPERTY, +}; + +/* signal enum */ +enum { + INVALIDATED, + LAST_SIGNAL, +}; + +static guint signals[LAST_SIGNAL] = {0}; + +typedef struct { + TpChannel *channel; + + GSimpleAsyncResult *result; +} EmpathyServerSASLHandlerPriv; + +G_DEFINE_TYPE (EmpathyServerSASLHandler, empathy_server_sasl_handler, + G_TYPE_OBJECT); + +#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyServerSASLHandler); + +static const gchar *sasl_statuses[] = { + "not started", + "in progress", + "server succeeded", + "client accepted", + "succeeded", + "server failed", + "client failed", +}; + +static void +sasl_status_changed_cb (TpChannel *channel, + TpSASLStatus status, + const gchar *error, + GHashTable *details, + gpointer user_data, + GObject *weak_object) +{ + EmpathyServerSASLHandlerPriv *priv = GET_PRIV (weak_object); + + DEBUG ("SASL status changed to '%s'", sasl_statuses[status]); + + if (status == TP_SASL_STATUS_SERVER_SUCCEEDED) + { + tp_cli_channel_interface_sasl_authentication_call_accept_sasl ( + priv->channel, -1, NULL, NULL, NULL, NULL); + + tp_cli_channel_call_close (priv->channel, -1, + NULL, NULL, NULL, NULL); + } +} + +static void +channel_invalidated_cb (TpProxy *proxy, + guint domain, + gint code, + gchar *message, + EmpathyServerSASLHandler *self) +{ + g_signal_emit (self, signals[INVALIDATED], 0); +} + +static void +empathy_server_sasl_handler_constructed (GObject *object) +{ + EmpathyServerSASLHandlerPriv *priv; + GError *error = NULL; + + priv = GET_PRIV (object); + + tp_cli_channel_interface_sasl_authentication_connect_to_sasl_status_changed (priv->channel, + sasl_status_changed_cb, NULL, NULL, object, &error); + + if (error != NULL) + { + DEBUG ("Failed to connect to SASLStatusChanged: %s", error->message); + g_clear_error (&error); + } + + tp_g_signal_connect_object (priv->channel, "invalidated", + G_CALLBACK (channel_invalidated_cb), object, 0); +} + +static void +empathy_server_sasl_handler_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + EmpathyServerSASLHandlerPriv *priv = GET_PRIV (object); + + switch (property_id) + { + case PROP_CHANNEL: + g_value_set_object (value, priv->channel); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +empathy_server_sasl_handler_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + EmpathyServerSASLHandlerPriv *priv = GET_PRIV (object); + + switch (property_id) + { + case PROP_CHANNEL: + priv->channel = g_value_dup_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +empathy_server_sasl_handler_dispose (GObject *object) +{ + EmpathyServerSASLHandlerPriv *priv = GET_PRIV (object); + + DEBUG ("%p", object); + + tp_clear_object (&priv->channel); + + G_OBJECT_CLASS (empathy_server_sasl_handler_parent_class)->dispose (object); +} + +static void +empathy_server_sasl_handler_class_init (EmpathyServerSASLHandlerClass *klass) +{ + GObjectClass *oclass = G_OBJECT_CLASS (klass); + GParamSpec *pspec; + + oclass->constructed = empathy_server_sasl_handler_constructed; + oclass->get_property = empathy_server_sasl_handler_get_property; + oclass->set_property = empathy_server_sasl_handler_set_property; + oclass->dispose = empathy_server_sasl_handler_dispose; + + g_type_class_add_private (klass, sizeof (EmpathyServerSASLHandlerPriv)); + + pspec = g_param_spec_object ("channel", "The TpChannel", + "The TpChannel this handler is supposed to handle.", + TP_TYPE_CHANNEL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (oclass, PROP_CHANNEL, pspec); + + signals[INVALIDATED] = g_signal_new ("invalidated", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +empathy_server_sasl_handler_init (EmpathyServerSASLHandler *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + EMPATHY_TYPE_SERVER_SASL_HANDLER, EmpathyServerSASLHandlerPriv); +} + +EmpathyServerSASLHandler * +empathy_server_sasl_handler_new (TpChannel *channel) +{ + g_return_val_if_fail (TP_IS_CHANNEL (channel), NULL); + + return g_object_new (EMPATHY_TYPE_SERVER_SASL_HANDLER, + "channel", channel, NULL); +} + +static void +start_mechanism_with_data_cb (TpChannel *proxy, + const GError *error, + gpointer user_data, + GObject *weak_object) +{ + if (error != NULL) + { + DEBUG ("Failed to start mechanism: %s", error->message); + return; + } + + DEBUG ("Started mechanism successfully"); +} + +void +empathy_server_sasl_handler_provide_password ( + EmpathyServerSASLHandler *handler, + const gchar *password) +{ + EmpathyServerSASLHandlerPriv *priv; + GArray *array; + + g_return_if_fail (EMPATHY_IS_SERVER_SASL_HANDLER (handler)); + + priv = GET_PRIV (handler); + + array = g_array_sized_new (TRUE, FALSE, + sizeof (gchar), strlen (password)); + + g_array_append_vals (array, password, strlen (password)); + + DEBUG ("Calling StartMechanismWithData with our password"); + + tp_cli_channel_interface_sasl_authentication_call_start_mechanism_with_data ( + priv->channel, -1, "X-TELEPATHY-PASSWORD", array, start_mechanism_with_data_cb, + NULL, NULL, G_OBJECT (handler)); + + g_array_unref (array); +} + +void +empathy_server_sasl_handler_cancel (EmpathyServerSASLHandler *handler) +{ + EmpathyServerSASLHandlerPriv *priv; + + g_return_if_fail (EMPATHY_IS_SERVER_SASL_HANDLER (handler)); + + priv = GET_PRIV (handler); + + DEBUG ("Cancelling SASL mechanism..."); + + tp_cli_channel_interface_sasl_authentication_call_abort_sasl ( + priv->channel, -1, TP_SASL_ABORT_REASON_USER_ABORT, + "User cancelled the authentication", + NULL, NULL, NULL, NULL); +} diff --git a/libempathy/empathy-server-sasl-handler.h b/libempathy/empathy-server-sasl-handler.h new file mode 100644 index 000000000..71f8d2a78 --- /dev/null +++ b/libempathy/empathy-server-sasl-handler.h @@ -0,0 +1,71 @@ +/* + * empathy-server-sasl-handler.h - Header for EmpathyServerSASLHandler + * Copyright (C) 2010 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __EMPATHY_SERVER_SASL_HANDLER_H__ +#define __EMPATHY_SERVER_SASL_HANDLER_H__ + +#include +#include + +#include + +G_BEGIN_DECLS + +typedef struct _EmpathyServerSASLHandler EmpathyServerSASLHandler; +typedef struct _EmpathyServerSASLHandlerClass EmpathyServerSASLHandlerClass; + +struct _EmpathyServerSASLHandlerClass { + GObjectClass parent_class; +}; + +struct _EmpathyServerSASLHandler { + GObject parent; + gpointer priv; +}; + +GType empathy_server_sasl_handler_get_type (void); + +#define EMPATHY_TYPE_SERVER_SASL_HANDLER \ + (empathy_server_sasl_handler_get_type ()) +#define EMPATHY_SERVER_SASL_HANDLER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_SERVER_SASL_HANDLER, \ + EmpathyServerSASLHandler)) +#define EMPATHY_SERVER_SASL_HANDLER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), EMPATHY_TYPE_SERVER_SASL_HANDLER, \ + EmpathyServerSASLHandlerClass)) +#define EMPATHY_IS_SERVER_SASL_HANDLER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), EMPATHY_TYPE_SERVER_SASL_HANDLER)) +#define EMPATHY_IS_SERVER_SASL_HANDLER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), EMPATHY_TYPE_SERVER_SASL_HANDLER)) +#define EMPATHY_SERVER_SASL_HANDLER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_SERVER_SASL_HANDLER, \ + EmpathyServerSASLHandlerClass)) + +EmpathyServerSASLHandler * empathy_server_sasl_handler_new ( + TpChannel *channel); + +void empathy_server_sasl_handler_provide_password ( + EmpathyServerSASLHandler *handler, const gchar *password); + +void empathy_server_sasl_handler_cancel (EmpathyServerSASLHandler *handler); + + +G_END_DECLS + +#endif /* #ifndef __EMPATHY_SERVER_SASL_HANDLER_H__*/ -- cgit v1.2.3 From 81d9ab0e356681fb49c43c7bd7bf75bdf84122bc Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Wed, 1 Dec 2010 14:47:39 +0000 Subject: auth-factory: create ServerSASLHandlers and signal them appearing Signed-off-by: Jonny Lamb --- libempathy/empathy-auth-factory.c | 90 +++++++++++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 12 deletions(-) diff --git a/libempathy/empathy-auth-factory.c b/libempathy/empathy-auth-factory.c index 5b338516d..29af7dd44 100644 --- a/libempathy/empathy-auth-factory.c +++ b/libempathy/empathy-auth-factory.c @@ -26,6 +26,7 @@ #define DEBUG_FLAG EMPATHY_DEBUG_TLS #include "empathy-debug.h" +#include "empathy-server-sasl-handler.h" #include "empathy-server-tls-handler.h" #include "empathy-utils.h" @@ -36,6 +37,11 @@ G_DEFINE_TYPE (EmpathyAuthFactory, empathy_auth_factory, G_TYPE_OBJECT); typedef struct { TpBaseClient *handler; + /* Keep a ref here so the auth client doesn't have to mess with + * refs. It will be cleared when the channel (and so the handler) + * gets invalidated. */ + EmpathyServerSASLHandler *sasl_handler; + gboolean dispose_run; } EmpathyAuthFactoryPriv; @@ -111,6 +117,18 @@ server_tls_handler_ready_cb (GObject *source, handler_context_data_free (data); } +static void +sasl_handler_invalidated_cb (EmpathyServerSASLHandler *handler, + gpointer user_data) +{ + EmpathyAuthFactory *self = user_data; + EmpathyAuthFactoryPriv *priv = GET_PRIV (self); + + DEBUG ("SASL handler is invalidated, unref it"); + + tp_clear_object (&priv->sasl_handler); +} + static void handle_channels_cb (TpSimpleHandler *handler, TpAccount *account, @@ -125,18 +143,22 @@ handle_channels_cb (TpSimpleHandler *handler, const GError *dbus_error; GError *error = NULL; EmpathyAuthFactory *self = user_data; + EmpathyAuthFactoryPriv *priv = GET_PRIV (self); HandlerContextData *data; + GHashTable *props; + const gchar * const *available_mechanisms; - DEBUG ("Handle TLS carrier channels."); + DEBUG ("Handle TLS or SASL carrier channels."); - /* there can't be more than one ServerTLSConnection channels - * at the same time, for the same connection/account. + /* there can't be more than one ServerTLSConnection or + * ServerAuthentication channels at the same time, for the same + * connection/account. */ if (g_list_length (channels) != 1) { g_set_error_literal (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "Can't handle more than one ServerTLSConnection channel " - "for the same connection."); + "Can't handle more than one ServerTLSConnection or ServerAuthentication " + "channel for the same connection."); goto error; } @@ -144,11 +166,38 @@ handle_channels_cb (TpSimpleHandler *handler, channel = channels->data; if (tp_channel_get_channel_type_id (channel) != - EMP_IFACE_QUARK_CHANNEL_TYPE_SERVER_TLS_CONNECTION) + EMP_IFACE_QUARK_CHANNEL_TYPE_SERVER_TLS_CONNECTION + && tp_channel_get_channel_type_id (channel) != + TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_AUTHENTICATION) { g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "Can only handle ServerTLSConnection channels, this was a %s " - "channel", tp_channel_get_channel_type (channel)); + "Can only handle ServerTLSConnection or ServerAuthentication channels, " + "this was a %s channel", tp_channel_get_channel_type (channel)); + + goto error; + } + + if (tp_channel_get_channel_type_id (channel) == + TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_AUTHENTICATION + && priv->sasl_handler != NULL) + { + g_set_error_literal (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, + "Can't handle more than one ServerAuthentication channel at one time"); + + goto error; + } + + props = tp_channel_borrow_immutable_properties (channel); + available_mechanisms = tp_asv_get_boxed (props, + TP_PROP_CHANNEL_INTERFACE_SASL_AUTHENTICATION_AVAILABLE_MECHANISMS, + G_TYPE_STRV); + + if (tp_channel_get_channel_type_id (channel) == + TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_AUTHENTICATION + && !tp_strv_contains (available_mechanisms, "X-TELEPATHY-PASSWORD")) + { + g_set_error_literal (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, + "Only the X-TELEPATHY-PASSWORD SASL mechanism is supported"); goto error; } @@ -162,11 +211,27 @@ handle_channels_cb (TpSimpleHandler *handler, } /* create a handler */ - data = handler_context_data_new (self, context); - tp_handle_channels_context_delay (context); - empathy_server_tls_handler_new_async (channel, server_tls_handler_ready_cb, - data); + if (tp_channel_get_channel_type_id (channel) == + EMP_IFACE_QUARK_CHANNEL_TYPE_SERVER_TLS_CONNECTION) + { + data = handler_context_data_new (self, context); + tp_handle_channels_context_delay (context); + + empathy_server_tls_handler_new_async (channel, server_tls_handler_ready_cb, + data); + } + else if (tp_channel_get_channel_type_id (channel) == + TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_AUTHENTICATION) + { + priv->sasl_handler = empathy_server_sasl_handler_new (channel); + g_signal_connect (priv->sasl_handler, "invalidated", + G_CALLBACK (sasl_handler_invalidated_cb), self); + + tp_handle_channels_context_accept (context); + g_signal_emit (self, signals[NEW_SERVER_SASL_HANDLER], 0, + priv->sasl_handler); + } return; error: @@ -249,6 +314,7 @@ empathy_auth_factory_dispose (GObject *object) priv->dispose_run = TRUE; tp_clear_object (&priv->handler); + tp_clear_object (&priv->sasl_handler); G_OBJECT_CLASS (empathy_auth_factory_parent_class)->dispose (object); } -- cgit v1.2.3 From 1994d674ad7b35e8b4a5db7f431c31414d1230f3 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Wed, 1 Dec 2010 14:48:13 +0000 Subject: auth-client: listen for new sasl handlers and pop up a password dialog Signed-off-by: Jonny Lamb --- src/empathy-auth-client.c | 71 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/src/empathy-auth-client.c b/src/empathy-auth-client.c index 17b66a57d..864253bbf 100644 --- a/src/empathy-auth-client.c +++ b/src/empathy-auth-client.c @@ -29,6 +29,7 @@ #define DEBUG_FLAG EMPATHY_DEBUG_TLS #include #include +#include #include #include @@ -180,7 +181,7 @@ verifier_verify_cb (GObject *source, } static void -auth_factory_new_handler_cb (EmpathyAuthFactory *factory, +auth_factory_new_tls_handler_cb (EmpathyAuthFactory *factory, EmpathyServerTLSHandler *handler, gpointer user_data) { @@ -204,6 +205,69 @@ auth_factory_new_handler_cb (EmpathyAuthFactory *factory, g_free (hostname); } +typedef struct +{ + EmpathyServerSASLHandler *handler; + GtkWidget *entry; +} PasswordDialogData; + +static void +password_dialog_response_cb (GtkDialog *dialog, + gint response, + gpointer user_data) +{ + PasswordDialogData *data = user_data; + + if (response == GTK_RESPONSE_ACCEPT) + { + empathy_server_sasl_handler_provide_password (data->handler, + gtk_entry_get_text (GTK_ENTRY (data->entry))); + } + else + { + empathy_server_sasl_handler_cancel (data->handler); + } + + gtk_widget_destroy (GTK_WIDGET (dialog)); + + g_object_unref (data->handler); + g_slice_free (PasswordDialogData, data); +} + +static void +auth_factory_new_sasl_handler_cb (EmpathyAuthFactory *factory, + EmpathyServerSASLHandler *handler, + gpointer user_data) +{ + GtkWidget *dialog, *entry; + PasswordDialogData *data; + + DEBUG ("New SASL server handler received from the factory"); + + dialog = gtk_dialog_new_with_buttons (_("Enter password"), NULL, + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, + GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, + NULL); + + entry = gtk_entry_new (); + gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE); + + gtk_box_pack_start (GTK_BOX ( + gtk_dialog_get_content_area (GTK_DIALOG (dialog))), + entry, FALSE, FALSE, 10); + gtk_widget_show (entry); + + data = g_slice_new0 (PasswordDialogData); + data->handler = g_object_ref (handler); + data->entry = entry; + + g_signal_connect (dialog, "response", + G_CALLBACK (password_dialog_response_cb), data); + + gtk_widget_show (dialog); +} + int main (int argc, char **argv) @@ -238,7 +302,10 @@ main (int argc, factory = empathy_auth_factory_dup_singleton (); g_signal_connect (factory, "new-server-tls-handler", - G_CALLBACK (auth_factory_new_handler_cb), NULL); + G_CALLBACK (auth_factory_new_tls_handler_cb), NULL); + + g_signal_connect (factory, "new-server-sasl-handler", + G_CALLBACK (auth_factory_new_sasl_handler_cb), NULL); if (!empathy_auth_factory_register (factory, &error)) { -- cgit v1.2.3 From 2b5028d1ec652a136f30d7b3955562a6a07f9f42 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Fri, 3 Dec 2010 13:03:28 +0000 Subject: server-sasl-handler: add an account property Signed-off-by: Jonny Lamb --- libempathy/empathy-auth-factory.c | 3 ++- libempathy/empathy-server-sasl-handler.c | 34 ++++++++++++++++++++++++++++++-- libempathy/empathy-server-sasl-handler.h | 5 ++++- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/libempathy/empathy-auth-factory.c b/libempathy/empathy-auth-factory.c index 29af7dd44..58b24dc4f 100644 --- a/libempathy/empathy-auth-factory.c +++ b/libempathy/empathy-auth-factory.c @@ -223,7 +223,8 @@ handle_channels_cb (TpSimpleHandler *handler, else if (tp_channel_get_channel_type_id (channel) == TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_AUTHENTICATION) { - priv->sasl_handler = empathy_server_sasl_handler_new (channel); + priv->sasl_handler = empathy_server_sasl_handler_new ( + account, channel); g_signal_connect (priv->sasl_handler, "invalidated", G_CALLBACK (sasl_handler_invalidated_cb), self); diff --git a/libempathy/empathy-server-sasl-handler.c b/libempathy/empathy-server-sasl-handler.c index 5c1e9d203..5c78591ed 100644 --- a/libempathy/empathy-server-sasl-handler.c +++ b/libempathy/empathy-server-sasl-handler.c @@ -27,6 +27,7 @@ enum { PROP_CHANNEL = 1, + PROP_ACCOUNT, LAST_PROPERTY, }; @@ -40,6 +41,7 @@ static guint signals[LAST_SIGNAL] = {0}; typedef struct { TpChannel *channel; + TpAccount *account; GSimpleAsyncResult *result; } EmpathyServerSASLHandlerPriv; @@ -125,6 +127,9 @@ empathy_server_sasl_handler_get_property (GObject *object, case PROP_CHANNEL: g_value_set_object (value, priv->channel); break; + case PROP_ACCOUNT: + g_value_set_object (value, priv->account); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -144,6 +149,9 @@ empathy_server_sasl_handler_set_property (GObject *object, case PROP_CHANNEL: priv->channel = g_value_dup_object (value); break; + case PROP_ACCOUNT: + priv->account = g_value_dup_object (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -158,6 +166,7 @@ empathy_server_sasl_handler_dispose (GObject *object) DEBUG ("%p", object); tp_clear_object (&priv->channel); + tp_clear_object (&priv->account); G_OBJECT_CLASS (empathy_server_sasl_handler_parent_class)->dispose (object); } @@ -181,6 +190,12 @@ empathy_server_sasl_handler_class_init (EmpathyServerSASLHandlerClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_property (oclass, PROP_CHANNEL, pspec); + pspec = g_param_spec_object ("account", "The TpAccount", + "The TpAccount this channel belongs to.", + TP_TYPE_ACCOUNT, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (oclass, PROP_ACCOUNT, pspec); + signals[INVALIDATED] = g_signal_new ("invalidated", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, @@ -197,12 +212,15 @@ empathy_server_sasl_handler_init (EmpathyServerSASLHandler *self) } EmpathyServerSASLHandler * -empathy_server_sasl_handler_new (TpChannel *channel) +empathy_server_sasl_handler_new (TpAccount *account, + TpChannel *channel) { g_return_val_if_fail (TP_IS_CHANNEL (channel), NULL); return g_object_new (EMPATHY_TYPE_SERVER_SASL_HANDLER, - "channel", channel, NULL); + "account", account, + "channel", channel, + NULL); } static void @@ -262,3 +280,15 @@ empathy_server_sasl_handler_cancel (EmpathyServerSASLHandler *handler) "User cancelled the authentication", NULL, NULL, NULL, NULL); } + +TpAccount * +empathy_server_sasl_handler_get_account (EmpathyServerSASLHandler *handler) +{ + EmpathyServerSASLHandlerPriv *priv; + + g_return_val_if_fail (EMPATHY_IS_SERVER_SASL_HANDLER (handler), NULL); + + priv = GET_PRIV (handler); + + return priv->account; +} diff --git a/libempathy/empathy-server-sasl-handler.h b/libempathy/empathy-server-sasl-handler.h index 71f8d2a78..47f49e2a4 100644 --- a/libempathy/empathy-server-sasl-handler.h +++ b/libempathy/empathy-server-sasl-handler.h @@ -23,6 +23,7 @@ #include #include +#include #include G_BEGIN_DECLS @@ -58,13 +59,15 @@ GType empathy_server_sasl_handler_get_type (void); EmpathyServerSASLHandlerClass)) EmpathyServerSASLHandler * empathy_server_sasl_handler_new ( - TpChannel *channel); + TpAccount *account, TpChannel *channel); void empathy_server_sasl_handler_provide_password ( EmpathyServerSASLHandler *handler, const gchar *password); void empathy_server_sasl_handler_cancel (EmpathyServerSASLHandler *handler); +TpAccount * empathy_server_sasl_handler_get_account ( + EmpathyServerSASLHandler *handler); G_END_DECLS -- cgit v1.2.3 From fd337e4163b26ea7e284473817a1d17946ab12d4 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Fri, 3 Dec 2010 13:04:04 +0000 Subject: auth-client: improve the password request dialog Signed-off-by: Jonny Lamb --- libempathy/empathy-server-sasl-handler.c | 10 ++++- libempathy/empathy-server-sasl-handler.h | 3 +- src/empathy-auth-client.c | 74 +++++++++++++++++++++++++++----- 3 files changed, 74 insertions(+), 13 deletions(-) diff --git a/libempathy/empathy-server-sasl-handler.c b/libempathy/empathy-server-sasl-handler.c index 5c78591ed..9f10a7921 100644 --- a/libempathy/empathy-server-sasl-handler.c +++ b/libempathy/empathy-server-sasl-handler.c @@ -241,7 +241,8 @@ start_mechanism_with_data_cb (TpChannel *proxy, void empathy_server_sasl_handler_provide_password ( EmpathyServerSASLHandler *handler, - const gchar *password) + const gchar *password, + gboolean remember) { EmpathyServerSASLHandlerPriv *priv; GArray *array; @@ -262,6 +263,13 @@ empathy_server_sasl_handler_provide_password ( NULL, NULL, G_OBJECT (handler)); g_array_unref (array); + + DEBUG ("%sremembering the password", remember ? "" : "not "); + + if (remember) + { + /* TODO */ + } } void diff --git a/libempathy/empathy-server-sasl-handler.h b/libempathy/empathy-server-sasl-handler.h index 47f49e2a4..cdedef90c 100644 --- a/libempathy/empathy-server-sasl-handler.h +++ b/libempathy/empathy-server-sasl-handler.h @@ -62,7 +62,8 @@ EmpathyServerSASLHandler * empathy_server_sasl_handler_new ( TpAccount *account, TpChannel *channel); void empathy_server_sasl_handler_provide_password ( - EmpathyServerSASLHandler *handler, const gchar *password); + EmpathyServerSASLHandler *handler, const gchar *password, + gboolean remember); void empathy_server_sasl_handler_cancel (EmpathyServerSASLHandler *handler); diff --git a/src/empathy-auth-client.c b/src/empathy-auth-client.c index 864253bbf..6b03a03d1 100644 --- a/src/empathy-auth-client.c +++ b/src/empathy-auth-client.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -209,6 +210,7 @@ typedef struct { EmpathyServerSASLHandler *handler; GtkWidget *entry; + GtkWidget *ticky; } PasswordDialogData; static void @@ -218,10 +220,11 @@ password_dialog_response_cb (GtkDialog *dialog, { PasswordDialogData *data = user_data; - if (response == GTK_RESPONSE_ACCEPT) + if (response == GTK_RESPONSE_OK) { empathy_server_sasl_handler_provide_password (data->handler, - gtk_entry_get_text (GTK_ENTRY (data->entry))); + gtk_entry_get_text (GTK_ENTRY (data->entry)), + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->ticky))); } else { @@ -234,33 +237,82 @@ password_dialog_response_cb (GtkDialog *dialog, g_slice_free (PasswordDialogData, data); } +static void +clear_icon_released_cb (GtkEntry *entry, + GtkEntryIconPosition icon_pos, + GdkEvent *event, + gpointer user_data) +{ + gtk_entry_set_text (entry, ""); +} + +static void +password_entry_changed_cb (GtkEditable *entry, + gpointer user_data) +{ + const gchar *str; + + str = gtk_entry_get_text (GTK_ENTRY (entry)); + + gtk_entry_set_icon_sensitive (GTK_ENTRY (entry), + GTK_ENTRY_ICON_SECONDARY, !EMP_STR_EMPTY (str)); +} + static void auth_factory_new_sasl_handler_cb (EmpathyAuthFactory *factory, EmpathyServerSASLHandler *handler, gpointer user_data) { - GtkWidget *dialog, *entry; + GtkWidget *dialog, *entry, *icon, *ticky; + GtkBox *box; + TpAccount *account; PasswordDialogData *data; DEBUG ("New SASL server handler received from the factory"); - dialog = gtk_dialog_new_with_buttons (_("Enter password"), NULL, - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, - GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, - NULL); + account = empathy_server_sasl_handler_get_account (handler); + + dialog = gtk_message_dialog_new_with_markup (NULL, 0, + GTK_MESSAGE_OTHER, GTK_BUTTONS_OK_CANCEL, + _("Enter your password for account\n%s"), + tp_account_get_display_name (account)); + + box = GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))); + /* dialog icon */ + icon = gtk_image_new_from_icon_name (tp_account_get_icon_name (account), + GTK_ICON_SIZE_DIALOG); + gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), icon); + gtk_widget_show (icon); + + /* entry */ entry = gtk_entry_new (); gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE); - gtk_box_pack_start (GTK_BOX ( - gtk_dialog_get_content_area (GTK_DIALOG (dialog))), - entry, FALSE, FALSE, 10); + /* entry clear icon */ + gtk_entry_set_icon_from_stock (GTK_ENTRY (entry), + GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR); + gtk_entry_set_icon_sensitive (GTK_ENTRY (entry), + GTK_ENTRY_ICON_SECONDARY, FALSE); + + g_signal_connect (entry, "icon-release", + G_CALLBACK (clear_icon_released_cb), NULL); + g_signal_connect (entry, "changed", + G_CALLBACK (password_entry_changed_cb), NULL); + + gtk_box_pack_start (box, entry, FALSE, FALSE, 0); gtk_widget_show (entry); + /* remember password ticky */ + ticky = gtk_check_button_new_with_label (_("Remember password")); + + gtk_box_pack_start (box, ticky, FALSE, FALSE, 0); + gtk_widget_show (ticky); + data = g_slice_new0 (PasswordDialogData); data->handler = g_object_ref (handler); data->entry = entry; + data->ticky = ticky; g_signal_connect (dialog, "response", G_CALLBACK (password_dialog_response_cb), data); -- cgit v1.2.3 From ee8f480f660963c7d26872a27ba9889bbed6a000 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Fri, 3 Dec 2010 14:25:46 +0000 Subject: auth-client: grab the keyboard focus when popping up the password dialog I like this. Signed-off-by: Jonny Lamb --- src/empathy-auth-client.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/empathy-auth-client.c b/src/empathy-auth-client.c index 6b03a03d1..d4e1cd64a 100644 --- a/src/empathy-auth-client.c +++ b/src/empathy-auth-client.c @@ -258,6 +258,69 @@ password_entry_changed_cb (GtkEditable *entry, GTK_ENTRY_ICON_SECONDARY, !EMP_STR_EMPTY (str)); } +#define KEYBOARD_GRABBED \ + g_quark_from_static_string ("password-entry-keyboard-grabbed") + +static gboolean +password_dialog_grab_keyboard (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) +{ + if (g_object_get_qdata (G_OBJECT (widget), KEYBOARD_GRABBED) == NULL) + { + GdkGrabStatus status = gdk_keyboard_grab (gtk_widget_get_window (widget), + FALSE, gdk_event_get_time (event)); + + if (status != GDK_GRAB_SUCCESS) + { + DEBUG ("Could not grab keyboard; grab status was %u", status); + } + else + { + g_object_set_qdata (G_OBJECT (widget), KEYBOARD_GRABBED, + GINT_TO_POINTER (TRUE)); + } + } + + return FALSE; +} + +static gboolean +password_dialog_ungrab_keyboard (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) +{ + if (g_object_get_qdata (G_OBJECT (widget), KEYBOARD_GRABBED) != NULL) + { + gdk_keyboard_ungrab (gdk_event_get_time (event)); + g_object_set_qdata (G_OBJECT (widget), KEYBOARD_GRABBED, NULL); + } + + return FALSE; +} + +static gboolean +password_dialog_window_state_changed (GtkWidget *widget, + GdkEventWindowState *event, + gpointer data) +{ + GdkWindowState state = gdk_window_get_state (gtk_widget_get_window (widget)); + + if (state & GDK_WINDOW_STATE_WITHDRAWN + || state & GDK_WINDOW_STATE_ICONIFIED + || state & GDK_WINDOW_STATE_FULLSCREEN + || state & GDK_WINDOW_STATE_MAXIMIZED) + { + password_dialog_ungrab_keyboard (widget, (GdkEvent*) event, data); + } + else + { + password_dialog_grab_keyboard (widget, (GdkEvent*) event, data); + } + + return FALSE; +} + static void auth_factory_new_sasl_handler_cb (EmpathyAuthFactory *factory, EmpathyServerSASLHandler *handler, @@ -272,10 +335,13 @@ auth_factory_new_sasl_handler_cb (EmpathyAuthFactory *factory, account = empathy_server_sasl_handler_get_account (handler); + /* dialog */ dialog = gtk_message_dialog_new_with_markup (NULL, 0, GTK_MESSAGE_OTHER, GTK_BUTTONS_OK_CANCEL, _("Enter your password for account\n%s"), tp_account_get_display_name (account)); + gtk_window_set_icon_name (GTK_WINDOW (dialog), + GTK_STOCK_DIALOG_AUTHENTICATION); box = GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))); @@ -316,8 +382,15 @@ auth_factory_new_sasl_handler_cb (EmpathyAuthFactory *factory, g_signal_connect (dialog, "response", G_CALLBACK (password_dialog_response_cb), data); + g_signal_connect (dialog, "window-state-event", + G_CALLBACK (password_dialog_window_state_changed), NULL); + g_signal_connect (dialog, "map-event", + G_CALLBACK (password_dialog_grab_keyboard), NULL); + g_signal_connect (dialog, "unmap-event", + G_CALLBACK (password_dialog_ungrab_keyboard), NULL); gtk_widget_show (dialog); + gtk_widget_grab_focus (entry); } int -- cgit v1.2.3 From 5c2ae48c27de994ba418bf759bbf011c8101943d Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Fri, 3 Dec 2010 15:58:05 +0000 Subject: auth-client: move the password dialog into a new file Signed-off-by: Jonny Lamb --- libempathy-gtk/Makefile.am | 2 + libempathy-gtk/empathy-password-dialog.c | 318 +++++++++++++++++++++++++++++++ libempathy-gtk/empathy-password-dialog.h | 66 +++++++ src/empathy-auth-client.c | 180 +---------------- 4 files changed, 390 insertions(+), 176 deletions(-) create mode 100644 libempathy-gtk/empathy-password-dialog.c create mode 100644 libempathy-gtk/empathy-password-dialog.h diff --git a/libempathy-gtk/Makefile.am b/libempathy-gtk/Makefile.am index 7e35929b1..72e489c75 100644 --- a/libempathy-gtk/Makefile.am +++ b/libempathy-gtk/Makefile.am @@ -68,6 +68,7 @@ libempathy_gtk_handwritten_source = \ empathy-new-message-dialog.c \ empathy-new-call-dialog.c \ empathy-notify-manager.c \ + empathy-password-dialog.c \ empathy-persona-store.c \ empathy-persona-view.c \ empathy-presence-chooser.c \ @@ -130,6 +131,7 @@ libempathy_gtk_headers = \ empathy-new-message-dialog.h \ empathy-new-call-dialog.h \ empathy-notify-manager.h \ + empathy-password-dialog.h \ empathy-persona-store.h \ empathy-persona-view.h \ empathy-presence-chooser.h \ diff --git a/libempathy-gtk/empathy-password-dialog.c b/libempathy-gtk/empathy-password-dialog.c new file mode 100644 index 000000000..332c9df49 --- /dev/null +++ b/libempathy-gtk/empathy-password-dialog.c @@ -0,0 +1,318 @@ +/* + * empathy-password-dialog.c - Source for EmpathyPasswordDialog + * Copyright (C) 2010 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "empathy-password-dialog.h" + +#include + +#define DEBUG_FLAG EMPATHY_DEBUG_SASL +#include +#include + +G_DEFINE_TYPE (EmpathyPasswordDialog, empathy_password_dialog, + GTK_TYPE_MESSAGE_DIALOG) + +#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyPasswordDialog); + +enum { + PROP_HANDLER = 1, + + LAST_PROPERTY, +}; + +typedef struct { + EmpathyServerSASLHandler *handler; + + GtkWidget *entry; + GtkWidget *ticky; + + gboolean grabbing; + + gboolean dispose_run; +} EmpathyPasswordDialogPriv; + +static void +empathy_password_dialog_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + EmpathyPasswordDialogPriv *priv = GET_PRIV (object); + + switch (property_id) + { + case PROP_HANDLER: + g_value_set_object (value, priv->handler); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +empathy_password_dialog_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + EmpathyPasswordDialogPriv *priv = GET_PRIV (object); + + switch (property_id) + { + case PROP_HANDLER: + g_assert (priv->handler == NULL); /* construct only */ + priv->handler = g_value_dup_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +empathy_password_dialog_dispose (GObject *object) +{ + EmpathyPasswordDialogPriv *priv = GET_PRIV (object); + + if (priv->dispose_run) + return; + + priv->dispose_run = TRUE; + + tp_clear_object (&priv->handler); + + G_OBJECT_CLASS (empathy_password_dialog_parent_class)->dispose (object); +} + +static void +password_dialog_response_cb (GtkDialog *dialog, + gint response, + gpointer user_data) +{ + EmpathyPasswordDialogPriv *priv = GET_PRIV (user_data); + + if (response == GTK_RESPONSE_OK) + { + empathy_server_sasl_handler_provide_password (priv->handler, + gtk_entry_get_text (GTK_ENTRY (priv->entry)), + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->ticky))); + } + else + { + empathy_server_sasl_handler_cancel (priv->handler); + } + + gtk_widget_destroy (GTK_WIDGET (dialog)); +} + +static void +clear_icon_released_cb (GtkEntry *entry, + GtkEntryIconPosition icon_pos, + GdkEvent *event, + gpointer user_data) +{ + gtk_entry_set_text (entry, ""); +} + +static void +password_entry_changed_cb (GtkEditable *entry, + gpointer user_data) +{ + const gchar *str; + + str = gtk_entry_get_text (GTK_ENTRY (entry)); + + gtk_entry_set_icon_sensitive (GTK_ENTRY (entry), + GTK_ENTRY_ICON_SECONDARY, !EMP_STR_EMPTY (str)); +} + +static gboolean +password_dialog_grab_keyboard (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) +{ + EmpathyPasswordDialogPriv *priv = GET_PRIV (user_data); + + if (!priv->grabbing) + { + GdkGrabStatus status = gdk_keyboard_grab (gtk_widget_get_window (widget), + FALSE, gdk_event_get_time (event)); + + if (status != GDK_GRAB_SUCCESS) + DEBUG ("Could not grab keyboard; grab status was %u", status); + else + priv->grabbing = TRUE; + } + + return FALSE; +} + +static gboolean +password_dialog_ungrab_keyboard (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) +{ + EmpathyPasswordDialogPriv *priv = GET_PRIV (user_data); + + if (priv->grabbing) + { + gdk_keyboard_ungrab (gdk_event_get_time (event)); + priv->grabbing = FALSE; + } + + return FALSE; +} + +static gboolean +password_dialog_window_state_changed (GtkWidget *widget, + GdkEventWindowState *event, + gpointer data) +{ + GdkWindowState state = gdk_window_get_state (gtk_widget_get_window (widget)); + + if (state & GDK_WINDOW_STATE_WITHDRAWN + || state & GDK_WINDOW_STATE_ICONIFIED + || state & GDK_WINDOW_STATE_FULLSCREEN + || state & GDK_WINDOW_STATE_MAXIMIZED) + { + password_dialog_ungrab_keyboard (widget, (GdkEvent*) event, data); + } + else + { + password_dialog_grab_keyboard (widget, (GdkEvent*) event, data); + } + + return FALSE; +} + +static void +empathy_password_dialog_constructed (GObject *object) +{ + EmpathyPasswordDialog *dialog; + EmpathyPasswordDialogPriv *priv; + TpAccount *account; + GtkWidget *icon; + GtkBox *box; + gchar *text; + + dialog = EMPATHY_PASSWORD_DIALOG (object); + priv = GET_PRIV (dialog); + + g_assert (priv->handler != NULL); + + priv->grabbing = FALSE; + + account = empathy_server_sasl_handler_get_account (priv->handler); + + /* dialog */ + gtk_dialog_add_buttons (GTK_DIALOG (dialog), + GTK_STOCK_OK, GTK_RESPONSE_OK, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + NULL); + + text = g_strdup_printf (_("Enter your password for account\n%s"), + tp_account_get_display_name (account)); + gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), text); + g_free (text); + + gtk_window_set_icon_name (GTK_WINDOW (dialog), + GTK_STOCK_DIALOG_AUTHENTICATION); + + box = GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))); + + /* dialog icon */ + icon = gtk_image_new_from_icon_name (tp_account_get_icon_name (account), + GTK_ICON_SIZE_DIALOG); + gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), icon); + gtk_widget_show (icon); + + /* entry */ + priv->entry = gtk_entry_new (); + gtk_entry_set_visibility (GTK_ENTRY (priv->entry), FALSE); + + /* entry clear icon */ + gtk_entry_set_icon_from_stock (GTK_ENTRY (priv->entry), + GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR); + gtk_entry_set_icon_sensitive (GTK_ENTRY (priv->entry), + GTK_ENTRY_ICON_SECONDARY, FALSE); + + g_signal_connect (priv->entry, "icon-release", + G_CALLBACK (clear_icon_released_cb), NULL); + g_signal_connect (priv->entry, "changed", + G_CALLBACK (password_entry_changed_cb), NULL); + + gtk_box_pack_start (box, priv->entry, FALSE, FALSE, 0); + gtk_widget_show (priv->entry); + + /* remember password ticky box */ + priv->ticky = gtk_check_button_new_with_label (_("Remember password")); + + gtk_box_pack_start (box, priv->ticky, FALSE, FALSE, 0); + gtk_widget_show (priv->ticky); + + g_signal_connect (dialog, "response", + G_CALLBACK (password_dialog_response_cb), dialog); + g_signal_connect (dialog, "window-state-event", + G_CALLBACK (password_dialog_window_state_changed), dialog); + g_signal_connect (dialog, "map-event", + G_CALLBACK (password_dialog_grab_keyboard), dialog); + g_signal_connect (dialog, "unmap-event", + G_CALLBACK (password_dialog_ungrab_keyboard), dialog); + + gtk_widget_grab_focus (priv->entry); +} + +static void +empathy_password_dialog_init (EmpathyPasswordDialog *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + EMPATHY_TYPE_PASSWORD_DIALOG, EmpathyPasswordDialogPriv); +} + +static void +empathy_password_dialog_class_init (EmpathyPasswordDialogClass *klass) +{ + GParamSpec *pspec; + GObjectClass *oclass = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (EmpathyPasswordDialogPriv)); + + oclass->set_property = empathy_password_dialog_set_property; + oclass->get_property = empathy_password_dialog_get_property; + oclass->dispose = empathy_password_dialog_dispose; + oclass->constructed = empathy_password_dialog_constructed; + + pspec = g_param_spec_object ("handler", "The EmpathyServerSASLHandler", + "The EmpathyServerSASLHandler to be used.", + EMPATHY_TYPE_SERVER_SASL_HANDLER, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (oclass, PROP_HANDLER, pspec); +} + +GtkWidget * +empathy_password_dialog_new (EmpathyServerSASLHandler *handler) +{ + g_assert (EMPATHY_IS_SERVER_SASL_HANDLER (handler)); + + return g_object_new (EMPATHY_TYPE_PASSWORD_DIALOG, + "handler", handler, NULL); +} diff --git a/libempathy-gtk/empathy-password-dialog.h b/libempathy-gtk/empathy-password-dialog.h new file mode 100644 index 000000000..566322de1 --- /dev/null +++ b/libempathy-gtk/empathy-password-dialog.h @@ -0,0 +1,66 @@ +/* + * empathy-password-dialog.h - Header for EmpathyPasswordDialog + * Copyright (C) 2010 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __EMPATHY_PASSWORD_DIALOG_H__ +#define __EMPATHY_PASSWORD_DIALOG_H__ + +#include +#include + +#include + +#include + +G_BEGIN_DECLS + +typedef struct _EmpathyPasswordDialog EmpathyPasswordDialog; +typedef struct _EmpathyPasswordDialogClass EmpathyPasswordDialogClass; + +struct _EmpathyPasswordDialogClass { + GtkMessageDialogClass parent_class; +}; + +struct _EmpathyPasswordDialog { + GtkMessageDialog parent; + gpointer priv; +}; + +GType empathy_password_dialog_get_type (void); + +#define EMPATHY_TYPE_PASSWORD_DIALOG \ + (empathy_password_dialog_get_type ()) +#define EMPATHY_PASSWORD_DIALOG(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_PASSWORD_DIALOG, \ + EmpathyPasswordDialog)) +#define EMPATHY_PASSWORD_DIALOG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), EMPATHY_TYPE_PASSWORD_DIALOG, \ + EmpathyPasswordDialogClass)) +#define EMPATHY_IS_PASSWORD_DIALOG(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), EMPATHY_TYPE_PASSWORD_DIALOG)) +#define EMPATHY_IS_PASSWORD_DIALOG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), EMPATHY_TYPE_PASSWORD_DIALOG)) +#define EMPATHY_PASSWORD_DIALOG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_PASSWORD_DIALOG, \ + EmpathyPasswordDialogClass)) + +GtkWidget * empathy_password_dialog_new (EmpathyServerSASLHandler *handler); + +G_END_DECLS + +#endif /* #ifndef __EMPATHY_PASSWORD_DIALOG_H__*/ diff --git a/src/empathy-auth-client.c b/src/empathy-auth-client.c index d4e1cd64a..f6cc9def8 100644 --- a/src/empathy-auth-client.c +++ b/src/empathy-auth-client.c @@ -34,6 +34,7 @@ #include #include +#include #include #include @@ -206,191 +207,18 @@ auth_factory_new_tls_handler_cb (EmpathyAuthFactory *factory, g_free (hostname); } -typedef struct -{ - EmpathyServerSASLHandler *handler; - GtkWidget *entry; - GtkWidget *ticky; -} PasswordDialogData; - -static void -password_dialog_response_cb (GtkDialog *dialog, - gint response, - gpointer user_data) -{ - PasswordDialogData *data = user_data; - - if (response == GTK_RESPONSE_OK) - { - empathy_server_sasl_handler_provide_password (data->handler, - gtk_entry_get_text (GTK_ENTRY (data->entry)), - gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->ticky))); - } - else - { - empathy_server_sasl_handler_cancel (data->handler); - } - - gtk_widget_destroy (GTK_WIDGET (dialog)); - - g_object_unref (data->handler); - g_slice_free (PasswordDialogData, data); -} - -static void -clear_icon_released_cb (GtkEntry *entry, - GtkEntryIconPosition icon_pos, - GdkEvent *event, - gpointer user_data) -{ - gtk_entry_set_text (entry, ""); -} - -static void -password_entry_changed_cb (GtkEditable *entry, - gpointer user_data) -{ - const gchar *str; - - str = gtk_entry_get_text (GTK_ENTRY (entry)); - - gtk_entry_set_icon_sensitive (GTK_ENTRY (entry), - GTK_ENTRY_ICON_SECONDARY, !EMP_STR_EMPTY (str)); -} - -#define KEYBOARD_GRABBED \ - g_quark_from_static_string ("password-entry-keyboard-grabbed") - -static gboolean -password_dialog_grab_keyboard (GtkWidget *widget, - GdkEvent *event, - gpointer user_data) -{ - if (g_object_get_qdata (G_OBJECT (widget), KEYBOARD_GRABBED) == NULL) - { - GdkGrabStatus status = gdk_keyboard_grab (gtk_widget_get_window (widget), - FALSE, gdk_event_get_time (event)); - - if (status != GDK_GRAB_SUCCESS) - { - DEBUG ("Could not grab keyboard; grab status was %u", status); - } - else - { - g_object_set_qdata (G_OBJECT (widget), KEYBOARD_GRABBED, - GINT_TO_POINTER (TRUE)); - } - } - - return FALSE; -} - -static gboolean -password_dialog_ungrab_keyboard (GtkWidget *widget, - GdkEvent *event, - gpointer user_data) -{ - if (g_object_get_qdata (G_OBJECT (widget), KEYBOARD_GRABBED) != NULL) - { - gdk_keyboard_ungrab (gdk_event_get_time (event)); - g_object_set_qdata (G_OBJECT (widget), KEYBOARD_GRABBED, NULL); - } - - return FALSE; -} - -static gboolean -password_dialog_window_state_changed (GtkWidget *widget, - GdkEventWindowState *event, - gpointer data) -{ - GdkWindowState state = gdk_window_get_state (gtk_widget_get_window (widget)); - - if (state & GDK_WINDOW_STATE_WITHDRAWN - || state & GDK_WINDOW_STATE_ICONIFIED - || state & GDK_WINDOW_STATE_FULLSCREEN - || state & GDK_WINDOW_STATE_MAXIMIZED) - { - password_dialog_ungrab_keyboard (widget, (GdkEvent*) event, data); - } - else - { - password_dialog_grab_keyboard (widget, (GdkEvent*) event, data); - } - - return FALSE; -} - static void auth_factory_new_sasl_handler_cb (EmpathyAuthFactory *factory, EmpathyServerSASLHandler *handler, gpointer user_data) { - GtkWidget *dialog, *entry, *icon, *ticky; - GtkBox *box; - TpAccount *account; - PasswordDialogData *data; + GtkWidget *dialog; DEBUG ("New SASL server handler received from the factory"); - account = empathy_server_sasl_handler_get_account (handler); - - /* dialog */ - dialog = gtk_message_dialog_new_with_markup (NULL, 0, - GTK_MESSAGE_OTHER, GTK_BUTTONS_OK_CANCEL, - _("Enter your password for account\n%s"), - tp_account_get_display_name (account)); - gtk_window_set_icon_name (GTK_WINDOW (dialog), - GTK_STOCK_DIALOG_AUTHENTICATION); - - box = GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))); - - /* dialog icon */ - icon = gtk_image_new_from_icon_name (tp_account_get_icon_name (account), - GTK_ICON_SIZE_DIALOG); - gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), icon); - gtk_widget_show (icon); - - /* entry */ - entry = gtk_entry_new (); - gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE); - - /* entry clear icon */ - gtk_entry_set_icon_from_stock (GTK_ENTRY (entry), - GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR); - gtk_entry_set_icon_sensitive (GTK_ENTRY (entry), - GTK_ENTRY_ICON_SECONDARY, FALSE); - - g_signal_connect (entry, "icon-release", - G_CALLBACK (clear_icon_released_cb), NULL); - g_signal_connect (entry, "changed", - G_CALLBACK (password_entry_changed_cb), NULL); - - gtk_box_pack_start (box, entry, FALSE, FALSE, 0); - gtk_widget_show (entry); - - /* remember password ticky */ - ticky = gtk_check_button_new_with_label (_("Remember password")); - - gtk_box_pack_start (box, ticky, FALSE, FALSE, 0); - gtk_widget_show (ticky); - - data = g_slice_new0 (PasswordDialogData); - data->handler = g_object_ref (handler); - data->entry = entry; - data->ticky = ticky; - - g_signal_connect (dialog, "response", - G_CALLBACK (password_dialog_response_cb), data); - g_signal_connect (dialog, "window-state-event", - G_CALLBACK (password_dialog_window_state_changed), NULL); - g_signal_connect (dialog, "map-event", - G_CALLBACK (password_dialog_grab_keyboard), NULL); - g_signal_connect (dialog, "unmap-event", - G_CALLBACK (password_dialog_ungrab_keyboard), NULL); - + /* TODO: check whether to show the dialog */ + dialog = empathy_password_dialog_new (handler); gtk_widget_show (dialog); - gtk_widget_grab_focus (entry); } int -- cgit v1.2.3 From 4d487def1692d57aca987219fa1ff6f133c389f1 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Mon, 6 Dec 2010 09:42:59 +0000 Subject: keyring: add simple keyring helper Signed-off-by: Jonny Lamb --- libempathy/Makefile.am | 2 + libempathy/empathy-keyring.c | 115 +++++++++++++++++++++++++++++++++++++++++++ libempathy/empathy-keyring.h | 37 ++++++++++++++ 3 files changed, 154 insertions(+) create mode 100644 libempathy/empathy-keyring.c create mode 100644 libempathy/empathy-keyring.h diff --git a/libempathy/Makefile.am b/libempathy/Makefile.am index 5122e073d..ae9e2b5e9 100644 --- a/libempathy/Makefile.am +++ b/libempathy/Makefile.am @@ -47,6 +47,7 @@ libempathy_headers = \ empathy-irc-network-manager.h \ empathy-irc-network.h \ empathy-irc-server.h \ + empathy-keyring.h \ empathy-location.h \ empathy-message.h \ empathy-server-sasl-handler.h \ @@ -87,6 +88,7 @@ libempathy_la_SOURCES = \ empathy-irc-network-manager.c \ empathy-irc-network.c \ empathy-irc-server.c \ + empathy-keyring.c \ empathy-message.c \ empathy-server-sasl-handler.c \ empathy-server-tls-handler.c \ diff --git a/libempathy/empathy-keyring.c b/libempathy/empathy-keyring.c new file mode 100644 index 000000000..7f49acc6d --- /dev/null +++ b/libempathy/empathy-keyring.c @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2010 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "empathy-keyring.h" + +#include + +#include + +#define DEBUG_FLAG EMPATHY_DEBUG_OTHER +#include "empathy-debug.h" + +/* +GnomeKeyringPasswordSchema keyring_schema = + { GNOME_KEYRING_ITEM_GENERIC_SECRET, + { { "account", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, + { "param", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, + { NULL } } }; +*/ + +static void +find_items_cb (GnomeKeyringResult result, + GList *list, + gpointer user_data) +{ + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data); + + if (result != GNOME_KEYRING_RESULT_OK) + { + GError error = { TP_ERROR, TP_ERROR_DOES_NOT_EXIST, + (gchar *) gnome_keyring_result_to_message (result) }; + g_simple_async_result_set_from_error (simple, &error); + } + + if (g_list_length (list) == 1) + { + GnomeKeyringFound *found = list->data; + + DEBUG ("Got secret"); + + g_simple_async_result_set_op_res_gpointer (simple, found->secret, NULL); + } + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +void +empathy_keyring_get_password_async (TpAccount *account, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + GnomeKeyringAttributeList *match; + const gchar *account_id; + + g_return_if_fail (TP_IS_ACCOUNT (account)); + g_return_if_fail (callback != NULL); + + simple = g_simple_async_result_new (G_OBJECT (account), callback, + user_data, empathy_keyring_get_password_async); + + account_id = tp_proxy_get_object_path (account) + + strlen (TP_ACCOUNT_OBJECT_PATH_BASE); + + DEBUG ("Trying to get password for: %s", account_id); + + match = gnome_keyring_attribute_list_new (); + gnome_keyring_attribute_list_append_string (match, "account", + account_id); + gnome_keyring_attribute_list_append_string (match, "param", "password"); + + gnome_keyring_find_items (GNOME_KEYRING_ITEM_GENERIC_SECRET, + match, find_items_cb, simple, NULL); + + gnome_keyring_attribute_list_free (match); +} + +const gchar * +empathy_keyring_get_password_finish (TpAccount *account, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (TP_IS_ACCOUNT (account), NULL); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL); + + simple = G_SIMPLE_ASYNC_RESULT (result); + + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, + G_OBJECT (account), empathy_keyring_get_password_async), NULL); + + return g_simple_async_result_get_op_res_gpointer (simple); +} diff --git a/libempathy/empathy-keyring.h b/libempathy/empathy-keyring.h new file mode 100644 index 000000000..2c062e1cd --- /dev/null +++ b/libempathy/empathy-keyring.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2010 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __EMPATHY_KEYRING_H__ +#define __EMPATHY_KEYRING_H__ + +#include + +#include + +G_BEGIN_DECLS + +void empathy_keyring_get_password_async (TpAccount *account, + GAsyncReadyCallback callback, gpointer user_data); + +const gchar * empathy_keyring_get_password_finish (TpAccount *account, + GAsyncResult *result, GError **error); + +G_END_DECLS + +#endif /* __EMPATHY_KEYRING_H__ */ + -- cgit v1.2.3 From bc099434f22a78d09d0dad3d5006ad836ab11d02 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Mon, 6 Dec 2010 09:43:34 +0000 Subject: server-sasl-handler: make a GAsyncInitable and get the password Signed-off-by: Jonny Lamb --- libempathy/empathy-auth-factory.c | 51 ++++++++--- libempathy/empathy-server-sasl-handler.c | 145 +++++++++++++++++++++++++++++-- libempathy/empathy-server-sasl-handler.h | 11 ++- src/empathy-auth-client.c | 9 +- 4 files changed, 193 insertions(+), 23 deletions(-) diff --git a/libempathy/empathy-auth-factory.c b/libempathy/empathy-auth-factory.c index 58b24dc4f..578b6d6cd 100644 --- a/libempathy/empathy-auth-factory.c +++ b/libempathy/empathy-auth-factory.c @@ -129,6 +129,40 @@ sasl_handler_invalidated_cb (EmpathyServerSASLHandler *handler, tp_clear_object (&priv->sasl_handler); } +static void +server_sasl_handler_ready_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + EmpathyAuthFactoryPriv *priv; + GError *error = NULL; + HandlerContextData *data = user_data; + + priv = GET_PRIV (data->self); + priv->sasl_handler = empathy_server_sasl_handler_new_finish (res, &error); + + if (error != NULL) + { + DEBUG ("Failed to create a server SASL handler; error %s", + error->message); + tp_handle_channels_context_fail (data->context, error); + + g_error_free (error); + } + else + { + tp_handle_channels_context_accept (data->context); + + g_signal_connect (priv->sasl_handler, "invalidated", + G_CALLBACK (sasl_handler_invalidated_cb), data->self); + + g_signal_emit (data->self, signals[NEW_SERVER_SASL_HANDLER], 0, + priv->sasl_handler); + } + + handler_context_data_free (data); +} + static void handle_channels_cb (TpSimpleHandler *handler, TpAccount *account, @@ -210,28 +244,21 @@ handle_channels_cb (TpSimpleHandler *handler, goto error; } + data = handler_context_data_new (self, context); + tp_handle_channels_context_delay (context); + /* create a handler */ if (tp_channel_get_channel_type_id (channel) == EMP_IFACE_QUARK_CHANNEL_TYPE_SERVER_TLS_CONNECTION) { - data = handler_context_data_new (self, context); - tp_handle_channels_context_delay (context); - empathy_server_tls_handler_new_async (channel, server_tls_handler_ready_cb, data); } else if (tp_channel_get_channel_type_id (channel) == TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_AUTHENTICATION) { - priv->sasl_handler = empathy_server_sasl_handler_new ( - account, channel); - - g_signal_connect (priv->sasl_handler, "invalidated", - G_CALLBACK (sasl_handler_invalidated_cb), self); - - tp_handle_channels_context_accept (context); - g_signal_emit (self, signals[NEW_SERVER_SASL_HANDLER], 0, - priv->sasl_handler); + empathy_server_sasl_handler_new_async (account, channel, + server_sasl_handler_ready_cb, data); } return; diff --git a/libempathy/empathy-server-sasl-handler.c b/libempathy/empathy-server-sasl-handler.c index 9f10a7921..b71cbdb7b 100644 --- a/libempathy/empathy-server-sasl-handler.c +++ b/libempathy/empathy-server-sasl-handler.c @@ -24,6 +24,7 @@ #define DEBUG_FLAG EMPATHY_DEBUG_SASL #include "empathy-debug.h" #include "empathy-utils.h" +#include "empathy-keyring.h" enum { PROP_CHANNEL = 1, @@ -44,10 +45,17 @@ typedef struct { TpAccount *account; GSimpleAsyncResult *result; + + gchar *password; + + GSimpleAsyncResult *async_init_res; } EmpathyServerSASLHandlerPriv; -G_DEFINE_TYPE (EmpathyServerSASLHandler, empathy_server_sasl_handler, - G_TYPE_OBJECT); +static void async_initable_iface_init (GAsyncInitableIface *iface); + +G_DEFINE_TYPE_WITH_CODE (EmpathyServerSASLHandler, empathy_server_sasl_handler, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init)); #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyServerSASLHandler); @@ -83,6 +91,83 @@ sasl_status_changed_cb (TpChannel *channel, } } +static gboolean +empathy_server_sasl_handler_give_password (gpointer data) +{ + EmpathyServerSASLHandler *self = data; + EmpathyServerSASLHandlerPriv *priv = GET_PRIV (self); + + empathy_server_sasl_handler_provide_password (self, + priv->password, FALSE); + + return FALSE; +} + +static void +empathy_server_sasl_handler_get_password_async_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + EmpathyServerSASLHandlerPriv *priv; + const gchar *password; + GError *error = NULL; + + priv = GET_PRIV (user_data); + + password = empathy_keyring_get_password_finish (TP_ACCOUNT (source), + result, &error); + + if (password != NULL) + { + priv->password = g_strdup (password); + + /* Do this in an idle so the async result will get there + * first. */ + g_idle_add (empathy_server_sasl_handler_give_password, user_data); + } + + g_simple_async_result_complete (priv->async_init_res); + tp_clear_object (&priv->async_init_res); +} + +static void +empathy_server_sasl_handler_init_async (GAsyncInitable *initable, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + EmpathyServerSASLHandler *self = EMPATHY_SERVER_SASL_HANDLER (initable); + EmpathyServerSASLHandlerPriv *priv = GET_PRIV (self); + + g_assert (priv->account != NULL); + + priv->async_init_res = g_simple_async_result_new (G_OBJECT (self), + callback, user_data, empathy_server_sasl_handler_new_async); + + empathy_keyring_get_password_async (priv->account, + empathy_server_sasl_handler_get_password_async_cb, self); +} + +static gboolean +empathy_server_sasl_handler_init_finish (GAsyncInitable *initable, + GAsyncResult *res, + GError **error) +{ + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), + error)) + return FALSE; + + return TRUE; +} + +static void +async_initable_iface_init (GAsyncInitableIface *iface) +{ + iface->init_async = empathy_server_sasl_handler_init_async; + iface->init_finish = empathy_server_sasl_handler_init_finish; +} + static void channel_invalidated_cb (TpProxy *proxy, guint domain, @@ -171,6 +256,18 @@ empathy_server_sasl_handler_dispose (GObject *object) G_OBJECT_CLASS (empathy_server_sasl_handler_parent_class)->dispose (object); } +static void +empathy_server_sasl_handler_finalize (GObject *object) +{ + EmpathyServerSASLHandlerPriv *priv = GET_PRIV (object); + + DEBUG ("%p", object); + + tp_clear_pointer (&priv->password, g_free); + + G_OBJECT_CLASS (empathy_server_sasl_handler_parent_class)->finalize (object); +} + static void empathy_server_sasl_handler_class_init (EmpathyServerSASLHandlerClass *klass) { @@ -181,6 +278,7 @@ empathy_server_sasl_handler_class_init (EmpathyServerSASLHandlerClass *klass) oclass->get_property = empathy_server_sasl_handler_get_property; oclass->set_property = empathy_server_sasl_handler_set_property; oclass->dispose = empathy_server_sasl_handler_dispose; + oclass->dispose = empathy_server_sasl_handler_finalize; g_type_class_add_private (klass, sizeof (EmpathyServerSASLHandlerPriv)); @@ -212,12 +310,35 @@ empathy_server_sasl_handler_init (EmpathyServerSASLHandler *self) } EmpathyServerSASLHandler * -empathy_server_sasl_handler_new (TpAccount *account, - TpChannel *channel) +empathy_server_sasl_handler_new_finish (GAsyncResult *result, + GError **error) { - g_return_val_if_fail (TP_IS_CHANNEL (channel), NULL); + GObject *object, *source_object; - return g_object_new (EMPATHY_TYPE_SERVER_SASL_HANDLER, + source_object = g_async_result_get_source_object (result); + + object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), + result, error); + g_object_unref (source_object); + + if (object != NULL) + return EMPATHY_SERVER_SASL_HANDLER (object); + else + return NULL; +} + +void +empathy_server_sasl_handler_new_async (TpAccount *account, + TpChannel *channel, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (TP_IS_ACCOUNT (account)); + g_return_if_fail (TP_IS_CHANNEL (channel)); + g_return_if_fail (callback != NULL); + + g_async_initable_new_async (EMPATHY_TYPE_SERVER_SASL_HANDLER, + G_PRIORITY_DEFAULT, NULL, callback, user_data, "account", account, "channel", channel, NULL); @@ -300,3 +421,15 @@ empathy_server_sasl_handler_get_account (EmpathyServerSASLHandler *handler) return priv->account; } + +gboolean +empathy_server_sasl_handler_has_password (EmpathyServerSASLHandler *handler) +{ + EmpathyServerSASLHandlerPriv *priv; + + g_return_val_if_fail (EMPATHY_IS_SERVER_SASL_HANDLER (handler), FALSE); + + priv = GET_PRIV (handler); + + return (priv->password != NULL); +} diff --git a/libempathy/empathy-server-sasl-handler.h b/libempathy/empathy-server-sasl-handler.h index cdedef90c..1eedc5b27 100644 --- a/libempathy/empathy-server-sasl-handler.h +++ b/libempathy/empathy-server-sasl-handler.h @@ -58,8 +58,12 @@ GType empathy_server_sasl_handler_get_type (void); (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_SERVER_SASL_HANDLER, \ EmpathyServerSASLHandlerClass)) -EmpathyServerSASLHandler * empathy_server_sasl_handler_new ( - TpAccount *account, TpChannel *channel); +void empathy_server_sasl_handler_new_async ( + TpAccount *account, TpChannel *channel, + GAsyncReadyCallback callback, gpointer user_data); + +EmpathyServerSASLHandler * empathy_server_sasl_handler_new_finish ( + GAsyncResult *result, GError **error); void empathy_server_sasl_handler_provide_password ( EmpathyServerSASLHandler *handler, const gchar *password, @@ -70,6 +74,9 @@ void empathy_server_sasl_handler_cancel (EmpathyServerSASLHandler *handler); TpAccount * empathy_server_sasl_handler_get_account ( EmpathyServerSASLHandler *handler); +gboolean empathy_server_sasl_handler_has_password ( + EmpathyServerSASLHandler *handler); + G_END_DECLS #endif /* #ifndef __EMPATHY_SERVER_SASL_HANDLER_H__*/ diff --git a/src/empathy-auth-client.c b/src/empathy-auth-client.c index f6cc9def8..98a736fb9 100644 --- a/src/empathy-auth-client.c +++ b/src/empathy-auth-client.c @@ -216,9 +216,12 @@ auth_factory_new_sasl_handler_cb (EmpathyAuthFactory *factory, DEBUG ("New SASL server handler received from the factory"); - /* TODO: check whether to show the dialog */ - dialog = empathy_password_dialog_new (handler); - gtk_widget_show (dialog); + /* If the handler has the password it will deal with it itself. */ + if (!empathy_server_sasl_handler_has_password (handler)) + { + dialog = empathy_password_dialog_new (handler); + gtk_widget_show (dialog); + } } int -- cgit v1.2.3 From 085edd72db61d923a639d874f44c9ed2805e75a8 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Mon, 6 Dec 2010 10:05:56 +0000 Subject: keyring: add set_password_{async,finish} functions Signed-off-by: Jonny Lamb --- libempathy/empathy-keyring.c | 86 ++++++++++++++++++++++++++++++++++++++++---- libempathy/empathy-keyring.h | 7 ++++ 2 files changed, 87 insertions(+), 6 deletions(-) diff --git a/libempathy/empathy-keyring.c b/libempathy/empathy-keyring.c index 7f49acc6d..b27df710f 100644 --- a/libempathy/empathy-keyring.c +++ b/libempathy/empathy-keyring.c @@ -27,13 +27,11 @@ #define DEBUG_FLAG EMPATHY_DEBUG_OTHER #include "empathy-debug.h" -/* -GnomeKeyringPasswordSchema keyring_schema = +static GnomeKeyringPasswordSchema keyring_schema = { GNOME_KEYRING_ITEM_GENERIC_SECRET, { { "account", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, { "param", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, { NULL } } }; -*/ static void find_items_cb (GnomeKeyringResult result, @@ -44,9 +42,11 @@ find_items_cb (GnomeKeyringResult result, if (result != GNOME_KEYRING_RESULT_OK) { - GError error = { TP_ERROR, TP_ERROR_DOES_NOT_EXIST, - (gchar *) gnome_keyring_result_to_message (result) }; - g_simple_async_result_set_from_error (simple, &error); + GError *error = g_error_new_literal (TP_ERROR, + TP_ERROR_DOES_NOT_EXIST, + gnome_keyring_result_to_message (result)); + g_simple_async_result_set_from_error (simple, error); + g_clear_error (&error); } if (g_list_length (list) == 1) @@ -113,3 +113,77 @@ empathy_keyring_get_password_finish (TpAccount *account, return g_simple_async_result_get_op_res_gpointer (simple); } + +static void +store_password_cb (GnomeKeyringResult result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data); + + if (result != GNOME_KEYRING_RESULT_OK) + { + GError *error = g_error_new_literal (TP_ERROR, + TP_ERROR_DOES_NOT_EXIST, + gnome_keyring_result_to_message (result)); + g_simple_async_result_set_from_error (simple, error); + g_clear_error (&error); + } + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +void +empathy_keyring_set_password_async (TpAccount *account, + const gchar *password, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + const gchar *account_id; + gchar *name; + + g_return_if_fail (TP_IS_ACCOUNT (account)); + g_return_if_fail (password != NULL); + g_return_if_fail (callback != NULL); + + simple = g_simple_async_result_new (G_OBJECT (account), callback, + user_data, empathy_keyring_set_password_async); + + account_id = tp_proxy_get_object_path (account) + + strlen (TP_ACCOUNT_OBJECT_PATH_BASE); + + DEBUG ("Remembering password for %s", account_id); + + name = g_strdup_printf ("account: %s; param: param-password", account_id); + + gnome_keyring_store_password (&keyring_schema, NULL, name, password, + store_password_cb, simple, NULL, + "account", account_id, + "param", "password", + NULL); + + g_free (name); +} + +gboolean +empathy_keyring_set_password_finish (TpAccount *account, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (TP_IS_ACCOUNT (account), FALSE); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, + G_OBJECT (account), empathy_keyring_set_password_async), FALSE); + + return TRUE; +} + diff --git a/libempathy/empathy-keyring.h b/libempathy/empathy-keyring.h index 2c062e1cd..015b7ae86 100644 --- a/libempathy/empathy-keyring.h +++ b/libempathy/empathy-keyring.h @@ -31,6 +31,13 @@ void empathy_keyring_get_password_async (TpAccount *account, const gchar * empathy_keyring_get_password_finish (TpAccount *account, GAsyncResult *result, GError **error); +void empathy_keyring_set_password_async (TpAccount *account, + const gchar *password, GAsyncReadyCallback callback, + gpointer user_data); + +gboolean empathy_keyring_set_password_finish (TpAccount *account, + GAsyncResult *result, GError **error); + G_END_DECLS #endif /* __EMPATHY_KEYRING_H__ */ -- cgit v1.2.3 From b66750b8540761c03b935ff93d50c642c9d1f07c Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Mon, 6 Dec 2010 10:06:51 +0000 Subject: server-sasl-handler: save the password if requested Signed-off-by: Jonny Lamb --- libempathy/empathy-server-sasl-handler.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/libempathy/empathy-server-sasl-handler.c b/libempathy/empathy-server-sasl-handler.c index b71cbdb7b..d9f504942 100644 --- a/libempathy/empathy-server-sasl-handler.c +++ b/libempathy/empathy-server-sasl-handler.c @@ -359,6 +359,25 @@ start_mechanism_with_data_cb (TpChannel *proxy, DEBUG ("Started mechanism successfully"); } +static void +empathy_server_sasl_handler_set_password_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + + if (!empathy_keyring_set_password_finish (TP_ACCOUNT (source), result, + &error)) + { + DEBUG ("Failed to set password: %s", error->message); + g_clear_error (&error); + } + else + { + DEBUG ("Password set successfully."); + } +} + void empathy_server_sasl_handler_provide_password ( EmpathyServerSASLHandler *handler, @@ -389,7 +408,8 @@ empathy_server_sasl_handler_provide_password ( if (remember) { - /* TODO */ + empathy_keyring_set_password_async (priv->account, password, + empathy_server_sasl_handler_set_password_cb, NULL); } } -- cgit v1.2.3 From 2c201cf276aa11b3ae1d1bedcf92eb29abf7f04d Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Mon, 6 Dec 2010 11:35:26 +0000 Subject: keyring: add a delete_password function Signed-off-by: Jonny Lamb --- libempathy/empathy-keyring.c | 96 ++++++++++++++++++++++++++++++++++++++++++++ libempathy/empathy-keyring.h | 6 +++ 2 files changed, 102 insertions(+) diff --git a/libempathy/empathy-keyring.c b/libempathy/empathy-keyring.c index b27df710f..55ddd1f69 100644 --- a/libempathy/empathy-keyring.c +++ b/libempathy/empathy-keyring.c @@ -187,3 +187,99 @@ empathy_keyring_set_password_finish (TpAccount *account, return TRUE; } +static void +item_delete_cb (GnomeKeyringResult result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data); + + if (result != GNOME_KEYRING_RESULT_OK) + { + GError *error = g_error_new_literal (TP_ERROR, + TP_ERROR_DOES_NOT_EXIST, + gnome_keyring_result_to_message (result)); + g_simple_async_result_set_from_error (simple, error); + g_clear_error (&error); + } + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +static void +find_item_to_delete_cb (GnomeKeyringResult result, + GList *list, + gpointer user_data) +{ + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data); + GnomeKeyringFound *found; + + if (result != GNOME_KEYRING_RESULT_OK || g_list_length (list) != 1) + { + GError *error = g_error_new_literal (TP_ERROR, + TP_ERROR_DOES_NOT_EXIST, + gnome_keyring_result_to_message (result)); + g_simple_async_result_set_from_error (simple, error); + g_clear_error (&error); + + g_simple_async_result_complete (simple); + g_object_unref (simple); + return; + } + + found = list->data; + + gnome_keyring_item_delete (NULL, found->item_id, item_delete_cb, + simple, NULL); +} + +void +empathy_keyring_delete_password_async (TpAccount *account, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + GnomeKeyringAttributeList *match; + const gchar *account_id; + + g_return_if_fail (TP_IS_ACCOUNT (account)); + g_return_if_fail (callback != NULL); + + simple = g_simple_async_result_new (G_OBJECT (account), callback, + user_data, empathy_keyring_delete_password_async); + + account_id = tp_proxy_get_object_path (account) + + strlen (TP_ACCOUNT_OBJECT_PATH_BASE); + + match = gnome_keyring_attribute_list_new (); + gnome_keyring_attribute_list_append_string (match, "account", + account_id); + gnome_keyring_attribute_list_append_string (match, "param", "password"); + + gnome_keyring_find_items (GNOME_KEYRING_ITEM_GENERIC_SECRET, + match, find_item_to_delete_cb, simple, NULL); + + gnome_keyring_attribute_list_free (match); +} + +gboolean +empathy_keyring_delete_password_finish (TpAccount *account, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (TP_IS_ACCOUNT (account), FALSE); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, + G_OBJECT (account), empathy_keyring_delete_password_async), FALSE); + + return TRUE; +} + diff --git a/libempathy/empathy-keyring.h b/libempathy/empathy-keyring.h index 015b7ae86..000f987f7 100644 --- a/libempathy/empathy-keyring.h +++ b/libempathy/empathy-keyring.h @@ -38,6 +38,12 @@ void empathy_keyring_set_password_async (TpAccount *account, gboolean empathy_keyring_set_password_finish (TpAccount *account, GAsyncResult *result, GError **error); +void empathy_keyring_delete_password_async (TpAccount *account, + GAsyncReadyCallback callback, gpointer user_data); + +gboolean empathy_keyring_delete_password_finish (TpAccount *account, + GAsyncResult *result, GError **error); + G_END_DECLS #endif /* __EMPATHY_KEYRING_H__ */ -- cgit v1.2.3 From 66f79bec1ec6b59d362324fbfdf0335e60c1d8e6 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Mon, 6 Dec 2010 12:28:13 +0000 Subject: keyring: allow set and delete password to have NULL callbacks Signed-off-by: Jonny Lamb --- libempathy/empathy-keyring.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/libempathy/empathy-keyring.c b/libempathy/empathy-keyring.c index 55ddd1f69..f3d523e54 100644 --- a/libempathy/empathy-keyring.c +++ b/libempathy/empathy-keyring.c @@ -145,7 +145,6 @@ empathy_keyring_set_password_async (TpAccount *account, g_return_if_fail (TP_IS_ACCOUNT (account)); g_return_if_fail (password != NULL); - g_return_if_fail (callback != NULL); simple = g_simple_async_result_new (G_OBJECT (account), callback, user_data, empathy_keyring_set_password_async); @@ -243,7 +242,6 @@ empathy_keyring_delete_password_async (TpAccount *account, const gchar *account_id; g_return_if_fail (TP_IS_ACCOUNT (account)); - g_return_if_fail (callback != NULL); simple = g_simple_async_result_new (G_OBJECT (account), callback, user_data, empathy_keyring_delete_password_async); -- cgit v1.2.3 From 07921157f6d77826e474eac64a425736a92e2321 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Mon, 6 Dec 2010 14:49:16 +0000 Subject: server-sasl-handler: handle invalid SASL statuses Signed-off-by: Jonny Lamb --- libempathy/empathy-server-sasl-handler.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libempathy/empathy-server-sasl-handler.c b/libempathy/empathy-server-sasl-handler.c index d9f504942..4b5a44193 100644 --- a/libempathy/empathy-server-sasl-handler.c +++ b/libempathy/empathy-server-sasl-handler.c @@ -79,6 +79,13 @@ sasl_status_changed_cb (TpChannel *channel, { EmpathyServerSASLHandlerPriv *priv = GET_PRIV (weak_object); + /* buh boh */ + if (status >= G_N_ELEMENTS (sasl_statuses)) + { + DEBUG ("SASL status changed to unknown status"); + return; + } + DEBUG ("SASL status changed to '%s'", sasl_statuses[status]); if (status == TP_SASL_STATUS_SERVER_SUCCEEDED) -- cgit v1.2.3 From 15426cd6aa437bc2772397b77dd0d59a345e004b Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Mon, 6 Dec 2010 15:01:25 +0000 Subject: password-dialog: don't display "Remember password" for now Signed-off-by: Jonny Lamb --- libempathy-gtk/empathy-password-dialog.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libempathy-gtk/empathy-password-dialog.c b/libempathy-gtk/empathy-password-dialog.c index 332c9df49..c5a891357 100644 --- a/libempathy-gtk/empathy-password-dialog.c +++ b/libempathy-gtk/empathy-password-dialog.c @@ -266,8 +266,15 @@ empathy_password_dialog_constructed (GObject *object) /* remember password ticky box */ priv->ticky = gtk_check_button_new_with_label (_("Remember password")); + /* Don't add this to the dialog yet because we haven't set up + * everything in the UI properly yet and the MC transition isn't + * ready etc. so we'll just force it to never remember a + * password. */ + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->ticky), FALSE); + /* gtk_box_pack_start (box, priv->ticky, FALSE, FALSE, 0); gtk_widget_show (priv->ticky); + */ g_signal_connect (dialog, "response", G_CALLBACK (password_dialog_response_cb), dialog); -- cgit v1.2.3 From 4014b19321977ffd5700aa8d1df258393bb74521 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Mon, 6 Dec 2010 15:58:30 +0000 Subject: password-dialog: center the dialog Signed-off-by: Jonny Lamb --- libempathy-gtk/empathy-password-dialog.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libempathy-gtk/empathy-password-dialog.c b/libempathy-gtk/empathy-password-dialog.c index c5a891357..179e68c48 100644 --- a/libempathy-gtk/empathy-password-dialog.c +++ b/libempathy-gtk/empathy-password-dialog.c @@ -286,6 +286,8 @@ empathy_password_dialog_constructed (GObject *object) G_CALLBACK (password_dialog_ungrab_keyboard), dialog); gtk_widget_grab_focus (priv->entry); + + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ALWAYS); } static void -- cgit v1.2.3 From a5a3b01dcda00b938e6ce61d3b6dbf6b0d57abe0 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Mon, 6 Dec 2010 16:24:38 +0000 Subject: keyring: change schema to be incompatible with current MC Signed-off-by: Jonny Lamb --- libempathy/empathy-keyring.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libempathy/empathy-keyring.c b/libempathy/empathy-keyring.c index f3d523e54..2ce53d361 100644 --- a/libempathy/empathy-keyring.c +++ b/libempathy/empathy-keyring.c @@ -29,8 +29,8 @@ static GnomeKeyringPasswordSchema keyring_schema = { GNOME_KEYRING_ITEM_GENERIC_SECRET, - { { "account", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, - { "param", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, + { { "account-id", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, + { "param-name", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, { NULL } } }; static void @@ -83,9 +83,9 @@ empathy_keyring_get_password_async (TpAccount *account, DEBUG ("Trying to get password for: %s", account_id); match = gnome_keyring_attribute_list_new (); - gnome_keyring_attribute_list_append_string (match, "account", + gnome_keyring_attribute_list_append_string (match, "account-id", account_id); - gnome_keyring_attribute_list_append_string (match, "param", "password"); + gnome_keyring_attribute_list_append_string (match, "param-name", "password"); gnome_keyring_find_items (GNOME_KEYRING_ITEM_GENERIC_SECRET, match, find_items_cb, simple, NULL); @@ -154,12 +154,12 @@ empathy_keyring_set_password_async (TpAccount *account, DEBUG ("Remembering password for %s", account_id); - name = g_strdup_printf ("account: %s; param: param-password", account_id); + name = g_strdup_printf ("account: %s; param: password", account_id); gnome_keyring_store_password (&keyring_schema, NULL, name, password, store_password_cb, simple, NULL, - "account", account_id, - "param", "password", + "account-id", account_id, + "param-name", "password", NULL); g_free (name); @@ -250,9 +250,9 @@ empathy_keyring_delete_password_async (TpAccount *account, strlen (TP_ACCOUNT_OBJECT_PATH_BASE); match = gnome_keyring_attribute_list_new (); - gnome_keyring_attribute_list_append_string (match, "account", + gnome_keyring_attribute_list_append_string (match, "account-id", account_id); - gnome_keyring_attribute_list_append_string (match, "param", "password"); + gnome_keyring_attribute_list_append_string (match, "param-name", "password"); gnome_keyring_find_items (GNOME_KEYRING_ITEM_GENERIC_SECRET, match, find_item_to_delete_cb, simple, NULL); -- cgit v1.2.3 From 2599834381f57b1370986e2a574cde6781f0b6bc Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Tue, 7 Dec 2010 11:02:02 +0000 Subject: po: add password-dialog to POTFILES.in Signed-off-by: Jonny Lamb --- po/POTFILES.in | 1 + 1 file changed, 1 insertion(+) diff --git a/po/POTFILES.in b/po/POTFILES.in index 7add53452..eb49cd438 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -55,6 +55,7 @@ libempathy-gtk/empathy-log-window.c [type: gettext/glade]libempathy-gtk/empathy-contact-selector-dialog.ui libempathy-gtk/empathy-new-message-dialog.c libempathy-gtk/empathy-new-call-dialog.c +libempathy-gtk/empathy-password-dialog.c libempathy-gtk/empathy-presence-chooser.c libempathy-gtk/empathy-protocol-chooser.c [type: gettext/glade]libempathy-gtk/empathy-search-bar.ui -- cgit v1.2.3 From 52620257848947efee91e27819cdc8f685784ed8 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Tue, 7 Dec 2010 11:02:14 +0000 Subject: password-dialog: small style change to please make check Signed-off-by: Jonny Lamb --- libempathy-gtk/empathy-password-dialog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libempathy-gtk/empathy-password-dialog.c b/libempathy-gtk/empathy-password-dialog.c index 179e68c48..aebd8f6bc 100644 --- a/libempathy-gtk/empathy-password-dialog.c +++ b/libempathy-gtk/empathy-password-dialog.c @@ -194,11 +194,11 @@ password_dialog_window_state_changed (GtkWidget *widget, || state & GDK_WINDOW_STATE_FULLSCREEN || state & GDK_WINDOW_STATE_MAXIMIZED) { - password_dialog_ungrab_keyboard (widget, (GdkEvent*) event, data); + password_dialog_ungrab_keyboard (widget, (GdkEvent *) event, data); } else { - password_dialog_grab_keyboard (widget, (GdkEvent*) event, data); + password_dialog_grab_keyboard (widget, (GdkEvent *) event, data); } return FALSE; -- cgit v1.2.3 From bd7cb52a486f7f57d75070c28afd1f2b1b0dc017 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Tue, 7 Dec 2010 11:10:15 +0000 Subject: password-dialog: stop using GET_PRIV Signed-off-by: Jonny Lamb --- libempathy-gtk/empathy-password-dialog.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/libempathy-gtk/empathy-password-dialog.c b/libempathy-gtk/empathy-password-dialog.c index aebd8f6bc..3c514ee82 100644 --- a/libempathy-gtk/empathy-password-dialog.c +++ b/libempathy-gtk/empathy-password-dialog.c @@ -30,8 +30,6 @@ G_DEFINE_TYPE (EmpathyPasswordDialog, empathy_password_dialog, GTK_TYPE_MESSAGE_DIALOG) -#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyPasswordDialog); - enum { PROP_HANDLER = 1, @@ -55,7 +53,7 @@ empathy_password_dialog_get_property (GObject *object, GValue *value, GParamSpec *pspec) { - EmpathyPasswordDialogPriv *priv = GET_PRIV (object); + EmpathyPasswordDialogPriv *priv = EMPATHY_PASSWORD_DIALOG (object)->priv; switch (property_id) { @@ -74,7 +72,7 @@ empathy_password_dialog_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { - EmpathyPasswordDialogPriv *priv = GET_PRIV (object); + EmpathyPasswordDialogPriv *priv = EMPATHY_PASSWORD_DIALOG (object)->priv; switch (property_id) { @@ -91,7 +89,7 @@ empathy_password_dialog_set_property (GObject *object, static void empathy_password_dialog_dispose (GObject *object) { - EmpathyPasswordDialogPriv *priv = GET_PRIV (object); + EmpathyPasswordDialogPriv *priv = EMPATHY_PASSWORD_DIALOG (object)->priv; if (priv->dispose_run) return; @@ -108,7 +106,7 @@ password_dialog_response_cb (GtkDialog *dialog, gint response, gpointer user_data) { - EmpathyPasswordDialogPriv *priv = GET_PRIV (user_data); + EmpathyPasswordDialogPriv *priv = EMPATHY_PASSWORD_DIALOG (user_data)->priv; if (response == GTK_RESPONSE_OK) { @@ -150,7 +148,7 @@ password_dialog_grab_keyboard (GtkWidget *widget, GdkEvent *event, gpointer user_data) { - EmpathyPasswordDialogPriv *priv = GET_PRIV (user_data); + EmpathyPasswordDialogPriv *priv = EMPATHY_PASSWORD_DIALOG (user_data)->priv; if (!priv->grabbing) { @@ -171,7 +169,7 @@ password_dialog_ungrab_keyboard (GtkWidget *widget, GdkEvent *event, gpointer user_data) { - EmpathyPasswordDialogPriv *priv = GET_PRIV (user_data); + EmpathyPasswordDialogPriv *priv = EMPATHY_PASSWORD_DIALOG (user_data)->priv; if (priv->grabbing) { @@ -215,7 +213,7 @@ empathy_password_dialog_constructed (GObject *object) gchar *text; dialog = EMPATHY_PASSWORD_DIALOG (object); - priv = GET_PRIV (dialog); + priv = dialog->priv; g_assert (priv->handler != NULL); -- cgit v1.2.3 From 436815408e8a159a56a4a5ce0ee4aa52b51a8800 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Tue, 7 Dec 2010 11:10:20 +0000 Subject: server-sasl-handler: stop using GET_PRIV Signed-off-by: Jonny Lamb --- libempathy/empathy-server-sasl-handler.c | 33 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/libempathy/empathy-server-sasl-handler.c b/libempathy/empathy-server-sasl-handler.c index 4b5a44193..3e6591624 100644 --- a/libempathy/empathy-server-sasl-handler.c +++ b/libempathy/empathy-server-sasl-handler.c @@ -21,9 +21,10 @@ #include +#include + #define DEBUG_FLAG EMPATHY_DEBUG_SASL #include "empathy-debug.h" -#include "empathy-utils.h" #include "empathy-keyring.h" enum { @@ -57,8 +58,6 @@ G_DEFINE_TYPE_WITH_CODE (EmpathyServerSASLHandler, empathy_server_sasl_handler, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init)); -#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyServerSASLHandler); - static const gchar *sasl_statuses[] = { "not started", "in progress", @@ -77,7 +76,7 @@ sasl_status_changed_cb (TpChannel *channel, gpointer user_data, GObject *weak_object) { - EmpathyServerSASLHandlerPriv *priv = GET_PRIV (weak_object); + EmpathyServerSASLHandlerPriv *priv = EMPATHY_SERVER_SASL_HANDLER (weak_object)->priv; /* buh boh */ if (status >= G_N_ELEMENTS (sasl_statuses)) @@ -102,7 +101,7 @@ static gboolean empathy_server_sasl_handler_give_password (gpointer data) { EmpathyServerSASLHandler *self = data; - EmpathyServerSASLHandlerPriv *priv = GET_PRIV (self); + EmpathyServerSASLHandlerPriv *priv = self->priv; empathy_server_sasl_handler_provide_password (self, priv->password, FALSE); @@ -119,7 +118,7 @@ empathy_server_sasl_handler_get_password_async_cb (GObject *source, const gchar *password; GError *error = NULL; - priv = GET_PRIV (user_data); + priv = EMPATHY_SERVER_SASL_HANDLER (user_data)->priv; password = empathy_keyring_get_password_finish (TP_ACCOUNT (source), result, &error); @@ -145,7 +144,7 @@ empathy_server_sasl_handler_init_async (GAsyncInitable *initable, gpointer user_data) { EmpathyServerSASLHandler *self = EMPATHY_SERVER_SASL_HANDLER (initable); - EmpathyServerSASLHandlerPriv *priv = GET_PRIV (self); + EmpathyServerSASLHandlerPriv *priv = self->priv; g_assert (priv->account != NULL); @@ -188,11 +187,9 @@ channel_invalidated_cb (TpProxy *proxy, static void empathy_server_sasl_handler_constructed (GObject *object) { - EmpathyServerSASLHandlerPriv *priv; + EmpathyServerSASLHandlerPriv *priv = EMPATHY_SERVER_SASL_HANDLER (object)->priv; GError *error = NULL; - priv = GET_PRIV (object); - tp_cli_channel_interface_sasl_authentication_connect_to_sasl_status_changed (priv->channel, sasl_status_changed_cb, NULL, NULL, object, &error); @@ -212,7 +209,7 @@ empathy_server_sasl_handler_get_property (GObject *object, GValue *value, GParamSpec *pspec) { - EmpathyServerSASLHandlerPriv *priv = GET_PRIV (object); + EmpathyServerSASLHandlerPriv *priv = EMPATHY_SERVER_SASL_HANDLER (object)->priv; switch (property_id) { @@ -234,7 +231,7 @@ empathy_server_sasl_handler_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { - EmpathyServerSASLHandlerPriv *priv = GET_PRIV (object); + EmpathyServerSASLHandlerPriv *priv = EMPATHY_SERVER_SASL_HANDLER (object)->priv; switch (property_id) { @@ -253,7 +250,7 @@ empathy_server_sasl_handler_set_property (GObject *object, static void empathy_server_sasl_handler_dispose (GObject *object) { - EmpathyServerSASLHandlerPriv *priv = GET_PRIV (object); + EmpathyServerSASLHandlerPriv *priv = EMPATHY_SERVER_SASL_HANDLER (object)->priv; DEBUG ("%p", object); @@ -266,7 +263,7 @@ empathy_server_sasl_handler_dispose (GObject *object) static void empathy_server_sasl_handler_finalize (GObject *object) { - EmpathyServerSASLHandlerPriv *priv = GET_PRIV (object); + EmpathyServerSASLHandlerPriv *priv = EMPATHY_SERVER_SASL_HANDLER (object)->priv; DEBUG ("%p", object); @@ -396,7 +393,7 @@ empathy_server_sasl_handler_provide_password ( g_return_if_fail (EMPATHY_IS_SERVER_SASL_HANDLER (handler)); - priv = GET_PRIV (handler); + priv = handler->priv; array = g_array_sized_new (TRUE, FALSE, sizeof (gchar), strlen (password)); @@ -427,7 +424,7 @@ empathy_server_sasl_handler_cancel (EmpathyServerSASLHandler *handler) g_return_if_fail (EMPATHY_IS_SERVER_SASL_HANDLER (handler)); - priv = GET_PRIV (handler); + priv = handler->priv; DEBUG ("Cancelling SASL mechanism..."); @@ -444,7 +441,7 @@ empathy_server_sasl_handler_get_account (EmpathyServerSASLHandler *handler) g_return_val_if_fail (EMPATHY_IS_SERVER_SASL_HANDLER (handler), NULL); - priv = GET_PRIV (handler); + priv = handler->priv; return priv->account; } @@ -456,7 +453,7 @@ empathy_server_sasl_handler_has_password (EmpathyServerSASLHandler *handler) g_return_val_if_fail (EMPATHY_IS_SERVER_SASL_HANDLER (handler), FALSE); - priv = GET_PRIV (handler); + priv = handler->priv; return (priv->password != NULL); } -- cgit v1.2.3 From eb3f7d2fb30be62b801b6086143fb476b5368b5d Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Tue, 7 Dec 2010 11:11:34 +0000 Subject: server-sasl-handler: shorten very long lines Signed-off-by: Jonny Lamb --- libempathy/empathy-server-sasl-handler.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libempathy/empathy-server-sasl-handler.c b/libempathy/empathy-server-sasl-handler.c index 3e6591624..749311d4b 100644 --- a/libempathy/empathy-server-sasl-handler.c +++ b/libempathy/empathy-server-sasl-handler.c @@ -190,8 +190,8 @@ empathy_server_sasl_handler_constructed (GObject *object) EmpathyServerSASLHandlerPriv *priv = EMPATHY_SERVER_SASL_HANDLER (object)->priv; GError *error = NULL; - tp_cli_channel_interface_sasl_authentication_connect_to_sasl_status_changed (priv->channel, - sasl_status_changed_cb, NULL, NULL, object, &error); + tp_cli_channel_interface_sasl_authentication_connect_to_sasl_status_changed ( + priv->channel, sasl_status_changed_cb, NULL, NULL, object, &error); if (error != NULL) { @@ -403,8 +403,8 @@ empathy_server_sasl_handler_provide_password ( DEBUG ("Calling StartMechanismWithData with our password"); tp_cli_channel_interface_sasl_authentication_call_start_mechanism_with_data ( - priv->channel, -1, "X-TELEPATHY-PASSWORD", array, start_mechanism_with_data_cb, - NULL, NULL, G_OBJECT (handler)); + priv->channel, -1, "X-TELEPATHY-PASSWORD", array, + start_mechanism_with_data_cb, NULL, NULL, G_OBJECT (handler)); g_array_unref (array); -- cgit v1.2.3