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; +} | 
