source: protocols/msn/passport.c @ 7e0af53

Last change on this file since 7e0af53 was a3265629, checked in by Wilmer van der Gaast <wilmer@…>, at 2006-10-15T18:44:47Z

Fixing early free(). Memory management in the passport code is getting too
messy, really... :-(

  • Property mode set to 100644
File size: 6.1 KB
RevLine 
[b7d3cc34]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
[ad8b8a3]22#include "http_client.h"
[b7d3cc34]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
[ad8b8a3]33static int passport_get_id_real( gpointer func, gpointer data, char *header );
34static void passport_get_id_ready( struct http_request *req );
35
[b7d3cc34]36static int passport_retrieve_dalogin( gpointer data, gpointer func, char *header );
[ad8b8a3]37static void passport_retrieve_dalogin_ready( struct http_request *req );
[b7d3cc34]38
[ad8b8a3]39static char *passport_create_header( char *cookie, char *email, char *pwd );
40static void destroy_reply( struct passport_reply *rep );
[b7d3cc34]41
[ad8b8a3]42int passport_get_id( gpointer func, gpointer data, char *username, char *password, char *cookie )
[b7d3cc34]43{
44        char *header = passport_create_header( cookie, username, password );
45       
[ad8b8a3]46        if( prd_cached == NULL )
47                return passport_retrieve_dalogin( func, data, header );
[b7d3cc34]48        else
[ad8b8a3]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;
[695e392]61        rep->header = header;
[ad8b8a3]62       
63        server = g_strdup( prd_cached );
64        dummy = strchr( server, '/' );
65       
66        if( dummy == NULL )
[b7d3cc34]67        {
[ad8b8a3]68                destroy_reply( rep );
69                return( 0 );
[b7d3cc34]70        }
[ad8b8a3]71       
[a2582c8]72        reqs = g_strdup_printf( "GET %s HTTP/1.0\r\n%s\r\n\r\n", dummy, header );
[ad8b8a3]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 );
[b7d3cc34]84}
85
[ad8b8a3]86static void passport_get_id_ready( struct http_request *req )
87{
88        struct passport_reply *rep = req->data;
89       
[a2582c8]90        if( !g_slist_find( msn_connections, rep->data ) )
[ad8b8a3]91        {
92                destroy_reply( rep );
93                return;
94        }
95       
[a2582c8]96        if( req->finished && req->reply_headers && req->status_code == 200 )
[ad8b8a3]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                }
[a2582c8]111                else
112                {
113                        rep->error_string = g_strdup( "Could not parse Passport server response" );
114                }
115        }
116        else
117        {
118                rep->error_string = g_strdup_printf( "HTTP error: %s",
119                                      req->status_string ? req->status_string : "Unknown error" );
[ad8b8a3]120        }
121       
122        rep->func( rep );
123        destroy_reply( rep );
124}
[b7d3cc34]125
[ad8b8a3]126static char *passport_create_header( char *cookie, char *email, char *pwd )
[b7d3cc34]127{
[695e392]128        char *buffer;
[b7d3cc34]129        char *currenttoken;
130        char *email_enc, *pwd_enc;
131       
[695e392]132        currenttoken = strstr( cookie, "lc=" );
133        if( currenttoken == NULL )
134                return NULL;
135       
[b7d3cc34]136        email_enc = g_new0( char, strlen( email ) * 3 + 1 );
137        strcpy( email_enc, email );
138        http_encode( email_enc );
139       
140        pwd_enc = g_new0( char, strlen( pwd ) * 3 + 1 );
141        strcpy( pwd_enc, pwd );
142        http_encode( pwd_enc );
143       
[695e392]144        buffer = g_strdup_printf( "Authorization: Passport1.4 OrgVerb=GET,"
145                                  "OrgURL=http%%3A%%2F%%2Fmessenger%%2Emsn%%2Ecom,"
146                                  "sign-in=%s,pwd=%s,%s", email_enc, pwd_enc,
147                                  currenttoken );
[b7d3cc34]148       
149        g_free( email_enc );
150        g_free( pwd_enc );
151       
[695e392]152        return buffer;
[b7d3cc34]153}
154
[ad8b8a3]155static int passport_retrieve_dalogin( gpointer func, gpointer data, char *header )
[b7d3cc34]156{
157        struct passport_reply *rep = g_new0( struct passport_reply, 1 );
[ad8b8a3]158        struct http_request *req;
[b7d3cc34]159       
160        rep->data = data;
161        rep->func = func;
162        rep->header = header;
163       
[db28304]164        req = http_dorequest_url( "https://nexus.passport.com/rdr/pprdr.asp", passport_retrieve_dalogin_ready, rep );
[b7d3cc34]165       
[ad8b8a3]166        if( !req )
[b7d3cc34]167                destroy_reply( rep );
168       
[ad8b8a3]169        return( req != NULL );
[b7d3cc34]170}
171
[ad8b8a3]172static void passport_retrieve_dalogin_ready( struct http_request *req )
[b7d3cc34]173{
[ad8b8a3]174        struct passport_reply *rep = req->data;
175        char *dalogin;
176        char *urlend;
[b7d3cc34]177       
[a2582c8]178        if( !g_slist_find( msn_connections, rep->data ) )
[b7d3cc34]179        {
180                destroy_reply( rep );
181                return;
182        }
183       
[a2582c8]184        if( !req->finished || !req->reply_headers || req->status_code != 200 )
185        {
[db28304]186                rep->error_string = g_strdup_printf( "HTTP error while fetching DALogin: %s",
[a2582c8]187                                        req->status_string ? req->status_string : "Unknown error" );
188                goto failure;
189        }
190       
[ad8b8a3]191        dalogin = strstr( req->reply_headers, "DALogin=" );     
[b7d3cc34]192       
[ad8b8a3]193        if( !dalogin )
[a2582c8]194        {
195                rep->error_string = g_strdup( "Parse error while fetching DALogin" );
[b7d3cc34]196                goto failure;
[a2582c8]197        }
[b7d3cc34]198       
[ad8b8a3]199        dalogin += strlen( "DALogin=" );
200        urlend = strchr( dalogin, ',' );
201        if( urlend )
202                *urlend = 0;
[b7d3cc34]203       
[ad8b8a3]204        /* strip the http(s):// part from the url */
205        urlend = strstr( urlend, "://" );
206        if( urlend )
207                dalogin = urlend + strlen( "://" );
[b7d3cc34]208       
[ad8b8a3]209        if( prd_cached == NULL )
210                prd_cached = g_strdup( dalogin );
[b7d3cc34]211       
[ad8b8a3]212        if( passport_get_id_real( rep->func, rep->data, rep->header ) )
[b7d3cc34]213        {
[a3265629]214                rep->header = NULL;
[b7d3cc34]215                destroy_reply( rep );
216                return;
217        }
218       
[ad8b8a3]219failure:       
[b7d3cc34]220        rep->func( rep );
221        destroy_reply( rep );
222}
223
224static void destroy_reply( struct passport_reply *rep )
225{
[ad8b8a3]226        g_free( rep->result );
227        g_free( rep->header );
[a2582c8]228        g_free( rep->error_string );
[ad8b8a3]229        g_free( rep );
[b7d3cc34]230}
Note: See TracBrowser for help on using the repository browser.