source: protocols/jabber/iq.c @ 5997488

Last change on this file since 5997488 was 0b4a0db, checked in by Wilmer van der Gaast <wilmer@…>, at 2006-09-20T20:26:47Z

Now parsing roster properly. (Hopefully...)

  • Property mode set to 100644
File size: 5.5 KB
Line 
1/***************************************************************************\
2*                                                                           *
3*  BitlBee - An IRC to IM gateway                                           *
4*  Jabber module - IQ packets                                               *
5*                                                                           *
6*  Copyright 2006 Wilmer van der Gaast <wilmer@gaast.net>                   *
7*                                                                           *
8*  This program is free software; you can redistribute it and/or modify     *
9*  it under the terms of the GNU General Public License as published by     *
10*  the Free Software Foundation; either version 2 of the License, or        *
11*  (at your option) any later version.                                      *
12*                                                                           *
13*  This program is distributed in the hope that it will be useful,          *
14*  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
15*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
16*  GNU General Public License for more details.                             *
17*                                                                           *
18*  You should have received a copy of the GNU General Public License along  *
19*  with this program; if not, write to the Free Software Foundation, Inc.,  *
20*  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.              *
21*                                                                           *
22\***************************************************************************/
23
24#include "jabber.h"
25
26xt_status jabber_pkt_iq( struct xt_node *node, gpointer data )
27{
28        struct gaim_connection *gc = data;
29        struct jabber_data *jd = gc->proto_data;
30        struct xt_node *query, *reply = NULL;
31        char *s, *type, *xmlns;
32        int st;
33       
34        query = xt_find_node( node->children, "query" );
35        type = xt_find_attr( node, "type" );
36       
37        if( !type )
38                return XT_HANDLED;      /* Ignore it for now, don't know what's best... */
39       
40        xmlns = xt_find_attr( query, "xmlns" );
41       
42        if( strcmp( type, "result" ) == 0 && xmlns && strcmp( xmlns, "jabber:iq:auth" ) == 0 )
43        {
44                /* Time to authenticate ourselves! */
45                reply = xt_new_node( "query", NULL, NULL );
46                xt_add_attr( reply, "xmlns", "jabber:iq:auth" );
47                xt_add_child( reply, xt_new_node( "username", jd->username, NULL ) );
48                xt_add_child( reply, xt_new_node( "resource", set_getstr( &gc->acc->set, "resource" ), NULL ) );
49               
50                if( xt_find_node( query->children, "digest" ) && ( s = xt_find_attr( jd->xt->root, "id" ) ) )
51                {
52                        /* We can do digest authentication, it seems, and of
53                           course we prefer that. */
54                        SHA_CTX sha;
55                        char hash_hex[40];
56                        unsigned char hash[20];
57                        int i;
58                       
59                        shaInit( &sha );
60                        shaUpdate( &sha, (unsigned char*) s, strlen( s ) );
61                        shaUpdate( &sha, (unsigned char*) gc->acc->pass, strlen( gc->acc->pass ) );
62                        shaFinal( &sha, hash );
63                       
64                        for( i = 0; i < 20; i ++ )
65                                sprintf( hash_hex + i * 2, "%02x", hash[i] );
66                       
67                        xt_add_child( reply, xt_new_node( "digest", hash_hex, NULL ) );
68                }
69                else if( xt_find_node( query->children, "password" ) )
70                {
71                        /* We'll have to stick with plaintext. Let's hope we're using SSL/TLS... */
72                        xt_add_child( reply, xt_new_node( "password", gc->acc->pass, NULL ) );
73                }
74                else
75                {
76                        xt_free_node( reply );
77                       
78                        hide_login_progress( gc, "Can't find suitable authentication method" );
79                        signoff( gc );
80                        return XT_ABORT;
81                }
82               
83                reply = jabber_make_packet( "iq", "set", NULL, reply );
84                st = jabber_write_packet( gc, reply );
85                xt_free_node( reply );
86               
87                return st ? XT_HANDLED : XT_ABORT;
88        }
89        if( strcmp( type, "result" ) == 0 && xmlns && strcmp( xmlns, "jabber:iq:roster" ) == 0 )
90        {
91                struct xt_node *node;
92               
93                node = query->children;
94                while( ( node = xt_find_node( node, "item" ) ) )
95                {
96                        char *jid = xt_find_attr( node, "jid" );
97                        char *name = xt_find_attr( node, "name" );
98                        char *sub = xt_find_attr( node, "subscription" );
99                       
100                        if( jid && sub && ( strcmp( sub, "both" ) == 0 || strcmp( sub, "to" ) == 0 ) )
101                                add_buddy( gc, NULL, jid, name );
102                       
103                        node = node->next;
104                }
105               
106                presence_announce( gc );
107        }
108        else if( strcmp( type, "result" ) == 0 )
109        {
110                /* If we weren't authenticated yet, let's assume we are now.
111                   There are cleaner ways to do this, probably, but well.. */
112                if( !( jd->flags & JFLAG_AUTHENTICATED ) )
113                {
114                        jd->flags |= JFLAG_AUTHENTICATED;
115                        if( !jabber_get_roster( gc ) )
116                                return XT_ABORT;
117                }
118        }
119        else if( strcmp( type, "error" ) == 0 )
120        {
121                if( !( jd->flags & JFLAG_AUTHENTICATED ) )
122                {
123                        hide_login_progress( gc, "Authentication failure" );
124                        signoff( gc );
125                        return XT_ABORT;
126                }
127        }
128       
129        return XT_HANDLED;
130}
131
132int jabber_start_auth( struct gaim_connection *gc )
133{
134        struct jabber_data *jd = gc->proto_data;
135        struct xt_node *node;
136        int st;
137       
138        node = xt_new_node( "query", NULL, xt_new_node( "username", jd->username, NULL ) );
139        xt_add_attr( node, "xmlns", "jabber:iq:auth" );
140        node = jabber_make_packet( "iq", "get", NULL, node );
141       
142        st = jabber_write_packet( gc, node );
143       
144        xt_free_node( node );
145        return st;
146}
147
148int jabber_get_roster( struct gaim_connection *gc )
149{
150        struct xt_node *node;
151        int st;
152       
153        set_login_progress( gc, 1, "Authenticated, requesting buddy list" );
154       
155        node = xt_new_node( "query", NULL, NULL );
156        xt_add_attr( node, "xmlns", "jabber:iq:roster" );
157        node = jabber_make_packet( "iq", "get", NULL, node );
158       
159        st = jabber_write_packet( gc, node );
160       
161        xt_free_node( node );
162        return st;
163}
Note: See TracBrowser for help on using the repository browser.