source: protocols/msn/passport.c @ 68c7c14

Last change on this file since 68c7c14 was 43f205b, checked in by Wilmer van der Gaast <wilmer@…>, at 2005-12-18T01:06:11Z

Crashbug fix in new MSN Passport code (plus a fix to make the 005 reply actually work).

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/* passport.c
2 *
3 * Functions to login to microsoft passport service for Messenger
4 * Copyright (C) 2004 Wouter Paesen <wouter@blue-gate.be>
5 * Copyright (C) 2004 Wilmer van der Gaast <wilmer@gaast.net>
6 *
7 * This program is free software; you can redistribute it and/or modify             
8 * it under the terms of the GNU General Public License version 2                   
9 * as published by the Free Software Foundation                                     
10 *                                                                                   
11 * This program is distributed in the hope that is will be useful,                 
12 * bit WITHOU ANY WARRANTY; without even the implied warranty of                   
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                   
14 * GNU General Public License for more details.                                     
15 *                                                                                   
16 * You should have received a copy of the GNU General Public License               
17 * along with this program; if not, write to the Free Software                     
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA         
19 *
20 */
21
22#include "http_client.h"
23#include "passport.h"
24#include "msn.h"
25#include "bitlbee.h"
26#include <ctype.h>
27#include <errno.h>
28
29#define MSN_BUF_LEN 8192
30
31static char *prd_cached = NULL;
32
33static int passport_get_id_real( gpointer func, gpointer data, char *header );
34static void passport_get_id_ready( struct http_request *req );
35
36static int passport_retrieve_dalogin( gpointer data, gpointer func, char *header );
37static void passport_retrieve_dalogin_ready( struct http_request *req );
38
39static char *passport_create_header( char *cookie, char *email, char *pwd );
40static void destroy_reply( struct passport_reply *rep );
41
42int passport_get_id( gpointer func, gpointer data, char *username, char *password, char *cookie )
43{
44        char *header = passport_create_header( cookie, username, password );
45       
46        if( prd_cached == NULL )
47                return passport_retrieve_dalogin( func, data, header );
48        else
49                return passport_get_id_real( func, data, header );
50}
51
52static int passport_get_id_real( gpointer func, gpointer data, char *header )
53{
54        struct passport_reply *rep;
55        char *server, *dummy, *reqs;
56        struct http_request *req;
57       
58        rep = g_new0( struct passport_reply, 1 );
59        rep->data = data;
60        rep->func = func;
61       
62        server = g_strdup( prd_cached );
63        dummy = strchr( server, '/' );
64       
65        if( dummy == NULL )
66        {
67                destroy_reply( rep );
68                return( 0 );
69        }
70       
71        reqs = g_malloc( strlen( header ) + strlen( dummy ) + 128 );
72        sprintf( reqs, "GET %s HTTP/1.0\r\n%s\r\n\r\n", dummy, header );
73       
74        *dummy = 0;
75        req = http_dorequest( server, 443, 1, reqs, passport_get_id_ready, rep );
76       
77        g_free( server );
78        g_free( reqs );
79       
80        if( req == NULL )
81                destroy_reply( rep );
82       
83        return( req != NULL );
84}
85
86static void passport_get_id_ready( struct http_request *req )
87{
88        struct passport_reply *rep = req->data;
89       
90        if( !g_slist_find( msn_connections, rep->data ) || !req->finished || !req->reply_headers )
91        {
92                destroy_reply( rep );
93                return;
94        }
95       
96        if( req->status_code == 200 )
97        {
98                char *dummy;
99               
100                if( ( dummy = strstr( req->reply_headers, "from-PP='" ) ) )
101                {
102                        char *responseend;
103                       
104                        dummy += strlen( "from-PP='" );
105                        responseend = strchr( dummy, '\'' );
106                        if( responseend )
107                                *responseend = 0;
108                       
109                        rep->result = g_strdup( dummy );
110                }
111        }
112       
113        rep->func( rep );
114        destroy_reply( rep );
115}
116
117static char *passport_create_header( char *cookie, char *email, char *pwd )
118{
119        char *buffer = g_new0( char, 2048 );
120        char *currenttoken;
121        char *email_enc, *pwd_enc;
122       
123        email_enc = g_new0( char, strlen( email ) * 3 + 1 );
124        strcpy( email_enc, email );
125        http_encode( email_enc );
126       
127        pwd_enc = g_new0( char, strlen( pwd ) * 3 + 1 );
128        strcpy( pwd_enc, pwd );
129        http_encode( pwd_enc );
130       
131        currenttoken = strstr( cookie, "lc=" );
132        if( currenttoken == NULL )
133                return( NULL );
134       
135        g_snprintf( buffer, 2048,
136                    "Authorization: Passport1.4 OrgVerb=GET,"
137                    "OrgURL=http%%3A%%2F%%2Fmessenger%%2Emsn%%2Ecom,"
138                    "sign-in=%s,pwd=%s,%s", email_enc, pwd_enc,
139                    currenttoken );
140       
141        g_free( email_enc );
142        g_free( pwd_enc );
143       
144        return( buffer );
145}
146
147#define PPR_REQUEST "GET /rdr/pprdr.asp HTTP/1.0\r\n\r\n"
148static int passport_retrieve_dalogin( gpointer func, gpointer data, char *header )
149{
150        struct passport_reply *rep = g_new0( struct passport_reply, 1 );
151        struct http_request *req;
152       
153        rep->data = data;
154        rep->func = func;
155        rep->header = header;
156       
157        req = http_dorequest( "nexus.passport.com", 443, 1, PPR_REQUEST, passport_retrieve_dalogin_ready, rep );
158       
159        if( !req )
160                destroy_reply( rep );
161       
162        return( req != NULL );
163}
164
165static void passport_retrieve_dalogin_ready( struct http_request *req )
166{
167        struct passport_reply *rep = req->data;
168        char *dalogin;
169        char *urlend;
170       
171        if( !g_slist_find( msn_connections, rep->data ) || !req->finished || !req->reply_headers )
172        {
173                destroy_reply( rep );
174                return;
175        }
176       
177        dalogin = strstr( req->reply_headers, "DALogin=" );     
178       
179        if( !dalogin )
180                goto failure;
181       
182        dalogin += strlen( "DALogin=" );
183        urlend = strchr( dalogin, ',' );
184        if( urlend )
185                *urlend = 0;
186       
187        /* strip the http(s):// part from the url */
188        urlend = strstr( urlend, "://" );
189        if( urlend )
190                dalogin = urlend + strlen( "://" );
191       
192        if( prd_cached == NULL )
193                prd_cached = g_strdup( dalogin );
194       
195        if( passport_get_id_real( rep->func, rep->data, rep->header ) )
196        {
197                destroy_reply( rep );
198                return;
199        }
200       
201failure:       
202        rep->func( rep );
203        destroy_reply( rep );
204}
205
206static void destroy_reply( struct passport_reply *rep )
207{
208        g_free( rep->result );
209        g_free( rep->header );
210        g_free( rep );
211}
Note: See TracBrowser for help on using the repository browser.