Changeset 4e04194 for protocols/yahoo


Ignore:
Timestamp:
2009-11-23T23:00:54Z (15 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
cd741d8
Parents:
b3117f2 (diff), fb51d85 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merging BitlBee 1.2.4+

Location:
protocols/yahoo
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • protocols/yahoo/libyahoo2.c

    rb3117f2 r4e04194  
    9090#include "base64.h"
    9191#include "http_client.h"
    92 
    93 static void yahoo_process_auth_response(struct http_request *req);
    9492
    9593#ifdef USE_STRUCT_CALLBACKS
     
    212210        YAHOO_SERVICE_CHATPING,
    213211        YAHOO_SERVICE_COMMENT = 0xa8,
    214         YAHOO_SERVICE_GAME_INVITE = 0xb7,
    215         YAHOO_SERVICE_STEALTH_PERM = 0xb9,
    216         YAHOO_SERVICE_STEALTH_SESSION = 0xba,
    217         YAHOO_SERVICE_AVATAR = 0xbc,
     212        YAHOO_SERVICE_STEALTH = 0xb9,
    218213        YAHOO_SERVICE_PICTURE_CHECKSUM = 0xbd,
    219214        YAHOO_SERVICE_PICTURE = 0xbe,
    220215        YAHOO_SERVICE_PICTURE_UPDATE = 0xc1,
    221216        YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2,
    222         YAHOO_SERVICE_YAB_UPDATE = 0xc4,
    223         YAHOO_SERVICE_Y6_VISIBLE_TOGGLE = 0xc5, /* YMSG13, key 13: 2 = invisible, 1 = visible */
    224         YAHOO_SERVICE_Y6_STATUS_UPDATE = 0xc6,  /* YMSG13 */
    225         YAHOO_SERVICE_PICTURE_STATUS = 0xc7,    /* YMSG13, key 213: 0 = none, 1 = avatar, 2 = picture */
    226         YAHOO_SERVICE_VERIFY_ID_EXISTS = 0xc8,
    227         YAHOO_SERVICE_AUDIBLE = 0xd0,
    228         YAHOO_SERVICE_Y7_PHOTO_SHARING = 0xd2,
    229         YAHOO_SERVICE_Y7_CONTACT_DETAILS = 0xd3,/* YMSG13 */
    230         YAHOO_SERVICE_Y7_CHAT_SESSION = 0xd4,
    231         YAHOO_SERVICE_Y7_AUTHORIZATION = 0xd6,  /* YMSG13 */
    232         YAHOO_SERVICE_Y7_FILETRANSFER = 0xdc,   /* YMSG13 */
    233         YAHOO_SERVICE_Y7_FILETRANSFERINFO,      /* YMSG13 */
    234         YAHOO_SERVICE_Y7_FILETRANSFERACCEPT,    /* YMSG13 */
    235         YAHOO_SERVICE_Y7_MINGLE = 0xe1, /* YMSG13 */
    236         YAHOO_SERVICE_Y7_CHANGE_GROUP = 0xe7, /* YMSG13 */
    237         YAHOO_SERVICE_Y8_STATUS = 0xf0,                 /* YMSG15 */
    238         YAHOO_SERVICE_Y8_LIST = 0Xf1,                   /* YMSG15 */
    239         YAHOO_SERVICE_WEBLOGIN = 0x0226,
    240         YAHOO_SERVICE_SMS_MSG = 0x02ea
     217        YAHOO_SERVICE_Y6_VISIBILITY=0xc5,
     218        YAHOO_SERVICE_Y6_STATUS_UPDATE=0xc6,
     219        YAHOO_PHOTOSHARE_INIT=0xd2,     
     220        YAHOO_SERVICE_CONTACT_YMSG13=0xd6,
     221        YAHOO_PHOTOSHARE_PREV=0xd7,
     222        YAHOO_PHOTOSHARE_KEY=0xd8,
     223        YAHOO_PHOTOSHARE_TRANS=0xda,
     224        YAHOO_FILE_TRANSFER_INIT_YMSG13=0xdc,
     225        YAHOO_FILE_TRANSFER_GET_YMSG13=0xdd,
     226        YAHOO_FILE_TRANSFER_PUT_YMSG13=0xde,
     227        YAHOO_SERVICE_YMSG15_STATUS=0xf0,
     228        YAHOO_SERVICE_YMSG15_BUDDY_LIST=0xf1,
    241229};
    242230
     
    776764                yahoo_send_data(yid->fd, data, len);
    777765        else
    778         yahoo_add_to_send_queue(yid, data, len);
     766                yahoo_add_to_send_queue(yid, data, len);
    779767        FREE(data);
    780768}
     
    14961484
    14971485                if (u->name != NULL) {
    1498                         if (pkt->service == YAHOO_SERVICE_LOGOFF || u->flags == 0) {
     1486                        if (pkt->service == YAHOO_SERVICE_LOGOFF) { /* || u->flags == 0) { Not in YMSG16 */
    14991487                                YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, u->name, YAHOO_STATUS_OFFLINE, NULL, 1, 0, 0);
    15001488                        } else {
     1489                                /* Key 47 always seems to be 1 for YMSG16 */
     1490                                if(!u->state)
     1491                                        u->away = 0;
     1492                                else
     1493                                        u->away = 1;
     1494
    15011495                                YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, u->name, u->state, u->msg, u->away, u->idle, u->mobile);
    15021496                        }
     
    23132307}
    23142308
     2309struct yahoo_https_auth_data
     2310{
     2311        struct yahoo_input_data *yid;
     2312        char *token;
     2313        char *chal;
     2314};
     2315
     2316static void yahoo_https_auth_token_init(struct yahoo_https_auth_data *had);
     2317static void yahoo_https_auth_token_finish(struct http_request *req);
     2318static void yahoo_https_auth_init(struct yahoo_https_auth_data *had);
     2319static void yahoo_https_auth_finish(struct http_request *req);
     2320
     2321/* Extract a value from a login.yahoo.com response. Assume CRLF-linebreaks
     2322   and FAIL miserably if they're not there... */
     2323static char *yahoo_ha_find_key(char *response, char *key)
     2324{
     2325        char *s, *end;
     2326        int len = strlen(key);
     2327       
     2328        s = response;
     2329        do {
     2330                if (strncmp(s, key, len) == 0 && s[len] == '=') {
     2331                        s += len + 1;
     2332                        if ((end = strchr(s, '\r')))
     2333                                return g_strndup(s, end - s);
     2334                        else
     2335                                return g_strdup(s);
     2336                }
     2337               
     2338                if ((s = strchr(s, '\n')))
     2339                        s ++;
     2340        } while (s && *s);
     2341       
     2342        return NULL;
     2343}
     2344
     2345static enum yahoo_status yahoo_https_status_parse(int code)
     2346{
     2347        switch (code)
     2348        {
     2349                case 1212: return YAHOO_LOGIN_PASSWD;
     2350                case 1213: return YAHOO_LOGIN_LOCK;
     2351                case 1235: return YAHOO_LOGIN_UNAME;
     2352                default: return (enum yahoo_status) code;
     2353        }
     2354}
     2355
    23152356static void yahoo_process_auth_0x10(struct yahoo_input_data *yid, const char *seed, const char *sn)
    23162357{
     2358        struct yahoo_https_auth_data *had = g_new0(struct yahoo_https_auth_data, 1);
     2359       
     2360        had->yid = yid;
     2361        had->chal = g_strdup(seed);
     2362       
     2363        yahoo_https_auth_token_init(had);
     2364}
     2365
     2366static void yahoo_https_auth_token_init(struct yahoo_https_auth_data *had)
     2367{
     2368        struct yahoo_input_data *yid = had->yid;
     2369        struct yahoo_data *yd = yid->yd;
     2370        struct http_request *req;
     2371        char *login, *passwd, *chal;
    23172372        char *url;
    2318 
    2319         yid->yd->login_cookie = strdup(seed);
    2320 
    2321         url = g_strdup_printf(
    2322                 "https://login.yahoo.com/config/pwtoken_get?"
    2323                 "src=ymsgr&ts=&login=%s&passwd=%s&chal=%s",
    2324                 yid->yd->user, yid->yd->password, seed);
    2325 
    2326         http_dorequest_url(url, yahoo_process_auth_response, yid);
     2373       
     2374        login = g_strndup(yd->user, 3 * strlen(yd->user));
     2375        http_encode(login);
     2376        passwd = g_strndup(yd->password, 3 * strlen(yd->password));
     2377        http_encode(passwd);
     2378        chal = g_strndup(had->chal, 3 * strlen(had->chal));
     2379        http_encode(chal);
     2380       
     2381        url = g_strdup_printf("https://login.yahoo.com/config/pwtoken_get?src=ymsgr&ts=%d&login=%s&passwd=%s&chal=%s",
     2382                               (int) time(NULL), login, passwd, chal);
     2383       
     2384        req = http_dorequest_url(url, yahoo_https_auth_token_finish, had);
    23272385       
    23282386        g_free(url);
     2387        g_free(chal);
     2388        g_free(passwd);
     2389        g_free(login);
     2390}
     2391
     2392static void yahoo_https_auth_token_finish(struct http_request *req)
     2393{
     2394        struct yahoo_https_auth_data *had = req->data;
     2395        struct yahoo_input_data *yid = had->yid;
     2396        struct yahoo_data *yd = yid->yd;
     2397        int st;
     2398       
     2399        if (req->status_code != 200) {
     2400                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 2000 + req->status_code, NULL);
     2401                goto fail;
     2402        }
     2403       
     2404        if (sscanf(req->reply_body, "%d", &st) != 1 || st != 0) {
     2405                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, yahoo_https_status_parse(st), NULL);
     2406                goto fail;
     2407        }
     2408       
     2409        if ((had->token = yahoo_ha_find_key(req->reply_body, "ymsgr")) == NULL) {
     2410                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 3001, NULL);
     2411                goto fail;
     2412        }
     2413       
     2414        return yahoo_https_auth_init(had);
     2415       
     2416fail:
     2417        g_free(had->token);
     2418        g_free(had->chal);
     2419        g_free(had);
     2420}
     2421
     2422static void yahoo_https_auth_init(struct yahoo_https_auth_data *had)
     2423{
     2424        struct http_request *req;
     2425        char *url;
     2426       
     2427        url = g_strdup_printf("https://login.yahoo.com/config/pwtoken_login?src=ymsgr&ts=%d&token=%s",
     2428                              (int) time(NULL), had->token);
     2429       
     2430        req = http_dorequest_url(url, yahoo_https_auth_finish, had);
     2431       
     2432        g_free(url);
     2433}
     2434
     2435static void yahoo_https_auth_finish(struct http_request *req)
     2436{
     2437        struct yahoo_https_auth_data *had = req->data;
     2438        struct yahoo_input_data *yid = had->yid;
     2439        struct yahoo_data *yd = yid->yd;
     2440        struct yahoo_packet *pack;
     2441        char *crumb;
     2442        int st;
     2443       
     2444        md5_byte_t result[16];
     2445        md5_state_t ctx;
     2446       
     2447        unsigned char yhash[32];
     2448
     2449        if (req->status_code != 200) {
     2450                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 2000 + req->status_code, NULL);
     2451                goto fail;
     2452        }
     2453       
     2454        if (sscanf(req->reply_body, "%d", &st) != 1 || st != 0) {
     2455                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, yahoo_https_status_parse(st), NULL);
     2456                goto fail;
     2457        }
     2458       
     2459        if ((yd->cookie_y = yahoo_ha_find_key(req->reply_body, "Y")) == NULL ||
     2460            (yd->cookie_t = yahoo_ha_find_key(req->reply_body, "T")) == NULL ||
     2461            (crumb = yahoo_ha_find_key(req->reply_body, "crumb")) == NULL) {
     2462                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 3002, NULL);
     2463                goto fail;
     2464        }
     2465       
     2466        md5_init(&ctx); 
     2467        md5_append(&ctx, (unsigned char*) crumb, 11);
     2468        md5_append(&ctx, (unsigned char*) had->chal, strlen(had->chal));
     2469        md5_finish(&ctx, result);
     2470        to_y64(yhash, result, 16);
     2471
     2472        pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->initial_status, yd->session_id);
     2473        yahoo_packet_hash(pack, 1, yd->user);
     2474        yahoo_packet_hash(pack, 0, yd->user);
     2475        yahoo_packet_hash(pack, 277, yd->cookie_y);
     2476        yahoo_packet_hash(pack, 278, yd->cookie_t);
     2477        yahoo_packet_hash(pack, 307, (char*) yhash);
     2478        yahoo_packet_hash(pack, 244, "524223");
     2479        yahoo_packet_hash(pack, 2, yd->user);
     2480        yahoo_packet_hash(pack, 2, "1");
     2481        yahoo_packet_hash(pack, 98, "us");
     2482        yahoo_packet_hash(pack, 135, "7.5.0.647");
     2483       
     2484        yahoo_send_packet(yid, pack, 0);
     2485               
     2486        yahoo_packet_free(pack);
     2487       
     2488fail:
     2489        g_free(crumb);
     2490        g_free(had->token);
     2491        g_free(had->chal);
     2492        g_free(had);
    23292493}
    23302494
     
    23582522                        break;
    23592523                case 2:
    2360                         /* HTTPS */
    23612524                        yahoo_process_auth_0x10(yid, seed, sn);
    23622525                        break;
     
    25152678               
    25162679                yd->buddies = y_list_append(yd->buddies, bud);
    2517                
     2680       
    25182681                /* Possibly called already, but at least the call above doesn't
    25192682                   seem to happen every time (not anytime I tried). */
     
    25222685
    25232686/*      YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, who, status, NULL, (status==YAHOO_STATUS_AVAILABLE?0:1)); */
     2687}
     2688
     2689static void yahoo_process_contact_ymsg13(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     2690{
     2691        char* who=NULL;
     2692        char* me=NULL; 
     2693        char* msg=NULL;
     2694        YList *l;
     2695        for (l = pkt->hash; l; l = l->next) {
     2696                struct yahoo_pair *pair = l->data;
     2697                if (pair->key == 4)
     2698                        who = pair->value;
     2699                else if (pair->key == 5)
     2700                        me = pair->value;
     2701                else
     2702                        DEBUG_MSG(("unknown key: %d = %s", pair->key, pair->value));
     2703        }
     2704
     2705        if(pkt->status==3)
     2706                YAHOO_CALLBACK(ext_yahoo_contact_auth_request)(yid->yd->client_id, me, who, msg);
    25242707}
    25252708
     
    27352918
    27362919        YList *l;
    2737         yahoo_dump_unhandled(pkt);
     2920        // yahoo_dump_unhandled(pkt);
    27382921        for (l = pkt->hash; l; l = l->next) {
    27392922                struct yahoo_pair *pair = l->data;
     
    27572940{
    27582941        DEBUG_MSG(("yahoo_packet_process: 0x%02x", pkt->service));
     2942        yahoo_dump_unhandled(pkt);
    27592943        switch (pkt->service)
    27602944        {
     
    27692953        case YAHOO_SERVICE_IDDEACT:
    27702954        case YAHOO_SERVICE_Y6_STATUS_UPDATE:
    2771         case YAHOO_SERVICE_Y8_STATUS:
     2955        case YAHOO_SERVICE_YMSG15_STATUS:
    27722956                yahoo_process_status(yid, pkt);
    27732957                break;
     
    27832967                yahoo_process_mail(yid, pkt);
    27842968                break;
     2969        case YAHOO_SERVICE_REJECTCONTACT:
    27852970        case YAHOO_SERVICE_NEWCONTACT:
    27862971                yahoo_process_contact(yid, pkt);
     
    28233008                yahoo_process_buddyadd(yid, pkt);
    28243009                break;
     3010        case YAHOO_SERVICE_CONTACT_YMSG13:
     3011                yahoo_process_contact_ymsg13(yid,pkt);
     3012                break;
    28253013        case YAHOO_SERVICE_REMBUDDY:
    28263014                yahoo_process_buddydel(yid, pkt);
     
    28513039        case YAHOO_SERVICE_CHATLOGOFF:
    28523040        case YAHOO_SERVICE_CHATMSG:
    2853         case YAHOO_SERVICE_REJECTCONTACT:
    28543041        case YAHOO_SERVICE_PEERTOPEER:
    28553042                WARNING(("unhandled service 0x%02x", pkt->service));
     
    28653052                yahoo_process_picture_upload(yid, pkt);
    28663053                break; 
    2867         case YAHOO_SERVICE_Y8_LIST:     /* Buddy List */
     3054        case YAHOO_SERVICE_YMSG15_BUDDY_LIST:   /* Buddy List */
    28683055                yahoo_process_buddy_list(yid, pkt);
    28693056        default:
     
    36433830}
    36443831
    3645 /* #define LOG(x...) printf x */
    3646 
    3647 static void yahoo_process_auth_response(struct http_request *req)
    3648 {
    3649         char *line_end;
    3650         char *token;
    3651         char *cookie;
    3652 
    3653         int error_code = 0;
    3654         int is_ymsgr = 0;
    3655 
    3656         struct yahoo_input_data *yid = req->data;
    3657 
    3658         char crypt_hash[25];
    3659 
    3660         md5_byte_t result[16];
    3661         md5_state_t ctx;
    3662 
    3663         struct yahoo_packet *packet = NULL;
    3664        
    3665         if (y_list_find(inputs, yid) == NULL)
    3666                 return;
    3667        
    3668         if (req->status_code != 200) {
    3669                 error_code = 3000 + req->status_code;
    3670                 goto FAIL;
    3671         }
    3672 
    3673         token = req->reply_body;
    3674         line_end = strstr(token, "\r\n");
    3675 
    3676         if (line_end) {
    3677                 *line_end = '\0';
    3678 
    3679                 line_end += 2;
    3680         }
    3681        
    3682         if (sscanf(token, "%d", &error_code) != 1) {
    3683                 error_code = 3000;
    3684                 goto FAIL;
    3685         }
    3686 
    3687         switch(error_code) {
    3688                 case 0:
    3689                         /* successful */
    3690                         break;
    3691 
    3692                 case 1212:
    3693                         LOG(("Incorrect ID or password\n"));
    3694                         error_code = YAHOO_LOGIN_PASSWD;
    3695                         goto FAIL;
    3696 
    3697                 case 1213:
    3698                         LOG(("Security lock from too many failed login attempts\n"));
    3699                         error_code = YAHOO_LOGIN_LOCK;
    3700                         goto FAIL;
    3701 
    3702                 case 1214:
    3703                         LOG(("Security lock\n"));
    3704                         goto FAIL;
    3705 
    3706                 case 1235:
    3707                         LOG(("User ID not taken yet\n"));
    3708                         error_code = YAHOO_LOGIN_UNAME;
    3709                         goto FAIL;
    3710 
    3711                 case 1216:
    3712                         LOG(("Seems to be a lock, but shows the same generic User ID/Password failure\n"));
    3713                         goto FAIL;
    3714 
    3715                 default:
    3716                         /* Unknown error code */
    3717                         LOG(("Unknown Error\n"));
    3718                         goto FAIL;
    3719         }
    3720 
    3721         if ( !strncmp(line_end, "ymsgr=", 6) ) {
    3722                 is_ymsgr = 1;
    3723         }
    3724         else if ( strncmp(line_end, "crumb=", 6) ) {
    3725                 LOG(("Oops! There was no ymsgr=. Where do I get my token from now :("));
    3726                 LOG(("I got this:\n\n%s\n",line_end));
    3727                 error_code = 2201;
    3728                 goto FAIL;
    3729         }
    3730 
    3731         token = line_end+6;
    3732 
    3733         line_end = strstr(token, "\r\n");
    3734 
    3735         if(line_end) {
    3736                 *line_end = '\0';
    3737                 line_end += 2;
    3738         }
    3739 
    3740         /* Go for the crumb */
    3741         if(is_ymsgr) {
    3742                 char *url;
    3743 
    3744                 url = g_strdup_printf(
    3745                         "https://login.yahoo.com/config/pwtoken_login?"
    3746                         "src=ymsgr&ts=&token=%s", token);
    3747 
    3748                 http_dorequest_url(url, yahoo_process_auth_response, yid);
    3749 
    3750                 g_free(url);
    3751 
    3752                 return;
    3753         }
    3754 
    3755         /* token is actually crumb */
    3756 
    3757         if(!line_end) {
    3758                 /* We did not get our cookies. Cry. */
    3759         }
    3760 
    3761         if((cookie = strstr(req->reply_headers, "Set-Cookie: Y=")) &&
    3762            (line_end = strstr(cookie + 14, "\r\n"))) {
    3763                 *line_end = '\0';
    3764                 yid->yd->cookie_y = strdup(cookie + 14);
    3765                 *line_end = ';';
    3766         } else {
    3767                 /* Cry. */
    3768                 LOG(("NO Y Cookie!"));
    3769                 error_code = 2202;
    3770                 goto FAIL;
    3771         }
    3772 
    3773         if((cookie = strstr(req->reply_headers, "Set-Cookie: T=")) &&
    3774            (line_end = strstr(cookie + 14, "\r\n"))) {
    3775                 *line_end = '\0';
    3776                 yid->yd->cookie_t = strdup(cookie + 14);
    3777                 *line_end = ';';
    3778         } else {
    3779                 /* Cry. */
    3780                 LOG(("NO T Cookie!"));
    3781                 error_code = 2203;
    3782                 goto FAIL;
    3783         }
    3784 
    3785         md5_init(&ctx);
    3786         md5_append(&ctx, (md5_byte_t *)token, strlen(token));
    3787         md5_append(&ctx, (md5_byte_t *)yid->yd->login_cookie, strlen(yid->yd->login_cookie));
    3788         md5_finish(&ctx, result);
    3789 
    3790         to_y64((unsigned char*)crypt_hash, result, 16);
    3791 
    3792         packet = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yid->yd->initial_status, yid->yd->session_id);
    3793         yahoo_packet_hash(packet, 1, yid->yd->user);
    3794         yahoo_packet_hash(packet, 0, yid->yd->user);
    3795         yahoo_packet_hash(packet, 277, yid->yd->cookie_y);
    3796         yahoo_packet_hash(packet, 278, yid->yd->cookie_t);
    3797         yahoo_packet_hash(packet, 307, crypt_hash);
    3798         yahoo_packet_hash(packet, 244, "2097087");      /* Rekkanoryo says this is the build number */
    3799         yahoo_packet_hash(packet, 2, yid->yd->user);
    3800         yahoo_packet_hash(packet, 2, "1");
    3801         yahoo_packet_hash(packet, 98, "us");            /* TODO Put country code */
    3802         yahoo_packet_hash(packet, 135, "9.0.0.1389");
    3803                
    3804         yahoo_send_packet(yid, packet, 0);
    3805 
    3806         yahoo_packet_free(packet);
    3807 
    3808         /* We don't need this anymore */
    3809         free(yid->yd->login_cookie);
    3810         yid->yd->login_cookie = NULL;
    3811        
    3812         return;
    3813 
    3814 FAIL:
    3815         YAHOO_CALLBACK(ext_yahoo_login_response)(yid->yd->client_id, error_code, NULL);
    3816 }
    3817 
    3818 
    38193832static void (*yahoo_process_connection[])(struct yahoo_input_data *, int over) = {
    38203833        yahoo_process_pager_connection,
     
    40454058
    40464059        yahoo_packet_hash(pkt, 5, who);
    4047         yahoo_packet_hash(pkt, 4, from?from:yd->user);
     4060        yahoo_packet_hash(pkt, 1, from?from:yd->user);
    40484061        yahoo_packet_hash(pkt, 14, " ");
    40494062        yahoo_packet_hash(pkt, 13, typ ? "1" : "0");
     
    40604073        struct yahoo_data *yd;
    40614074        struct yahoo_packet *pkt = NULL;
    4062         int service;
     4075        int old_status;
    40634076        char s[4];
    40644077
     
    40684081        yd = yid->yd;
    40694082
    4070         if (msg) {
     4083        old_status = yd->current_status;
     4084
     4085        if (msg && strncmp(msg,"Invisible",9)) {
    40714086                yd->current_status = YAHOO_STATUS_CUSTOM;
    40724087        } else {
     
    40744089        }
    40754090
    4076         if (yd->current_status == YAHOO_STATUS_AVAILABLE)
    4077                 service = YAHOO_SERVICE_ISBACK;
    4078         else
    4079                 service = YAHOO_SERVICE_ISAWAY;
     4091        /* Thank you libpurple :) */
     4092        if (yd->current_status == YAHOO_STATUS_INVISIBLE) {
     4093                pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0);
     4094                yahoo_packet_hash(pkt, 13, "2");
     4095                yahoo_send_packet(yid, pkt, 0);
     4096                yahoo_packet_free(pkt);
     4097
     4098                return;
     4099        }
     4100
     4101        pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, yd->current_status, yd->session_id);
     4102        snprintf(s, sizeof(s), "%d", yd->current_status);
     4103        yahoo_packet_hash(pkt, 10, s);
    40804104         
    4081         if ((away == 2) && (yd->current_status == YAHOO_STATUS_AVAILABLE)) {
    4082                 pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_BRB, yd->session_id);
    4083                 yahoo_packet_hash(pkt, 10, "999");
    4084                 yahoo_packet_hash(pkt, 47, "2");
    4085         }else {
    4086                 pkt = yahoo_packet_new(service, YAHOO_STATUS_AVAILABLE, yd->session_id);
    4087                 snprintf(s, sizeof(s), "%d", yd->current_status);
    4088                 yahoo_packet_hash(pkt, 10, s);
    4089                 if (yd->current_status == YAHOO_STATUS_CUSTOM) {
    4090                         yahoo_packet_hash(pkt, 19, msg);
    4091                         yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0");
    4092                 } else {
    4093                         yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0");
    4094                 }
    4095                
    4096                
    4097                
    4098         }
     4105        if (yd->current_status == YAHOO_STATUS_CUSTOM) {
     4106                yahoo_packet_hash(pkt, 19, msg);
     4107        } else {
     4108                yahoo_packet_hash(pkt, 19, "");
     4109        }
     4110       
     4111        yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0");
    40994112
    41004113        yahoo_send_packet(yid, pkt, 0);
    41014114        yahoo_packet_free(pkt);
     4115
     4116        if(old_status == YAHOO_STATUS_INVISIBLE) {
     4117                pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0);
     4118                yahoo_packet_hash(pkt, 13, "1");
     4119                yahoo_send_packet(yid, pkt, 0);
     4120                yahoo_packet_free(pkt);
     4121        }
    41024122}
    41034123
     
    41144134        LOG(("yahoo_logoff: current status: %d", yd->current_status));
    41154135
    4116         if(yd->current_status != -1) {
     4136        if(yd->current_status != -1 && 0) {
     4137                /* Meh. Don't send this. The event handlers are not going to
     4138                   get to do this so it'll just leak memory. And the TCP
     4139                   connection reset will hopefully be clear enough. */
    41174140                pkt = yahoo_packet_new(YAHOO_SERVICE_LOGOFF, YAHOO_STATUS_AVAILABLE, yd->session_id);
    41184141                yd->current_status = -1;
     
    43474370                return;
    43484371
    4349         pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id);
    4350         yahoo_packet_hash(pkt, 1, yd->user);
    4351         yahoo_packet_hash(pkt, 7, who);
    4352         yahoo_packet_hash(pkt, 65, group);
     4372        pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YPACKET_STATUS_DEFAULT, yd->session_id);
     4373
    43534374        if (msg != NULL) /* add message/request "it's me add me" */
    43544375                yahoo_packet_hash(pkt, 14, msg);
     4376        else
     4377                yahoo_packet_hash(pkt,14,"");
     4378
     4379        yahoo_packet_hash(pkt, 65, group);
     4380        yahoo_packet_hash(pkt, 97, "1");
     4381        yahoo_packet_hash(pkt, 1, yd->user);
     4382        yahoo_packet_hash(pkt, 302, "319");
     4383        yahoo_packet_hash(pkt, 300, "319");
     4384        yahoo_packet_hash(pkt, 7, who);
     4385        yahoo_packet_hash(pkt, 334, "0");
     4386        yahoo_packet_hash(pkt, 301, "319");
     4387        yahoo_packet_hash(pkt, 303, "319");
     4388
     4389
    43554390        yahoo_send_packet(yid, pkt, 0);
    43564391        yahoo_packet_free(pkt);
     
    43744409        yahoo_send_packet(yid, pkt, 0);
    43754410        yahoo_packet_free(pkt);
     4411}
     4412
     4413void yahoo_accept_buddy_ymsg13(int id,const char* me,const char* who){
     4414        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4415        struct yahoo_data *yd;
     4416
     4417        if(!yid)
     4418                return;
     4419        yd = yid->yd;
     4420
     4421        struct yahoo_packet* pkt=NULL;
     4422        pkt= yahoo_packet_new(YAHOO_SERVICE_CONTACT_YMSG13,YAHOO_STATUS_AVAILABLE,0);
     4423
     4424        yahoo_packet_hash(pkt,1,me ?: yd->user);       
     4425        yahoo_packet_hash(pkt,5,who);
     4426        yahoo_packet_hash(pkt,13,"1");
     4427        yahoo_packet_hash(pkt,334,"0");
     4428        yahoo_send_packet(yid, pkt, 0);
     4429        yahoo_packet_free(pkt);
     4430}
     4431
     4432void yahoo_reject_buddy_ymsg13(int id,const char* me,const char* who,const char* msg){
     4433        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4434        struct yahoo_data *yd;
     4435
     4436        if(!yid)
     4437                return;
     4438        yd = yid->yd;
     4439
     4440        struct yahoo_packet* pkt=NULL;
     4441        pkt= yahoo_packet_new(YAHOO_SERVICE_CONTACT_YMSG13,YAHOO_STATUS_AVAILABLE,0);
     4442
     4443        yahoo_packet_hash(pkt,1,me ?: yd->user);       
     4444        yahoo_packet_hash(pkt,5,who);
     4445//      yahoo_packet_hash(pkt,241,YAHOO_PROTO_VER);
     4446        yahoo_packet_hash(pkt,13,"2");
     4447        yahoo_packet_hash(pkt,334,"0");
     4448        yahoo_packet_hash(pkt,97,"1");
     4449        yahoo_packet_hash(pkt,14,msg?:"");
     4450
     4451        yahoo_send_packet(yid, pkt, 0);
     4452        yahoo_packet_free(pkt);
     4453
    43764454}
    43774455
     
    44314509                return;
    44324510
    4433         pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH_PERM, YAHOO_STATUS_AVAILABLE, yd->session_id);
     4511        pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH, YAHOO_STATUS_AVAILABLE, yd->session_id);
    44344512        yahoo_packet_hash(pkt, 1, yd->user);
    44354513        yahoo_packet_hash(pkt, 7, who);
  • protocols/yahoo/yahoo.c

    rb3117f2 r4e04194  
    254254static GList *byahoo_away_states( struct im_connection *ic )
    255255{
    256         GList *m = NULL;
    257 
    258         m = g_list_append( m, "Available" );
    259         m = g_list_append( m, "Be Right Back" );
    260         m = g_list_append( m, "Busy" );
    261         m = g_list_append( m, "Not At Home" );
    262         m = g_list_append( m, "Not At Desk" );
    263         m = g_list_append( m, "Not In Office" );
    264         m = g_list_append( m, "On Phone" );
    265         m = g_list_append( m, "On Vacation" );
    266         m = g_list_append( m, "Out To Lunch" );
    267         m = g_list_append( m, "Stepped Out" );
    268         m = g_list_append( m, "Invisible" );
    269         m = g_list_append( m, GAIM_AWAY_CUSTOM );
     256        static GList *m = NULL;
     257
     258        if( m == NULL )
     259        {
     260                m = g_list_append( m, "Available" );
     261                m = g_list_append( m, "Be Right Back" );
     262                m = g_list_append( m, "Busy" );
     263                m = g_list_append( m, "Not At Home" );
     264                m = g_list_append( m, "Not At Desk" );
     265                m = g_list_append( m, "Not In Office" );
     266                m = g_list_append( m, "On Phone" );
     267                m = g_list_append( m, "On Vacation" );
     268                m = g_list_append( m, "Out To Lunch" );
     269                m = g_list_append( m, "Stepped Out" );
     270                m = g_list_append( m, "Invisible" );
     271                m = g_list_append( m, GAIM_AWAY_CUSTOM );
     272        }
    270273       
    271274        return m;
     
    346349       
    347350        return c;
     351}
     352
     353static void byahoo_auth_allow( struct im_connection *ic, const char *who )
     354{
     355        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
     356       
     357        yahoo_accept_buddy_ymsg13( yd->y2_id, NULL, who );
     358}
     359
     360static void byahoo_auth_deny( struct im_connection *ic, const char *who )
     361{
     362        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
     363       
     364        yahoo_reject_buddy_ymsg13( yd->y2_id, NULL, who, NULL );
    348365}
    349366
     
    373390        ret->handle_cmp = g_strcasecmp;
    374391       
     392        ret->auth_allow = byahoo_auth_allow;
     393        ret->auth_deny = byahoo_auth_deny;
     394       
    375395        register_protocol(ret);
    376396}
     
    452472        struct byahoo_write_ready_data *d = data;
    453473       
    454         yahoo_write_ready( d->id, d->fd, d->data );
    455        
    456         return FALSE;
     474        return yahoo_write_ready( d->id, d->fd, d->data );
    457475}
    458476
     
    922940}
    923941
     942void ext_yahoo_contact_auth_request( int id, const char *myid, const char *who, const char *msg )
     943{
     944        struct im_connection *ic = byahoo_get_ic_by_id( id );
     945       
     946        imcb_ask_auth( ic, who, NULL );
     947}
     948
    924949void ext_yahoo_contact_added( int id, const char *myid, const char *who, const char *msg )
    925950{
    926         /* Groups schmoups. If I want to handle groups properly I can get the
    927            buddy data from some internal libyahoo2 structure. */
    928         imcb_add_buddy( byahoo_get_ic_by_id( id ), (char*) who, NULL );
     951        struct im_connection *ic = byahoo_get_ic_by_id( id );
     952       
     953        imcb_add_buddy( ic, (char*) who, NULL );
    929954}
    930955
  • protocols/yahoo/yahoo2.h

    rb3117f2 r4e04194  
    217217void yahoo_buddyicon_request(int id, const char *who);
    218218
     219void yahoo_accept_buddy_ymsg13(int,const char*,const char*);
     220void yahoo_reject_buddy_ymsg13(int,const char*,const char*,const char*);
     221
    219222#include "yahoo_httplib.h"
    220223
  • protocols/yahoo/yahoo2_callbacks.h

    rb3117f2 r4e04194  
    361361
    362362/*
     363 * Name: ext_yahoo_contact_auth_request
     364 *      Called when a contact wants to add you to his/her contact list
     365 * Params:
     366 *      id   - the id that identifies the server connection
     367 *      myid - the identity s/he added
     368 *      who  - who did it
     369 *      msg  - any message sent
     370 */
     371void YAHOO_CALLBACK_TYPE(ext_yahoo_contact_auth_request)(int id, const char *myid, const char *who, const char *msg);
     372
     373
     374/*
    363375 * Name: ext_yahoo_contact_added
    364376 *      Called when a contact is added to your list
  • protocols/yahoo/yahoo2_types.h

    rb3117f2 r4e04194  
    5757        YAHOO_LOGIN_LOCK = 14,
    5858        YAHOO_LOGIN_DUPL = 99,
    59         YAHOO_LOGIN_SOCK = -1
     59        YAHOO_LOGIN_SOCK = -1,
     60};
     61
     62enum ypacket_status {
     63        YPACKET_STATUS_DISCONNECTED = -1,
     64        YPACKET_STATUS_DEFAULT = 0,
     65        YPACKET_STATUS_SERVERACK = 1,
     66        YPACKET_STATUS_GAME     = 0x2,
     67        YPACKET_STATUS_AWAY     = 0x4,
     68        YPACKET_STATUS_CONTINUED = 0x5,
     69        YPACKET_STATUS_INVISIBLE = 12,
     70        YPACKET_STATUS_NOTIFY = 0x16, /* TYPING */
     71        YPACKET_STATUS_WEBLOGIN = 0x5a55aa55,
     72        YPACKET_STATUS_OFFLINE = 0x5a55aa56
    6073};
    6174
     
    133146#define YAHOO_CHAT_MALE 0x8000
    134147#define YAHOO_CHAT_FEMALE 0x10000
    135 #define YAHOO_CHAT_FEMALE 0x10000
    136148#define YAHOO_CHAT_DUNNO 0x400
    137149#define YAHOO_CHAT_WEBCAM 0x10
Note: See TracChangeset for help on using the changeset viewer.