Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/msn/passport.c

    rad8b8a3 rb7d3cc34  
    2020 */
    2121
    22 #include "http_client.h"
     22#include "ssl_client.h"
    2323#include "passport.h"
    2424#include "msn.h"
     
    3131static char *prd_cached = NULL;
    3232
    33 static int passport_get_id_real( gpointer func, gpointer data, char *header );
    34 static void passport_get_id_ready( struct http_request *req );
    35 
     33static char *passport_create_header( char *reply, char *email, char *pwd );
    3634static int passport_retrieve_dalogin( gpointer data, gpointer func, char *header );
    37 static void passport_retrieve_dalogin_ready( struct http_request *req );
    38 
    39 static char *passport_create_header( char *cookie, char *email, char *pwd );
     35static void passport_retrieve_dalogin_connected( gpointer data, void *ssl, GaimInputCondition cond );
     36static int passport_get_id_from( gpointer data, gpointer func, char *header_i, char *url );
     37static void passport_get_id_connected( gpointer data, void *ssl, GaimInputCondition cond );
    4038static void destroy_reply( struct passport_reply *rep );
    4139
    42 int passport_get_id( gpointer func, gpointer data, char *username, char *password, char *cookie )
     40
     41int passport_get_id( gpointer data, char *username, char *password, char *cookie, gpointer func )
    4342{
    4443        char *header = passport_create_header( cookie, username, password );
    4544       
    46         if( prd_cached == NULL )
    47                 return passport_retrieve_dalogin( func, data, header );
     45        if( prd_cached )
     46        {
     47                int st;
     48               
     49                st = passport_get_id_from( data, func, header, prd_cached );
     50                g_free( header );
     51                return( st );
     52        }
    4853        else
    49                 return passport_get_id_real( func, data, header );
    50 }
    51 
    52 static 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 );
     54        {
     55                return( passport_retrieve_dalogin( data, func, header ) );
     56        }
     57}
     58
     59
     60static char *passport_create_header( char *reply, char *email, char *pwd )
     61{
     62        char *buffer = g_new0( char, 2048 );
     63        char *currenttoken;
     64        char *email_enc, *pwd_enc;
     65       
     66        email_enc = g_new0( char, strlen( email ) * 3 + 1 );
     67        strcpy( email_enc, email );
     68        http_encode( email_enc );
     69       
     70        pwd_enc = g_new0( char, strlen( pwd ) * 3 + 1 );
     71        strcpy( pwd_enc, pwd );
     72        http_encode( pwd_enc );
     73       
     74        currenttoken = strstr( reply, "lc=" );
     75        if( currenttoken == NULL )
     76                return( NULL );
     77       
     78        g_snprintf( buffer, 2048,
     79                    "Authorization: Passport1.4 OrgVerb=GET,"
     80                    "OrgURL=http%%3A%%2F%%2Fmessenger%%2Emsn%%2Ecom,"
     81                    "sign-in=%s,pwd=%s,%s", email_enc, pwd_enc,
     82                    currenttoken );
     83       
     84        g_free( email_enc );
     85        g_free( pwd_enc );
     86       
     87        return( buffer );
     88}
     89
     90
     91static int passport_retrieve_dalogin( gpointer data, gpointer func, char *header )
     92{
     93        struct passport_reply *rep = g_new0( struct passport_reply, 1 );
     94        void *ssl;
     95       
    5996        rep->data = data;
    6097        rep->func = func;
    61        
    62         server = g_strdup( prd_cached );
     98        rep->header = header;
     99       
     100        ssl = ssl_connect( "nexus.passport.com", 443, passport_retrieve_dalogin_connected, rep );
     101       
     102        if( !ssl )
     103                destroy_reply( rep );
     104       
     105        return( ssl != NULL );
     106}
     107
     108#define PPR_BUFFERSIZE 2048
     109#define PPR_REQUEST "GET /rdr/pprdr.asp HTTP/1.0\r\n\r\n"
     110static void passport_retrieve_dalogin_connected( gpointer data, void *ssl, GaimInputCondition cond )
     111{
     112        int ret;
     113        char buffer[PPR_BUFFERSIZE+1];
     114        struct passport_reply *rep = data;
     115       
     116        if( !g_slist_find( msn_connections, rep->data ) )
     117        {
     118                if( ssl ) ssl_disconnect( ssl );
     119                destroy_reply( rep );
     120                return;
     121        }
     122       
     123        if( !ssl )
     124        {
     125                rep->func( rep );
     126                destroy_reply( rep );
     127                return;
     128        }
     129       
     130        ssl_write( ssl, PPR_REQUEST, strlen( PPR_REQUEST ) );
     131       
     132        if( ( ret = ssl_read( ssl, buffer, PPR_BUFFERSIZE ) ) <= 0 )
     133        {
     134                goto failure;
     135        }
     136
     137        {
     138                char *dalogin = strstr( buffer, "DALogin=" );
     139                char *urlend;
     140               
     141                if( !dalogin )
     142                        goto failure;
     143               
     144                dalogin += strlen( "DALogin=" );
     145                urlend = strchr( dalogin, ',' );
     146                if( urlend )
     147                        *urlend = 0;
     148               
     149                /* strip the http(s):// part from the url */
     150                urlend = strstr( urlend, "://" );
     151                if( urlend )
     152                        dalogin = urlend + strlen( "://" );
     153               
     154                if( prd_cached == NULL )
     155                        prd_cached = g_strdup( dalogin );
     156        }
     157       
     158        if( passport_get_id_from( rep->data, rep->func, rep->header, prd_cached ) )
     159        {
     160                ssl_disconnect( ssl );
     161                destroy_reply( rep );
     162                return;
     163        }
     164       
     165failure:       
     166        ssl_disconnect( ssl );
     167        rep->func( rep );
     168        destroy_reply( rep );
     169}
     170
     171
     172static int passport_get_id_from( gpointer data, gpointer func, char *header_i, char *url )
     173{
     174        struct passport_reply *rep = g_new0( struct passport_reply, 1 );
     175        char server[512], *dummy;
     176        void *ssl;
     177       
     178        rep->data = data;
     179        rep->func = func;
     180        rep->redirects = 4;
     181       
     182        strncpy( server, url, 512 );
    63183        dummy = strchr( server, '/' );
    64        
     184        if( dummy )
     185                *dummy = 0;
     186       
     187        ssl = ssl_connect( server, 443, passport_get_id_connected, rep );
     188       
     189        if( ssl )
     190        {
     191                rep->header = g_strdup( header_i );
     192                rep->url = g_strdup( url );
     193        }
     194        else
     195        {
     196                destroy_reply( rep );
     197        }
     198       
     199        return( ssl != NULL );
     200}
     201
     202#define PPG_BUFFERSIZE 4096
     203static void passport_get_id_connected( gpointer data, void *ssl, GaimInputCondition cond )
     204{
     205        struct passport_reply *rep = data;
     206        char server[512], buffer[PPG_BUFFERSIZE+1], *dummy;
     207        int ret;
     208       
     209        if( !g_slist_find( msn_connections, rep->data ) )
     210        {
     211                if( ssl ) ssl_disconnect( ssl );
     212                destroy_reply( rep );
     213                return;
     214        }
     215       
     216        if( !ssl )
     217        {
     218                rep->func( rep );
     219                destroy_reply( rep );
     220                return;
     221        }
     222       
     223        memset( buffer, 0, PPG_BUFFERSIZE + 1 );
     224       
     225        strncpy( server, rep->url, 512 );
     226        dummy = strchr( server, '/' );
    65227        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 
    86 static 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 ) )
    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='" ) ) )
     228                goto end;
     229       
     230        g_snprintf( buffer, PPG_BUFFERSIZE - 1, "GET %s HTTP/1.0\r\n"
     231                    "%s\r\n\r\n", dummy, rep->header );
     232       
     233        ssl_write( ssl, buffer, strlen( buffer ) );
     234        memset( buffer, 0, PPG_BUFFERSIZE + 1 );
     235       
     236        {
     237                char *buffer2 = buffer;
     238               
     239                while( ( ( ret = ssl_read( ssl, buffer2, 512 ) ) > 0 ) &&
     240                       ( buffer + PPG_BUFFERSIZE - buffer2 - ret - 512 >= 0 ) )
     241                {
     242                        buffer2 += ret;
     243                }
     244        }
     245       
     246        if( *buffer == 0 )
     247                goto end;
     248       
     249        if( ( dummy = strstr( buffer, "Location:" ) ) )
     250        {
     251                char *urlend;
     252               
     253                rep->redirects --;
     254                if( rep->redirects == 0 )
     255                        goto end;
     256               
     257                dummy += strlen( "Location:" );
     258                while( isspace( *dummy ) ) dummy ++;
     259                urlend = dummy;
     260                while( !isspace( *urlend ) ) urlend ++;
     261                *urlend = 0;
     262                if( ( urlend = strstr( dummy, "://" ) ) )
     263                        dummy = urlend + strlen( "://" );
     264               
     265                g_free( rep->url );
     266                rep->url = g_strdup( dummy );
     267               
     268                strncpy( server, dummy, sizeof( server ) - 1 );
     269                dummy = strchr( server, '/' );
     270                if( dummy ) *dummy = 0;
     271               
     272                ssl_disconnect( ssl );
     273               
     274                if( ssl_connect( server, 443, passport_get_id_connected, rep ) )
     275                {
     276                        return;
     277                }
     278                else
     279                {
     280                        rep->func( rep );
     281                        destroy_reply( rep );
     282                        return;
     283                }
     284        }
     285        else if( strstr( buffer, "200 OK" ) )
     286        {
     287                if( ( dummy = strstr( buffer, "from-PP='" ) ) )
    101288                {
    102289                        char *responseend;
     
    111298        }
    112299       
     300end:
     301        ssl_disconnect( ssl );
    113302        rep->func( rep );
    114303        destroy_reply( rep );
    115304}
    116305
    117 static 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"
    148 static 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 
    165 static 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 ) )
    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        
    201 failure:       
    202         rep->func( rep );
    203         destroy_reply( rep );
    204 }
    205306
    206307static void destroy_reply( struct passport_reply *rep )
    207308{
    208         g_free( rep->result );
    209         g_free( rep->header );
    210         g_free( rep );
    211 }
     309        if( rep->result ) g_free( rep->result );
     310        if( rep->url ) g_free( rep->url );
     311        if( rep->header ) g_free( rep->header );
     312        if( rep ) g_free( rep );
     313}
Note: See TracChangeset for help on using the changeset viewer.