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
--- /dev/null
+/*
+ * Copyright (C) 2008 Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
+ *
+ * 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 <string.h>
+#include <stdlib.h>
+#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;
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2008 Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
+ *
+ * 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
#include "tcp_connect.h"
#include "iksemel_extra.h"
#include "xmpp.h"
+#include "sasl.h"
int
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
{
}
void
-write_stream (hc_xmpp_t *xmpp);
+write_stream (hc_xmpp_t *xmpp)
{
char *buffer = NULL;
asprintf (&buffer, "<stream:stream xmlns='jabber:client' "
"xmlns:stream='http://etherx.jabber.org/streams' "
- "version='1.0' to='%s'>", 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;
#include <stdlib.h>
+#include <string.h>
+#include <gsasl.h>
#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;
}
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;
+}
#include <iksemel.h>
+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 *);
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
#ifndef HC_XMPP_INTERNAL_H
#define HC_XMPP_INTERNAL_H
+#include <gsasl.h>
#include <iksemel.h>
#include "xmpp.h"
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