From: Thadeu Lima de Souza Cascardo Date: Sun, 2 Nov 2008 11:58:02 +0000 (-0200) Subject: Support for SASL PLAIN authentication X-Git-Url: http://git.cascardo.info/?p=cascardo%2Fchat.git;a=commitdiff_plain;h=fee0c9537ee0b8dc497fd789d0c20e5db09766a8 Support for SASL PLAIN authentication --- diff --git a/Makefile b/Makefile index 15fe746..275426f 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ OBJECTS = sort_udns.o tcp_connect.o iksemel_extra.o tictactoe.o \ - xmpp.o features.o + xmpp.o features.o sasl.o CC = gcc -CFLAGS = -g -Wall `pkg-config --cflags iksemel` -LIBS = -ludns `pkg-config --libs iksemel` +CFLAGS = -g -Wall `pkg-config --cflags iksemel libgsasl` +LIBS = -ludns `pkg-config --libs iksemel libgsasl` all: tictactoe diff --git a/sasl.c b/sasl.c new file mode 100644 index 0000000..dd93367 --- /dev/null +++ b/sasl.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2008 Thadeu Lima de Souza Cascardo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + + +#include +#include +#include "xmpp_internal.h" +#include "sasl.h" + +void +hc_xmpp_sasl_authenticate (hc_xmpp_t *xmpp) +{ + const char *mech = "PLAIN"; + char *p = ""; + iks *auth; + gsasl_client_start (xmpp->sasl_ctx, mech, &xmpp->sasl_session); + gsasl_property_set (xmpp->sasl_session, GSASL_AUTHID, xmpp->user); + gsasl_property_set (xmpp->sasl_session, GSASL_PASSWORD, xmpp->password); + gsasl_step64 (xmpp->sasl_session, p, &p); + auth = iks_new ("auth"); + iks_insert_attrib (auth, "xmlns", HC_XMPP_NS_SASL); + iks_insert_attrib (auth, "mechanism", mech); + iks_insert_cdata (auth, p, 0); + hc_xmpp_send_iks (xmpp, auth); + free (p); +} + +void +hc_xmpp_sasl_iterate (hc_xmpp_t *xmpp, iks *stanza) +{ + if (!iks_strcmp (iks_name (stanza), "success")) + { + xmpp->status = HC_XMPP_AUTHENTICATED; + } +} diff --git a/sasl.h b/sasl.h new file mode 100644 index 0000000..a5bafb7 --- /dev/null +++ b/sasl.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2008 Thadeu Lima de Souza Cascardo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + + +#ifndef HC_XMPP_SASL_H +#define HC_XMPP_SASL_H + +#include "xmpp.h" + +void hc_xmpp_sasl_authenticate (hc_xmpp_t *); +void hc_xmpp_sasl_iterate (hc_xmpp_t *, iks *); + +#endif diff --git a/tictactoe.c b/tictactoe.c index cc1dab5..700a269 100644 --- a/tictactoe.c +++ b/tictactoe.c @@ -26,6 +26,7 @@ #include "tcp_connect.h" #include "iksemel_extra.h" #include "xmpp.h" +#include "sasl.h" int myhook (void *data, int type, iks *stanza) @@ -33,10 +34,16 @@ myhook (void *data, int type, iks *stanza) if (!iks_strcmp (iks_name (stanza), "stream:features")) { hc_xmpp_features (data, stanza); - if (hc_xmpp_is_tls_supported (data)) - fprintf (stderr, "TLS is supported\n"); if (hc_xmpp_is_sasl_supported (data)) - fprintf (stderr, "SASL is supported\n"); + { + hc_xmpp_sasl_authenticate (data); + } + } + else if (!iks_strcmp (iks_find_attrib (stanza, "xmlns"), HC_XMPP_NS_SASL)) + { + hc_xmpp_sasl_iterate (data, stanza); + if (hc_xmpp_status (data) == HC_XMPP_AUTHENTICATED) + fprintf (stdout, "Authenticated\n"); } else { @@ -46,32 +53,32 @@ myhook (void *data, int type, iks *stanza) } void -write_stream (hc_xmpp_t *xmpp); +write_stream (hc_xmpp_t *xmpp) { char *buffer = NULL; asprintf (&buffer, "", xmpp->server); - write (xmpp->fd, buffer, strlen (buffer)); + "version='1.0' to='%s'>", hc_xmpp_server (xmpp)); + hc_xmpp_send_buffer (xmpp, buffer, 0); free (buffer); } void -loop (hc_xmpp_t *xmpp); +loop (hc_xmpp_t *xmpp) { - char buffer[4096]; - int r; - while ((r = read (xmpp->fd, buffer, sizeof (buffer))) > 0) - iks_parse (xmpp->parser, buffer, r, 0); + while (1) + hc_xmpp_read_and_parse (xmpp); } int main (int argc, char **argv) { char *server = "jabber-br.org"; + char *user = "pubsub"; + char *password = "pubsub"; hc_xmpp_t *xmpp; dns_init (NULL, 1); - xmpp = hc_xmpp_new (myhook, server); + xmpp = hc_xmpp_new (myhook, server, user, password); write_stream (xmpp); loop (xmpp); return 0; diff --git a/xmpp.c b/xmpp.c index a6a0a09..ca9501e 100644 --- a/xmpp.c +++ b/xmpp.c @@ -18,19 +18,26 @@ #include +#include +#include #include "xmpp.h" #include "xmpp_internal.h" #include "iksemel_extra.h" +#include "tcp_connect.h" hc_xmpp_t * -hc_xmpp_new (iksStreamHook *hook, char *server) +hc_xmpp_new (iksStreamHook *hook, char *server, char *user, char *pass) { hc_xmpp_t *xmpp = malloc (sizeof (hc_xmpp_t)); xmpp->server = strdup (server); + xmpp->user = strdup (user); + xmpp->password = strdup (pass); xmpp->parser = iks_extra_stream_new (xmpp, hook); + gsasl_init (&xmpp->sasl_ctx); xmpp->fd = hc_tcp_connect (server, "xmpp-client"); xmpp->tls = NONE; xmpp->sasl = NONE; + xmpp->status = HC_XMPP_NONE; return xmpp; } @@ -82,3 +89,39 @@ hc_xmpp_is_sasl_enabled (hc_xmpp_t *xmpp) return xmpp->sasl & ENABLED; } +char * +hc_xmpp_server (hc_xmpp_t *xmpp) +{ + return xmpp->server; +} + +void +hc_xmpp_send_buffer (hc_xmpp_t *xmpp, char *buffer, size_t len) +{ + if (len == 0) + len = strlen (buffer); + write (xmpp->fd, buffer, len); +} + +void +hc_xmpp_send_iks (hc_xmpp_t *xmpp, iks *x) +{ + char *str; + str = iks_string (iks_stack (x), x); + write (xmpp->fd, str, strlen (str)); +} + +void +hc_xmpp_read_and_parse (hc_xmpp_t *xmpp) +{ + char buffer[4096]; + int r; + r = read (xmpp->fd, buffer, sizeof (buffer)); + iks_parse (xmpp->parser, buffer, r, 0); +} + +int +hc_xmpp_status (hc_xmpp_t *xmpp) +{ + return xmpp->status; +} diff --git a/xmpp.h b/xmpp.h index 74cee4a..7a0e0d0 100644 --- a/xmpp.h +++ b/xmpp.h @@ -22,12 +22,19 @@ #include +enum +{ + HC_XMPP_NONE, + HC_XMPP_AUTHENTICATED, + HC_XMPP_BOUND +}; + typedef struct _hc_xmpp_t hc_xmpp_t; #define HC_XMPP_NS_TLS "urn:ietf:params:xml:ns:xmpp-tls" #define HC_XMPP_NS_SASL "urn:ietf:params:xml:ns:xmpp-sasl" -hc_xmpp_t * hc_xmpp_new (void); +hc_xmpp_t * hc_xmpp_new (iksStreamHook *, char *, char *, char *); int hc_xmpp_is_tls_supported (hc_xmpp_t *); int hc_xmpp_is_tls_required (hc_xmpp_t *); int hc_xmpp_is_tls_optional (hc_xmpp_t *); @@ -36,6 +43,11 @@ int hc_xmpp_is_sasl_supported (hc_xmpp_t *); int hc_xmpp_is_sasl_required (hc_xmpp_t *); int hc_xmpp_is_sasl_optional (hc_xmpp_t *); int hc_xmpp_is_sasl_enabled (hc_xmpp_t *); +char *hc_xmpp_server (hc_xmpp_t *); +void hc_xmpp_send_buffer (hc_xmpp_t *, char *, size_t); +void hc_xmpp_send_iks (hc_xmpp_t *, iks *); +void hc_xmpp_read_and_parse (hc_xmpp_t *); void hc_xmpp_features (hc_xmpp_t *, iks *); +int hc_xmpp_status (hc_xmpp_t *); #endif diff --git a/xmpp_internal.h b/xmpp_internal.h index f57c688..df8790c 100644 --- a/xmpp_internal.h +++ b/xmpp_internal.h @@ -20,6 +20,7 @@ #ifndef HC_XMPP_INTERNAL_H #define HC_XMPP_INTERNAL_H +#include #include #include "xmpp.h" @@ -35,10 +36,15 @@ enum struct _hc_xmpp_t { char *server; + char *user; + char *password; iksparser *parser; + Gsasl *sasl_ctx; + Gsasl_session *sasl_session; int fd; int tls; int sasl; + int status; }; #endif