Changeset devel,468

Show
Ignore:
Timestamp:
2009-10-03T19:27:50Z (10 months ago)
Author:
Wilmer van der Gaast <wilmer@…>
branch-nick:
devel
revision id:
wilmer@gaast.net-20091003192750-78vm8ju2uxl511tt
Message:

Yahoo! can log in again. This code still needs major cleanups, use it only
if you're very desparate.

Location:
devel/protocols/yahoo
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • devel/protocols/yahoo/libyahoo2.c

    r85.1.2 r468  
    8989 
    9090#include "base64.h" 
     91#include "http_client.h" 
     92 
     93static void yahoo_process_auth_response(struct http_request *req); 
     94 
     95/* What's this used for actually? */ 
     96static void _yahoo_http_connected(int id, int fd, int error, void *data); 
    9197 
    9298#ifdef USE_STRUCT_CALLBACKS 
     
    169175        YAHOO_SERVICE_GOTGROUPRENAME, /* < 1, 36(old), 37(new) */ 
    170176        YAHOO_SERVICE_SYSMESSAGE = 0x14, 
     177        YAHOO_SERVICE_SKINNAME = 0x15, 
    171178        YAHOO_SERVICE_PASSTHROUGH2 = 0x16, 
    172179        YAHOO_SERVICE_CONFINVITE = 0x18, 
     
    192199        YAHOO_SERVICE_LIST, 
    193200        YAHOO_SERVICE_AUTH = 0x57, 
     201        YAHOO_SERVICE_AUTHBUDDY = 0x6d, 
    194202        YAHOO_SERVICE_ADDBUDDY = 0x83, 
    195203        YAHOO_SERVICE_REMBUDDY, 
     
    197205        YAHOO_SERVICE_REJECTCONTACT, 
    198206        YAHOO_SERVICE_GROUPRENAME = 0x89, /* > 1, 65(new), 66(0), 67(old) */ 
     207        YAHOO_SERVICE_Y7_PING = 0x8A, /* 0 - id and that's it?? */ 
    199208        YAHOO_SERVICE_CHATONLINE = 0x96, /* > 109(id), 1, 6(abcde) < 0,1*/ 
    200209        YAHOO_SERVICE_CHATGOTO, 
     
    202211        YAHOO_SERVICE_CHATLEAVE, 
    203212        YAHOO_SERVICE_CHATEXIT = 0x9b, 
     213        YAHOO_SERVICE_CHATADDINVITE = 0x9d, 
    204214        YAHOO_SERVICE_CHATLOGOUT = 0xa0, 
    205215        YAHOO_SERVICE_CHATPING, 
    206216        YAHOO_SERVICE_COMMENT = 0xa8, 
    207         YAHOO_SERVICE_STEALTH = 0xb9, 
     217        YAHOO_SERVICE_GAME_INVITE = 0xb7, 
     218        YAHOO_SERVICE_STEALTH_PERM = 0xb9, 
     219        YAHOO_SERVICE_STEALTH_SESSION = 0xba, 
     220        YAHOO_SERVICE_AVATAR = 0xbc, 
    208221        YAHOO_SERVICE_PICTURE_CHECKSUM = 0xbd, 
    209222        YAHOO_SERVICE_PICTURE = 0xbe, 
    210223        YAHOO_SERVICE_PICTURE_UPDATE = 0xc1, 
    211         YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2 
     224        YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2, 
     225        YAHOO_SERVICE_YAB_UPDATE = 0xc4, 
     226        YAHOO_SERVICE_Y6_VISIBLE_TOGGLE = 0xc5, /* YMSG13, key 13: 2 = invisible, 1 = visible */ 
     227        YAHOO_SERVICE_Y6_STATUS_UPDATE = 0xc6,  /* YMSG13 */ 
     228        YAHOO_SERVICE_PICTURE_STATUS = 0xc7,    /* YMSG13, key 213: 0 = none, 1 = avatar, 2 = picture */ 
     229        YAHOO_SERVICE_VERIFY_ID_EXISTS = 0xc8, 
     230        YAHOO_SERVICE_AUDIBLE = 0xd0, 
     231        YAHOO_SERVICE_Y7_PHOTO_SHARING = 0xd2, 
     232        YAHOO_SERVICE_Y7_CONTACT_DETAILS = 0xd3,/* YMSG13 */ 
     233        YAHOO_SERVICE_Y7_CHAT_SESSION = 0xd4, 
     234        YAHOO_SERVICE_Y7_AUTHORIZATION = 0xd6,  /* YMSG13 */ 
     235        YAHOO_SERVICE_Y7_FILETRANSFER = 0xdc,   /* YMSG13 */ 
     236        YAHOO_SERVICE_Y7_FILETRANSFERINFO,      /* YMSG13 */ 
     237        YAHOO_SERVICE_Y7_FILETRANSFERACCEPT,    /* YMSG13 */ 
     238        YAHOO_SERVICE_Y7_MINGLE = 0xe1, /* YMSG13 */ 
     239        YAHOO_SERVICE_Y7_CHANGE_GROUP = 0xe7, /* YMSG13 */ 
     240        YAHOO_SERVICE_Y8_STATUS = 0xf0,                 /* YMSG15 */ 
     241        YAHOO_SERVICE_Y8_LIST = 0Xf1,                   /* YMSG15 */ 
     242        YAHOO_SERVICE_WEBLOGIN = 0x0226, 
     243        YAHOO_SERVICE_SMS_MSG = 0x02ea 
    212244}; 
    213245 
     
    733765 
    734766        memcpy(data + pos, "YMSG", 4); pos += 4; 
    735         pos += yahoo_put16(data + pos, 0x000c); 
     767        pos += yahoo_put16(data + pos, YAHOO_PROTO_VER); 
    736768        pos += yahoo_put16(data + pos, 0x0000); 
    737769        pos += yahoo_put16(data + pos, pktlen + extra_pad); 
     
    14801512} 
    14811513 
     1514static void yahoo_process_buddy_list(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 
     1515{ 
     1516        struct yahoo_data *yd = yid->yd; 
     1517        YList *l; 
     1518        int last_packet = 0; 
     1519        char *cur_group = NULL; 
     1520        struct yahoo_buddy *newbud = NULL; 
     1521 
     1522        /* we could be getting multiple packets here */ 
     1523        for (l = pkt->hash; l; l = l->next) { 
     1524                struct yahoo_pair *pair = l->data; 
     1525 
     1526                switch(pair->key) { 
     1527                case 300: 
     1528                case 301: 
     1529                case 302: 
     1530                case 303: 
     1531                        if ( 315 == atoi(pair->value) ) 
     1532                                last_packet = 1; 
     1533                        break; 
     1534                case 65: 
     1535                        cur_group = strdup(pair->value); 
     1536                        break; 
     1537                case 7: 
     1538                        newbud = y_new0(struct yahoo_buddy, 1); 
     1539                        newbud->id = strdup(pair->value); 
     1540                        if(cur_group) 
     1541                                newbud->group = strdup(cur_group); 
     1542                        else { 
     1543                                struct yahoo_buddy *lastbud = (struct yahoo_buddy *)y_list_nth( 
     1544                                                                yd->buddies, y_list_length(yd->buddies)-1)->data; 
     1545                                newbud->group = strdup(lastbud->group); 
     1546                        } 
     1547 
     1548                        yd->buddies = y_list_append(yd->buddies, newbud); 
     1549 
     1550                        break; 
     1551                } 
     1552        } 
     1553 
     1554        /* we could be getting multiple packets here */ 
     1555        if (last_packet) 
     1556                return; 
     1557 
     1558        YAHOO_CALLBACK(ext_yahoo_got_buddies)(yd->client_id, yd->buddies); 
     1559 
     1560 
     1561        /*** We login at the very end of the packet communication */ 
     1562        if (!yd->logged_in) { 
     1563                yd->logged_in = TRUE; 
     1564                if(yd->current_status < 0) 
     1565                        yd->current_status = yd->initial_status; 
     1566                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_OK, NULL); 
     1567        } 
     1568} 
     1569 
    14821570static void yahoo_process_list(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 
    14831571{ 
     
    15491637                        }  
    15501638 
    1551                         if(yd->cookie_y && yd->cookie_t && yd->cookie_c) 
     1639                        // if(yd->cookie_y && yd->cookie_t && yd->cookie_c) 
     1640                        if(yd->cookie_y && yd->cookie_t) 
    15521641                                YAHOO_CALLBACK(ext_yahoo_got_cookies)(yd->client_id); 
    15531642 
     
    22262315} 
    22272316 
     2317static void yahoo_process_auth_0x10(struct yahoo_input_data *yid, const char *seed, const char *sn) 
     2318{ 
     2319        char *url; 
     2320 
     2321        yid->yd->login_cookie = strdup(seed); 
     2322 
     2323        url = g_strdup_printf( 
     2324                "https://login.yahoo.com/config/pwtoken_get?" 
     2325                "src=ymsgr&ts=&login=%s&passwd=%s&chal=%s", 
     2326                yid->yd->user, yid->yd->password, seed); 
     2327 
     2328        http_dorequest_url(url, yahoo_process_auth_response, yid); 
     2329         
     2330        g_free(url); 
     2331} 
     2332 
    22282333static void yahoo_process_auth(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 
    22292334{ 
     
    22532358                case 1: 
    22542359                        yahoo_process_auth_0x0b(yid, seed, sn); 
     2360                        break; 
     2361                case 2: 
     2362                        /* HTTPS */ 
     2363                        yahoo_process_auth_0x10(yid, seed, sn); 
    22552364                        break; 
    22562365                default: 
     
    26612770        case YAHOO_SERVICE_IDACT: 
    26622771        case YAHOO_SERVICE_IDDEACT: 
     2772        case YAHOO_SERVICE_Y6_STATUS_UPDATE: 
     2773        case YAHOO_SERVICE_Y8_STATUS: 
    26632774                yahoo_process_status(yid, pkt); 
    26642775                break; 
     
    27562867                yahoo_process_picture_upload(yid, pkt); 
    27572868                break;   
     2869        case YAHOO_SERVICE_Y8_LIST:     /* Buddy List */ 
     2870                yahoo_process_buddy_list(yid, pkt); 
    27582871        default: 
    27592872                WARNING(("unknown service 0x%02x", pkt->service)); 
     
    35323645} 
    35333646 
     3647//#define LOG(x...) printf x 
     3648 
     3649static void yahoo_process_auth_response(struct http_request *req) 
     3650{ 
     3651        char *line_end; 
     3652        char *token; 
     3653        char *cookie; 
     3654 
     3655        int error_code = 0; 
     3656        int is_ymsgr = 0; 
     3657 
     3658        struct yahoo_data *yd = NULL; 
     3659        struct yahoo_input_data *yid = req->data; 
     3660 
     3661        unsigned char crypt_hash[25]; 
     3662 
     3663        md5_byte_t result[16]; 
     3664        md5_state_t ctx; 
     3665 
     3666        struct yahoo_packet *packet =NULL; 
     3667 
     3668        token = req->reply_body; 
     3669        line_end = strstr(token, "\r\n"); 
     3670 
     3671        if (line_end) { 
     3672                *line_end = '\0'; 
     3673 
     3674                line_end+=2; 
     3675        } 
     3676 
     3677        error_code = atoi((char *)token); 
     3678 
     3679        switch(error_code) { 
     3680                case 0: 
     3681                        /* successful */ 
     3682                        LOG(("successful\n")); 
     3683                        break; 
     3684                case 1212: 
     3685                        /* Incorrect ID or password */ 
     3686                        LOG(("Incorrect ID or password\n")); 
     3687 
     3688                        return; 
     3689                case 1213: 
     3690                        /* Security lock from too many failed login attempts */ 
     3691                        LOG(("Security lock from too many failed login attempts\n")); 
     3692 
     3693                        return; 
     3694 
     3695                case 1214: 
     3696                        /* Security lock */ 
     3697                        LOG(("Security lock\n")); 
     3698 
     3699                        return; 
     3700 
     3701                case 1235: 
     3702                        /* User ID not taken yet */ 
     3703                        LOG(("User ID not taken yet\n")); 
     3704 
     3705                        return; 
     3706 
     3707                case 1216: 
     3708                        /* Seems to be a lock, but shows the same generic User ID/Password failure */ 
     3709                        LOG(("Seems to be a lock, but shows the same generic User ID/Password failure\n")); 
     3710 
     3711                        return; 
     3712                case 100: 
     3713                        /* Username and password cannot be blank */ 
     3714                        LOG(("Username and password cannot be blank\n")); 
     3715 
     3716                        return; 
     3717                default: 
     3718                        /* Unknown error code */ 
     3719                        LOG(("Unknown Error\n")); 
     3720 
     3721                        return; 
     3722        } 
     3723 
     3724        if ( !strncmp(line_end, "ymsgr=", 6) ) { 
     3725                is_ymsgr = 1; 
     3726        } 
     3727        else if ( strncmp(line_end, "crumb=", 6) ) { 
     3728                LOG(("Oops! There was no ymsgr=. Where do I get my token from now :(")); 
     3729                LOG(("I got this:\n\n%s\n",line_end)); 
     3730                return; 
     3731                /* Error */ 
     3732        } 
     3733 
     3734        token = line_end+6; 
     3735 
     3736        line_end = strstr(token, "\r\n"); 
     3737 
     3738        if(line_end) { 
     3739                *line_end = '\0'; 
     3740                line_end+=2; 
     3741        } 
     3742 
     3743        /* Go for the crumb */ 
     3744        if(is_ymsgr) { 
     3745                char *url; 
     3746 
     3747                url = g_strdup_printf( 
     3748                        "https://login.yahoo.com/config/pwtoken_login?" 
     3749                        "src=ymsgr&ts=&token=%s", token); 
     3750                 
     3751                http_dorequest_url(url, yahoo_process_auth_response, yid); 
     3752                g_free(url); 
     3753 
     3754                return; 
     3755        } 
     3756 
     3757        /* token is actually crumb */ 
     3758 
     3759        if(!line_end) { 
     3760                /* We did not get our cookies. Cry. */ 
     3761        } 
     3762 
     3763        cookie = strstr(req->reply_headers, "Set-Cookie: Y="); 
     3764 
     3765        if(!cookie) { 
     3766                /* Cry. */ 
     3767                LOG(("NO Y Cookie!")); 
     3768                return; 
     3769        } 
     3770 
     3771        cookie+=14; 
     3772 
     3773        line_end = strstr(cookie, "\r\n"); 
     3774        *line_end = '\0'; 
     3775 
     3776        LOG(("Cookie length: %d", strlen(cookie))); 
     3777 
     3778        yid->yd->cookie_y = strdup(cookie); 
     3779        *line_end = ';'; 
     3780 
     3781        cookie = strstr(req->reply_headers, "Set-Cookie: T="); 
     3782        if(!cookie) { 
     3783                LOG(("NO T Cookie!")); 
     3784                /* Cry. */ 
     3785                return; 
     3786        } 
     3787 
     3788        cookie+=14; 
     3789 
     3790        line_end = strstr(cookie, "\r\n"); 
     3791        *line_end = '\0'; 
     3792 
     3793        yid->yd->cookie_t = strdup(cookie); 
     3794 
     3795        LOG(("My Cookies ::\n Y: %s\nT: %s\n\n", yid->yd->cookie_y, yid->yd->cookie_t)); 
     3796 
     3797        md5_init(&ctx); 
     3798        md5_append(&ctx, (md5_byte_t *)token, strlen(token)); 
     3799        md5_append(&ctx, (md5_byte_t *)yid->yd->login_cookie, strlen(yid->yd->login_cookie)); 
     3800        md5_finish(&ctx, result); 
     3801 
     3802        to_y64(crypt_hash, result, 16); 
     3803 
     3804        yd = yid->yd; 
     3805 
     3806        //yid = find_input_by_id_and_type(yd->client_id, YAHOO_CONNECTION_PAGER); 
     3807 
     3808        packet = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->initial_status, yd->session_id); 
     3809        yahoo_packet_hash(packet, 1, yd->user); 
     3810        yahoo_packet_hash(packet, 0, yd->user); 
     3811        yahoo_packet_hash(packet, 277, yd->cookie_y); 
     3812        yahoo_packet_hash(packet, 278, yd->cookie_t); 
     3813        yahoo_packet_hash(packet, 307, crypt_hash); 
     3814        yahoo_packet_hash(packet, 244, "2097087");      /* Rekkanoryo says this is the build number */ 
     3815        yahoo_packet_hash(packet, 2, yd->user); 
     3816        yahoo_packet_hash(packet, 2, "1"); 
     3817        yahoo_packet_hash(packet, 98, "us");            /* TODO Put country code */ 
     3818        yahoo_packet_hash(packet, 135, "9.0.0.1389"); 
     3819                 
     3820        yahoo_send_packet(yid, packet, 0); 
     3821 
     3822        yahoo_packet_free(packet); 
     3823 
     3824        /* We don't need this anymore */ 
     3825        free(yd->login_cookie); 
     3826        yd->login_cookie = NULL; 
     3827} 
     3828 
     3829 
    35343830static void (*yahoo_process_connection[])(struct yahoo_input_data *, int over) = { 
    35353831        yahoo_process_pager_connection, 
     
    35393835        yahoo_process_webcam_connection, 
    35403836        yahoo_process_chatcat_connection, 
    3541         yahoo_process_search_connection 
     3837        yahoo_process_search_connection, 
    35423838}; 
    35433839 
     
    35573853        } while(len == -1 && errno == EINTR); 
    35583854 
    3559         if(len == -1 && errno == EAGAIN)        /* we'll try again later */ 
     3855        if(len == -1 && (errno == EAGAIN||errno == EINTR))      /* we'll try again later */ 
    35603856                return 1; 
    35613857 
     
    41464442                return; 
    41474443 
    4148         pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH, YAHOO_STATUS_AVAILABLE, yd->session_id); 
     4444        pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH_PERM, YAHOO_STATUS_AVAILABLE, yd->session_id); 
    41494445        yahoo_packet_hash(pkt, 1, yd->user); 
    41504446        yahoo_packet_hash(pkt, 7, who); 
  • devel/protocols/yahoo/yahoo2_types.h

    r220 r468  
    8585}; 
    8686 
    87 #define YAHOO_PROTO_VER 0x000b 
     87#define YAHOO_PROTO_VER 0x0010 
    8888 
    8989/* Yahoo style/color directives */ 
     
    115115        YAHOO_CONNECTION_WEBCAM, 
    116116        YAHOO_CONNECTION_CHATCAT, 
    117         YAHOO_CONNECTION_SEARCH 
     117        YAHOO_CONNECTION_SEARCH, 
     118        YAHOO_CONNECTION_AUTH, 
    118119}; 
    119120