aboutsummaryrefslogtreecommitdiffstats
path: root/protocols/jabber/iq.c
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2006-09-20 21:42:27 +0200
committerWilmer van der Gaast <wilmer@gaast.net>2006-09-20 21:42:27 +0200
commit21167d2d14c333d67445546bb69dd52dd295287d (patch)
tree50c010702a3487c666ad8e614b25879de258d9cf /protocols/jabber/iq.c
parentf06894d8f55b50b632c1d81ad878f8581273ba66 (diff)
It can send a valid (pre-XMPP) login packet. Lots of work to do, still...
Diffstat (limited to 'protocols/jabber/iq.c')
-rw-r--r--protocols/jabber/iq.c81
1 files changed, 78 insertions, 3 deletions
diff --git a/protocols/jabber/iq.c b/protocols/jabber/iq.c
index e3553637..58e3f33c 100644
--- a/protocols/jabber/iq.c
+++ b/protocols/jabber/iq.c
@@ -23,13 +23,88 @@
#include "jabber.h"
+/*
+<iq xmlns="jabber:client" id="BeeX00000001" type="result"><query
+xmlns="jabber:iq:auth"><username>wilmer</username><resource/><password/><digest/>
+<sequence>499</sequence><token>450D1FFD</token></query></iq>
+*/
+
xt_status jabber_pkt_iq( struct xt_node *node, gpointer data )
{
- char *from = xt_find_attr( node, "from" );
+ struct gaim_connection *gc = data;
+ struct jabber_data *jd = gc->proto_data;
+ struct xt_node *query, *reply = NULL;
+ char *s;
+ int st;
+
+ query = xt_find_node( node->children, "query" );
- printf( "Received IQ from %s:\n", from );
- xt_print( node );
+ if( !query )
+ return XT_HANDLED; /* Ignore it for now, don't know what's best... */
+
+ if( ( s = xt_find_attr( query, "xmlns" ) ) && strcmp( s, "jabber:iq:auth" ) == 0 )
+ {
+ /* Time to authenticate ourselves! */
+ reply = xt_new_node( "query", NULL, NULL );
+ xt_add_attr( reply, "xmlns", "jabber:iq:auth" );
+ xt_add_child( reply, xt_new_node( "username", jd->username, NULL ) );
+ xt_add_child( reply, xt_new_node( "resource", set_getstr( &gc->acc->set, "resource" ), NULL ) );
+
+ if( xt_find_node( query->children, "digest" ) && ( s = xt_find_attr( jd->xt->root, "id" ) ) )
+ {
+ /* We can do digest authentication, it seems, and of
+ course we prefer that. */
+ SHA_CTX sha;
+ char hash_hex[40];
+ unsigned char hash[20];
+ int i;
+
+ shaInit( &sha );
+ shaUpdate( &sha, (unsigned char*) s, strlen( s ) );
+ shaUpdate( &sha, (unsigned char*) gc->acc->pass, strlen( gc->acc->pass ) );
+ shaFinal( &sha, hash );
+
+ for( i = 0; i < 20; i ++ )
+ sprintf( hash_hex + i * 2, "%02x", hash[i] );
+
+ xt_add_child( reply, xt_new_node( "digest", hash_hex, NULL ) );
+ }
+ else if( xt_find_node( query->children, "password" ) )
+ {
+ /* We'll have to stick with plaintext. Let's hope we're using SSL/TLS... */
+ xt_add_child( reply, xt_new_node( "password", gc->acc->pass, NULL ) );
+ }
+ else
+ {
+ xt_free_node( reply );
+
+ hide_login_progress_error( gc, "Can't find suitable authentication method" );
+ signoff( gc );
+ return XT_ABORT;
+ }
+
+ reply = jabber_make_packet( "iq", "set", NULL, reply );
+ st = jabber_write_packet( gc, reply );
+ xt_free_node( reply );
+
+ return st ? XT_HANDLED : XT_ABORT;
+ }
return XT_HANDLED;
}
+int jabber_start_auth( struct gaim_connection *gc )
+{
+ struct jabber_data *jd = gc->proto_data;
+ struct xt_node *node;
+ int st;
+
+ node = xt_new_node( "query", NULL, xt_new_node( "username", jd->username, NULL ) );
+ xt_add_attr( node, "xmlns", "jabber:iq:auth" );
+ node = jabber_make_packet( "iq", "get", NULL, node );
+
+ st = jabber_write_packet( gc, node );
+
+ xt_free_node( node );
+ return st;
+}