Changeset 4fefb77


Ignore:
Timestamp:
2009-10-03T19:27:50Z (15 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
c3e349e
Parents:
0182773
Message:

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

Location:
protocols/yahoo
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • protocols/yahoo/libyahoo2.c

    r0182773 r4fefb77  
    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);
  • protocols/yahoo/yahoo2_types.h

    r0182773 r4fefb77  
    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
Note: See TracChangeset for help on using the changeset viewer.