summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDafydd Harries <dafydd.harries@collabora.co.uk>2009-11-17 20:02:22 -0500
committerDafydd Harries <dafydd.harries@collabora.co.uk>2009-11-17 20:07:41 -0500
commit78885334038f201e9a4dbaf1bd04d004fd35b32a (patch)
treea28e61b50a3db5391efe7bf56ff264b72246f7fd
parent9dfc9defae7aa003a8ce4a49338fab710c7f6ce0 (diff)
allow adding extra handlers to WockySaslAuth instances
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/wocky-test-sasl-auth-server.c44
-rw-r--r--tests/wocky-test-sasl-auth.c15
-rw-r--r--tests/wocky-test-sasl-handler.c70
-rw-r--r--tests/wocky-test-sasl-handler.h42
-rw-r--r--wocky/wocky-sasl-auth.c35
-rw-r--r--wocky/wocky-sasl-auth.h3
7 files changed, 194 insertions, 17 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3be2b34..5ba5f9b 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -108,6 +108,8 @@ wocky_test_sasl_auth_DEPENDENCIES = $(LIBWOCKY)
wocky_test_sasl_auth_SOURCES = \
wocky-test-helper.c wocky-test-helper.h \
wocky-test-sasl-auth.c \
+ wocky-test-sasl-handler.c \
+ wocky-test-sasl-handler.h \
wocky-test-sasl-auth-server.c \
wocky-test-sasl-auth-server.h \
wocky-test-stream.c \
diff --git a/tests/wocky-test-sasl-auth-server.c b/tests/wocky-test-sasl-auth-server.c
index d29648c..5540c45 100644
--- a/tests/wocky-test-sasl-auth-server.c
+++ b/tests/wocky-test-sasl-auth-server.c
@@ -602,27 +602,37 @@ handle_auth (TestSaslAuthServer *self, WockyXmppStanza *stanza)
priv->state = AUTH_STATE_CHALLENGE;
-#if HAVE_LIBSASL2
- ret = sasl_server_start (priv->sasl_conn, mech, (gchar *) response,
- (unsigned) response_len, &challenge, &challenge_len);
-#else
- challenge = "";
- challenge_len = 0;
- g_assert (!wocky_strdiff ("PLAIN", mech));
- /* response format: ^@ u s e r ^@ p a s s */
- /* require at least 1 char user and password */
- if (response_len >= 4)
+ if (!wocky_strdiff ("X-TEST", mech))
{
- const gchar *user = ((gchar *) response) + 1;
- int ulen = strlen (user);
- gchar *pass = g_strndup (user + ulen + 1, response_len - ulen - 2);
- ret = ( wocky_strdiff (user, priv->username) ? SASL_NOUSER :
- wocky_strdiff (pass, priv->password) ? SASL_BADAUTH : SASL_OK );
- g_free (pass);
+ challenge = "";
+ challenge_len = 0;
+ ret = wocky_strdiff ((gchar *) response, priv->password) ?
+ SASL_BADAUTH : SASL_OK;
}
else
- ret = SASL_BADAUTH;
+ {
+#if HAVE_LIBSASL2
+ ret = sasl_server_start (priv->sasl_conn, mech, (gchar *) response,
+ (unsigned) response_len, &challenge, &challenge_len);
+#else
+ challenge = "";
+ challenge_len = 0;
+ g_assert (!wocky_strdiff ("PLAIN", mech));
+ /* response format: ^@ u s e r ^@ p a s s */
+ /* require at least 1 char user and password */
+ if (response_len >= 4)
+ {
+ const gchar *user = ((gchar *) response) + 1;
+ int ulen = strlen (user);
+ gchar *pass = g_strndup (user + ulen + 1, response_len - ulen - 2);
+ ret = ( wocky_strdiff (user, priv->username) ? SASL_NOUSER :
+ wocky_strdiff (pass, priv->password) ? SASL_BADAUTH : SASL_OK );
+ g_free (pass);
+ }
+ else
+ ret = SASL_BADAUTH;
#endif
+ }
if (!check_sasl_return (self, ret))
goto out;
diff --git a/tests/wocky-test-sasl-auth.c b/tests/wocky-test-sasl-auth.c
index e4a55ef..259ef48 100644
--- a/tests/wocky-test-sasl-auth.c
+++ b/tests/wocky-test-sasl-auth.c
@@ -1,6 +1,7 @@
#include <stdio.h>
#include "wocky-test-sasl-auth-server.h"
+#include "wocky-test-sasl-handler.h"
#include "wocky-test-stream.h"
#include "wocky-test-helper.h"
@@ -135,6 +136,7 @@ feature_stanza_received (GObject *source,
gpointer user_data)
{
WockyXmppStanza *stanza;
+ WockySaslHandler *test_handler;
test_t *test = (test_t *) user_data;
stanza = wocky_xmpp_connection_recv_stanza_finish (
@@ -148,6 +150,10 @@ feature_stanza_received (GObject *source,
test->wrong_password ? "wrong" : test->password,
WOCKY_XMPP_CONNECTION (source));
+ test_handler = WOCKY_SASL_HANDLER (wocky_test_sasl_handler_new ());
+ wocky_sasl_auth_add_handler (sasl, test_handler);
+ g_object_unref (test_handler);
+
wocky_sasl_auth_authenticate_async (sasl,
stanza,
current_test->allow_plain, NULL,
@@ -299,6 +305,15 @@ main (int argc,
{ "/xmpp-sasl/digest-md5-slash-challenge", "DIGEST-MD5", FALSE,
0, 0, SERVER_PROBLEM_SLASH_CHALLENGE, FALSE, FALSE,
"moose", "something", "cass-x200s" },
+
+ { "/xmpp-sasl/external-handler-fail", "X-TEST", FALSE,
+ WOCKY_SASL_AUTH_ERROR, WOCKY_SASL_AUTH_ERROR_FAILURE,
+ SERVER_PROBLEM_INVALID_PASSWORD, FALSE, FALSE,
+ "dave", "daisy daisy", "hal" },
+
+ { "/xmpp-sasl/external-handler-succeed", "X-TEST", FALSE,
+ 0, 0, SERVER_PROBLEM_NO_PROBLEM, FALSE, FALSE,
+ "ripley", "open sesame", "mother" },
};
test_init (argc, argv);
diff --git a/tests/wocky-test-sasl-handler.c b/tests/wocky-test-sasl-handler.c
new file mode 100644
index 0000000..1053633
--- /dev/null
+++ b/tests/wocky-test-sasl-handler.c
@@ -0,0 +1,70 @@
+
+#include "wocky-test-sasl-handler.h"
+
+#include <wocky/wocky-sasl-handler.h>
+
+static void
+sasl_handler_iface_init (gpointer g_iface);
+
+G_DEFINE_TYPE_WITH_CODE (WockyTestSaslHandler, wocky_test_sasl_handler,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (WOCKY_TYPE_SASL_HANDLER, sasl_handler_iface_init))
+
+static void
+wocky_test_sasl_handler_class_init (WockyTestSaslHandlerClass *klass)
+{
+}
+
+static void
+wocky_test_sasl_handler_init (WockyTestSaslHandler *self)
+{
+}
+
+static gchar *
+test_handle_challenge (WockySaslHandler *handler,
+ WockyXmppStanza *stanza, GError **error);
+
+static void
+test_handle_success (WockySaslHandler *handler, WockyXmppStanza *stanza,
+ GError **error);
+
+static void
+test_handle_failure (WockySaslHandler *handler, WockyXmppStanza *stanza,
+ GError **error);
+
+static void
+sasl_handler_iface_init (gpointer g_iface)
+{
+ WockySaslHandlerIface *iface = g_iface;
+
+ iface->mechanism = "X-TEST";
+ iface->challenge_func = test_handle_challenge;
+ iface->success_func = test_handle_success;
+ iface->failure_func = test_handle_failure;
+}
+
+WockyTestSaslHandler*
+wocky_test_sasl_handler_new (void)
+{
+ return g_object_new (WOCKY_TYPE_TEST_SASL_HANDLER, NULL);
+}
+
+static gchar *
+test_handle_challenge (WockySaslHandler *handler,
+ WockyXmppStanza *stanza, GError **error)
+{
+ return g_base64_encode ((guchar *) "open sesame", 11);
+}
+
+static void
+test_handle_success (WockySaslHandler *handler, WockyXmppStanza *stanza,
+ GError **error)
+{
+}
+
+static void
+test_handle_failure (WockySaslHandler *handler, WockyXmppStanza *stanza,
+ GError **error)
+{
+}
+
diff --git a/tests/wocky-test-sasl-handler.h b/tests/wocky-test-sasl-handler.h
new file mode 100644
index 0000000..2cf7941
--- /dev/null
+++ b/tests/wocky-test-sasl-handler.h
@@ -0,0 +1,42 @@
+#ifndef _WOCKY_TEST_SASL_HANDLER_H
+#define _WOCKY_TEST_SASL_HANDLER_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define WOCKY_TYPE_TEST_SASL_HANDLER wocky_test_sasl_handler_get_type()
+
+#define WOCKY_TEST_SASL_HANDLER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), WOCKY_TYPE_TEST_SASL_HANDLER, \
+ WockyTestSaslHandler))
+
+#define WOCKY_TEST_SASL_HANDLER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), WOCKY_TYPE_TEST_SASL_HANDLER, \
+ WockyTestSaslHandlerClass))
+
+#define WOCKY_IS_TEST_SASL_HANDLER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), WOCKY_TYPE_TEST_SASL_HANDLER))
+
+#define WOCKY_IS_TEST_SASL_HANDLER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), WOCKY_TYPE_TEST_SASL_HANDLER))
+
+#define WOCKY_TEST_SASL_HANDLER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), WOCKY_TYPE_TEST_SASL_HANDLER, \
+ WockyTestSaslHandlerClass))
+
+typedef struct {
+ GObject parent;
+} WockyTestSaslHandler;
+
+typedef struct {
+ GObjectClass parent_class;
+} WockyTestSaslHandlerClass;
+
+GType wocky_test_sasl_handler_get_type (void);
+
+WockyTestSaslHandler* wocky_test_sasl_handler_new (void);
+
+G_END_DECLS
+
+#endif /* _WOCKY_TEST_SASL_HANDLER_H */
diff --git a/wocky/wocky-sasl-auth.c b/wocky/wocky-sasl-auth.c
index b084af6..2b01571 100644
--- a/wocky/wocky-sasl-auth.c
+++ b/wocky/wocky-sasl-auth.c
@@ -67,6 +67,7 @@ struct _WockySaslAuthPrivate
WockySaslHandler *handler;
GCancellable *cancel;
GSimpleAsyncResult *result;
+ GSList *handlers;
};
#define WOCKY_SASL_AUTH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), WOCKY_TYPE_SASL_AUTH, WockySaslAuthPrivate))
@@ -212,6 +213,12 @@ wocky_sasl_auth_dispose (GObject *object)
g_object_unref (priv->handler);
}
+ if (priv->handlers != NULL)
+ {
+ g_slist_foreach (priv->handlers, (GFunc) g_object_unref, NULL);
+ g_slist_free (priv->handlers);
+ }
+
if (priv->connection != NULL)
{
g_object_unref (priv->connection);
@@ -594,6 +601,24 @@ wocky_sasl_auth_select_handler (
WockySaslAuth *sasl, gboolean allow_plain, GSList *mechanisms)
{
WockySaslAuthPrivate *priv = WOCKY_SASL_AUTH_GET_PRIVATE (sasl);
+ GSList *i, *k;
+
+ for (k = priv->handlers; k != NULL; k = k->next)
+ {
+ WockySaslHandler *handler = k->data;
+ const gchar *handler_mech = wocky_sasl_handler_get_mechanism (handler);
+
+ for (i = mechanisms; i != NULL; i = i->next)
+ {
+ const gchar *mechanism = i->data;
+
+ if (!wocky_strdiff (handler_mech, mechanism))
+ {
+ g_object_ref (handler);
+ return handler;
+ }
+ }
+ }
if (wocky_sasl_auth_has_mechanism (mechanisms, "DIGEST-MD5"))
{
@@ -677,3 +702,13 @@ out:
g_slist_free (mechanisms);
}
+
+void
+wocky_sasl_auth_add_handler (WockySaslAuth *auth, WockySaslHandler *handler)
+{
+ WockySaslAuthPrivate *priv = WOCKY_SASL_AUTH_GET_PRIVATE (auth);
+
+ g_object_ref (handler);
+ priv->handlers = g_slist_append (priv->handlers, handler);
+}
+
diff --git a/wocky/wocky-sasl-auth.h b/wocky/wocky-sasl-auth.h
index bbd60f9..bb177e1 100644
--- a/wocky/wocky-sasl-auth.h
+++ b/wocky/wocky-sasl-auth.h
@@ -104,6 +104,9 @@ gboolean wocky_sasl_auth_authenticate_finish (WockySaslAuth *sasl,
const gchar *
wocky_sasl_auth_mechanism_used (WockySaslAuth *sasl);
+void
+wocky_sasl_auth_add_handler (WockySaslAuth *auth, WockySaslHandler *handler);
+
G_END_DECLS
#endif /* #ifndef __WOCKY_SASL_AUTH_H__*/