source: protocols/jabber/iq.c @ 70f6aab8

Last change on this file since 70f6aab8 was 70f6aab8, checked in by Wilmer van der Gaast <wilmer@…>, at 2006-09-20T20:09:19Z

It now requests a roster when logged in, no parsing for it yet.

  • Property mode set to 100644
File size: 4.9 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        else if( strcmp( type, "result" ) == 0 )
90        {
91                /* If we weren't authenticated yet, let's assume we are now.
92                   There are cleaner ways to do this, probably, but well.. */
93                if( !( jd->flags & JFLAG_AUTHENTICATED ) )
94                {
95                        jd->flags |= JFLAG_AUTHENTICATED;
96                        if( !jabber_get_roster( gc ) )
97                                return XT_ABORT;
98                }
99        }
100        else if( strcmp( type, "error" ) == 0 )
101        {
102                if( !( jd->flags & JFLAG_AUTHENTICATED ) )
103                {
104                        hide_login_progress( gc, "Authentication failure" );
105                        signoff( gc );
106                        return XT_ABORT;
107                }
108        }
109       
110        return XT_HANDLED;
111}
112
113int jabber_start_auth( struct gaim_connection *gc )
114{
115        struct jabber_data *jd = gc->proto_data;
116        struct xt_node *node;
117        int st;
118       
119        node = xt_new_node( "query", NULL, xt_new_node( "username", jd->username, NULL ) );
120        xt_add_attr( node, "xmlns", "jabber:iq:auth" );
121        node = jabber_make_packet( "iq", "get", NULL, node );
122       
123        st = jabber_write_packet( gc, node );
124       
125        xt_free_node( node );
126        return st;
127}
128
129int jabber_get_roster( struct gaim_connection *gc )
130{
131        struct xt_node *node;
132        int st;
133       
134        set_login_progress( gc, 1, "Authenticated, requesting buddy list" );
135       
136        node = xt_new_node( "query", NULL, NULL );
137        xt_add_attr( node, "xmlns", "jabber:iq:roster" );
138        node = jabber_make_packet( "iq", "get", NULL, node );
139       
140        st = jabber_write_packet( gc, node );
141       
142        xt_free_node( node );
143        return st;
144}
Note: See TracBrowser for help on using the repository browser.