diff options
author | Wilmer van der Gaast <wilmer@gaast.net> | 2006-09-20 21:42:27 +0200 |
---|---|---|
committer | Wilmer van der Gaast <wilmer@gaast.net> | 2006-09-20 21:42:27 +0200 |
commit | 21167d2d14c333d67445546bb69dd52dd295287d (patch) | |
tree | 50c010702a3487c666ad8e614b25879de258d9cf /protocols/jabber/iq.c | |
parent | f06894d8f55b50b632c1d81ad878f8581273ba66 (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.c | 81 |
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; +} |