OBJECTS = sort_udns.o tcp_connect.o iksemel_extra.o tictactoe.o \
- xmpp.o features.o sasl.o
+ xmpp.o features.o sasl.o bind.o
CC = gcc
CFLAGS = -g -Wall `pkg-config --cflags iksemel libgsasl`
LIBS = -ludns `pkg-config --libs iksemel libgsasl`
--- /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 "xmpp_internal.h"
+#include "bind.h"
+
+void
+hc_xmpp_bind (hc_xmpp_t *xmpp)
+{
+ iks *iqbind;
+ iks *query;
+ iqbind = iks_new ("iq");
+ iks_insert_attrib (iqbind, "type", "set");
+ query = iks_insert (iqbind, "bind");
+ iks_insert_attrib (query, "xmlns", HC_XMPP_NS_BIND);
+ hc_xmpp_send_iks (xmpp, iqbind);
+ iks_delete (iqbind);
+}
+
+void
+hc_xmpp_bind_result (hc_xmpp_t *xmpp, iks *result)
+{
+ if (!iks_strcmp (iks_find_attrib (result, "type"), "result"))
+ {
+ xmpp->status = HC_XMPP_BOUND;
+ xmpp->bind |= ENABLED;
+ }
+}
+
+void
+hc_xmpp_session (hc_xmpp_t *xmpp)
+{
+ iks *iqsession;
+ iks *query;
+ iqsession = iks_new ("iq");
+ iks_insert_attrib (iqsession, "type", "set");
+ query = iks_insert (iqsession, "session");
+ iks_insert_attrib (query, "xmlns", HC_XMPP_NS_SESSION);
+ hc_xmpp_send_iks (xmpp, iqsession);
+ iks_delete (iqsession);
+}
+
+void
+hc_xmpp_session_result (hc_xmpp_t *xmpp, iks *result)
+{
+ if (!iks_strcmp (iks_find_attrib (result, "type"), "result"))
+ {
+ xmpp->status = HC_XMPP_SESSION;
+ xmpp->session |= ENABLED;
+ }
+}
+
--- /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_BIND_H
+#define HC_XMPP_BIND_H
+
+#include "xmpp.h"
+
+void hc_xmpp_bind (hc_xmpp_t *);
+void hc_xmpp_bind_result (hc_xmpp_t *, iks *);
+void hc_xmpp_session (hc_xmpp_t *);
+void hc_xmpp_session_result (hc_xmpp_t*, iks *);
+
+#endif
#include "xmpp_internal.h"
-void
+static void
+session (hc_xmpp_t *xmpp, iks *f)
+{
+ iks *c;
+ xmpp->session |= SUPPORTED;
+ for (c = iks_child (f); c != NULL; c = iks_next (c))
+ {
+ if (!iks_strcmp (iks_name (c), "optional"))
+ xmpp->session |= OPTIONAL;
+ else if (!iks_strcmp (iks_name (c), "required"))
+ xmpp->session |= REQUIRED;
+ }
+}
+
+static void
+xmpp_bind (hc_xmpp_t *xmpp, iks *f)
+{
+ iks *c;
+ xmpp->bind |= SUPPORTED;
+ for (c = iks_child (f); c != NULL; c = iks_next (c))
+ {
+ if (!iks_strcmp (iks_name (c), "optional"))
+ xmpp->bind |= OPTIONAL;
+ else if (!iks_strcmp (iks_name (c), "required"))
+ xmpp->bind |= REQUIRED;
+ }
+}
+
+static void
sasl (hc_xmpp_t *xmpp, iks *f)
{
iks *c;
}
}
-void
+static void
tls (hc_xmpp_t *xmpp, iks *f)
{
iks *c;
if (!iks_strcmp (iks_name (c), "starttls") &&
!iks_strcmp (iks_find_attrib (c, "xmlns"), HC_XMPP_NS_TLS))
tls (xmpp, c);
- if (!iks_strcmp (iks_name (c), "mechanisms") &&
+ else if (!iks_strcmp (iks_name (c), "mechanisms") &&
!iks_strcmp (iks_find_attrib (c, "xmlns"), HC_XMPP_NS_SASL))
sasl (xmpp, c);
+ else if (!iks_strcmp (iks_name (c), "bind") &&
+ !iks_strcmp (iks_find_attrib (c, "xmlns"), HC_XMPP_NS_BIND))
+ xmpp_bind (xmpp, c);
+ else if (!iks_strcmp (iks_name (c), "session") &&
+ !iks_strcmp (iks_find_attrib (c, "xmlns"), HC_XMPP_NS_SESSION))
+ session (xmpp, c);
}
}
iks_insert_cdata (auth, p, 0);
hc_xmpp_send_iks (xmpp, auth);
free (p);
+ iks_delete (auth);
}
void
{
if (!iks_strcmp (iks_name (stanza), "success"))
{
+ xmpp->sasl |= ENABLED;
xmpp->status = HC_XMPP_AUTHENTICATED;
}
}
#include "iksemel_extra.h"
#include "xmpp.h"
#include "sasl.h"
+#include "bind.h"
-int
+static void write_stream (hc_xmpp_t *);
+
+static void
+send_message_test (hc_xmpp_t *xmpp)
+{
+ iks *msg;
+ msg = iks_new ("message");
+ iks_insert_attrib (msg, "to", "metal@jabber-br.org");
+ iks_insert_cdata (iks_insert (msg, "body"), "pubsub", 0);
+ hc_xmpp_send_iks (xmpp, msg);
+ iks_delete (msg);
+}
+
+static int
myhook (void *data, int type, iks *stanza)
{
- if (!iks_strcmp (iks_name (stanza), "stream:features"))
+ if (!iks_strcmp (iks_name (stanza), "iq"))
+ {
+ char *ns = iks_find_attrib (iks_child (stanza), "xmlns");
+ if (!iks_strcmp (ns, HC_XMPP_NS_BIND))
+ {
+ hc_xmpp_bind_result (data, stanza);
+ if (hc_xmpp_status (data) == HC_XMPP_BOUND &&
+ hc_xmpp_is_session_supported (data))
+ hc_xmpp_session (data);
+ }
+ else if (!iks_strcmp (ns, HC_XMPP_NS_SESSION))
+ {
+ hc_xmpp_session_result (data, stanza);
+ if (hc_xmpp_status (data) == HC_XMPP_SESSION)
+ send_message_test (data);
+ }
+ }
+ else if (!iks_strcmp (iks_name (stanza), "stream:features"))
{
hc_xmpp_features (data, stanza);
- if (hc_xmpp_is_sasl_supported (data))
+ if (hc_xmpp_is_sasl_supported (data) & !hc_xmpp_is_sasl_enabled (data))
{
hc_xmpp_sasl_authenticate (data);
}
+ if (hc_xmpp_is_bind_supported (data))
+ {
+ hc_xmpp_bind (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");
+ {
+ write_stream (data);
+ fprintf (stdout, "Authenticated\n");
+ }
}
else
{
return IKS_OK;
}
-void
+static void
write_stream (hc_xmpp_t *xmpp)
{
char *buffer = NULL;
free (buffer);
}
-void
+static void
loop (hc_xmpp_t *xmpp)
{
while (1)
return xmpp->sasl & ENABLED;
}
+int
+hc_xmpp_is_bind_supported (hc_xmpp_t *xmpp)
+{
+ return xmpp->bind & SUPPORTED;
+}
+
+int
+hc_xmpp_is_session_supported (hc_xmpp_t *xmpp)
+{
+ return xmpp->session & SUPPORTED;
+}
+
+int
+hc_xmpp_is_session_required (hc_xmpp_t *xmpp)
+{
+ return xmpp->session & REQUIRED;
+}
+
char *
hc_xmpp_server (hc_xmpp_t *xmpp)
{
{
HC_XMPP_NONE,
HC_XMPP_AUTHENTICATED,
- HC_XMPP_BOUND
+ HC_XMPP_BOUND,
+ HC_XMPP_SESSION
};
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"
+#define HC_XMPP_NS_BIND "urn:ietf:params:xml:ns:xmpp-bind"
+#define HC_XMPP_NS_SESSION "urn:ietf:params:xml:ns:xmpp-session"
hc_xmpp_t * hc_xmpp_new (iksStreamHook *, char *, char *, char *);
int hc_xmpp_is_tls_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 *);
+int hc_xmpp_is_bind_supported (hc_xmpp_t *);
+int hc_xmpp_is_session_supported (hc_xmpp_t *);
+int hc_xmpp_is_session_required (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 *);
int fd;
int tls;
int sasl;
+ int bind;
+ int session;
int status;
};