From 19176513584bf26fa69a8a946982d9c521038a17 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Wed, 3 Jun 2009 17:10:36 +0100 Subject: Fixed a bug that caused crashes when joining certain kinds of Google Talk chatrooms. Doesn't seem to be Google Talk specific, other than that this is the first time I see empty elements that cause this crash. A more proper/efficient fix may be to just move the break outside the inner if. --- protocols/jabber/conference.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'protocols') diff --git a/protocols/jabber/conference.c b/protocols/jabber/conference.c index 480006bd..08bef4f5 100644 --- a/protocols/jabber/conference.c +++ b/protocols/jabber/conference.c @@ -233,8 +233,10 @@ void jabber_chat_pkt_presence( struct im_connection *ic, struct jabber_buddy *bu if( ( s = xt_find_attr( c, "xmlns" ) ) && ( strcmp( s, XMLNS_MUC_USER ) == 0 ) ) { - c = xt_find_node( c->children, "item" ); - if( ( s = xt_find_attr( c, "jid" ) ) ) + struct xt_node *item; + + item = xt_find_node( c->children, "item" ); + if( ( s = xt_find_attr( item, "jid" ) ) ) { /* Yay, found what we need. :-) */ bud->ext_jid = jabber_normalize( s ); -- cgit v1.2.3 From b9369b55c99246a8feaee0ad24367044d92fa55d Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Thu, 18 Jun 2009 00:17:15 +0100 Subject: Fixed compatibility with AIM mobile messages. Should work according to reports in bug #88 (where this patch comes from) and #bitlbee. Not sure about side effects, one way to find out... --- protocols/oscar/aim.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'protocols') diff --git a/protocols/oscar/aim.h b/protocols/oscar/aim.h index 9516996c..d1fc602a 100644 --- a/protocols/oscar/aim.h +++ b/protocols/oscar/aim.h @@ -143,6 +143,17 @@ struct client_info_s { "en", \ } +#define AIM_CLIENTINFO_KNOWNGOOD_5_1_3036 { \ + "AOL Instant Messenger, version 5.1.3036/WIN32", \ + 0x0109, \ + 0x0005, \ + 0x0001, \ + 0x0000, \ + 0x0bdc, \ + "us", \ + "en", \ +} + /* * I would make 4.1.2010 the default, but they seem to have found * an alternate way of breaking that one. @@ -151,7 +162,7 @@ struct client_info_s { * memory test, which may require you to have a WinAIM binary laying * around. (see login.c::memrequest()) */ -#define AIM_CLIENTINFO_KNOWNGOOD AIM_CLIENTINFO_KNOWNGOOD_3_5_1670 +#define AIM_CLIENTINFO_KNOWNGOOD AIM_CLIENTINFO_KNOWNGOOD_5_1_3036 #ifndef TRUE #define TRUE 1 -- cgit v1.2.3 From 4fefb772f530cd15ef3e92606532d3c6b193d96b Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 3 Oct 2009 20:27:50 +0100 Subject: Yahoo! can log in again. This code still needs major cleanups, use it only if you're very desparate. --- protocols/yahoo/libyahoo2.c | 310 ++++++++++++++++++++++++++++++++++++++++- protocols/yahoo/yahoo2_types.h | 5 +- 2 files changed, 306 insertions(+), 9 deletions(-) (limited to 'protocols') diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index a61955c4..52655240 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -88,6 +88,12 @@ char *strchr (), *strrchr (); #endif #include "base64.h" +#include "http_client.h" + +static void yahoo_process_auth_response(struct http_request *req); + +/* What's this used for actually? */ +static void _yahoo_http_connected(int id, int fd, int error, void *data); #ifdef USE_STRUCT_CALLBACKS struct yahoo_callbacks *yc=NULL; @@ -168,6 +174,7 @@ enum yahoo_service { /* these are easier to see in hex */ YAHOO_SERVICE_PING, YAHOO_SERVICE_GOTGROUPRENAME, /* < 1, 36(old), 37(new) */ YAHOO_SERVICE_SYSMESSAGE = 0x14, + YAHOO_SERVICE_SKINNAME = 0x15, YAHOO_SERVICE_PASSTHROUGH2 = 0x16, YAHOO_SERVICE_CONFINVITE = 0x18, YAHOO_SERVICE_CONFLOGON, @@ -191,24 +198,49 @@ enum yahoo_service { /* these are easier to see in hex */ YAHOO_SERVICE_AUTHRESP = 0x54, YAHOO_SERVICE_LIST, YAHOO_SERVICE_AUTH = 0x57, + YAHOO_SERVICE_AUTHBUDDY = 0x6d, YAHOO_SERVICE_ADDBUDDY = 0x83, YAHOO_SERVICE_REMBUDDY, YAHOO_SERVICE_IGNORECONTACT, /* > 1, 7, 13 < 1, 66, 13, 0*/ YAHOO_SERVICE_REJECTCONTACT, YAHOO_SERVICE_GROUPRENAME = 0x89, /* > 1, 65(new), 66(0), 67(old) */ + YAHOO_SERVICE_Y7_PING = 0x8A, /* 0 - id and that's it?? */ YAHOO_SERVICE_CHATONLINE = 0x96, /* > 109(id), 1, 6(abcde) < 0,1*/ YAHOO_SERVICE_CHATGOTO, YAHOO_SERVICE_CHATJOIN, /* > 1 104-room 129-1600326591 62-2 */ YAHOO_SERVICE_CHATLEAVE, YAHOO_SERVICE_CHATEXIT = 0x9b, + YAHOO_SERVICE_CHATADDINVITE = 0x9d, YAHOO_SERVICE_CHATLOGOUT = 0xa0, YAHOO_SERVICE_CHATPING, YAHOO_SERVICE_COMMENT = 0xa8, - YAHOO_SERVICE_STEALTH = 0xb9, + YAHOO_SERVICE_GAME_INVITE = 0xb7, + YAHOO_SERVICE_STEALTH_PERM = 0xb9, + YAHOO_SERVICE_STEALTH_SESSION = 0xba, + YAHOO_SERVICE_AVATAR = 0xbc, YAHOO_SERVICE_PICTURE_CHECKSUM = 0xbd, YAHOO_SERVICE_PICTURE = 0xbe, YAHOO_SERVICE_PICTURE_UPDATE = 0xc1, - YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2 + YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2, + YAHOO_SERVICE_YAB_UPDATE = 0xc4, + YAHOO_SERVICE_Y6_VISIBLE_TOGGLE = 0xc5, /* YMSG13, key 13: 2 = invisible, 1 = visible */ + YAHOO_SERVICE_Y6_STATUS_UPDATE = 0xc6, /* YMSG13 */ + YAHOO_SERVICE_PICTURE_STATUS = 0xc7, /* YMSG13, key 213: 0 = none, 1 = avatar, 2 = picture */ + YAHOO_SERVICE_VERIFY_ID_EXISTS = 0xc8, + YAHOO_SERVICE_AUDIBLE = 0xd0, + YAHOO_SERVICE_Y7_PHOTO_SHARING = 0xd2, + YAHOO_SERVICE_Y7_CONTACT_DETAILS = 0xd3,/* YMSG13 */ + YAHOO_SERVICE_Y7_CHAT_SESSION = 0xd4, + YAHOO_SERVICE_Y7_AUTHORIZATION = 0xd6, /* YMSG13 */ + YAHOO_SERVICE_Y7_FILETRANSFER = 0xdc, /* YMSG13 */ + YAHOO_SERVICE_Y7_FILETRANSFERINFO, /* YMSG13 */ + YAHOO_SERVICE_Y7_FILETRANSFERACCEPT, /* YMSG13 */ + YAHOO_SERVICE_Y7_MINGLE = 0xe1, /* YMSG13 */ + YAHOO_SERVICE_Y7_CHANGE_GROUP = 0xe7, /* YMSG13 */ + YAHOO_SERVICE_Y8_STATUS = 0xf0, /* YMSG15 */ + YAHOO_SERVICE_Y8_LIST = 0Xf1, /* YMSG15 */ + YAHOO_SERVICE_WEBLOGIN = 0x0226, + YAHOO_SERVICE_SMS_MSG = 0x02ea }; struct yahoo_pair { @@ -732,7 +764,7 @@ static void yahoo_send_packet(struct yahoo_input_data *yid, struct yahoo_packet data = y_new0(unsigned char, len + 1); memcpy(data + pos, "YMSG", 4); pos += 4; - pos += yahoo_put16(data + pos, 0x000c); + pos += yahoo_put16(data + pos, YAHOO_PROTO_VER); pos += yahoo_put16(data + pos, 0x0000); pos += yahoo_put16(data + pos, pktlen + extra_pad); pos += yahoo_put16(data + pos, pkt->service); @@ -1479,6 +1511,62 @@ static void yahoo_process_status(struct yahoo_input_data *yid, struct yahoo_pack } } +static void yahoo_process_buddy_list(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +{ + struct yahoo_data *yd = yid->yd; + YList *l; + int last_packet = 0; + char *cur_group = NULL; + struct yahoo_buddy *newbud = NULL; + + /* we could be getting multiple packets here */ + for (l = pkt->hash; l; l = l->next) { + struct yahoo_pair *pair = l->data; + + switch(pair->key) { + case 300: + case 301: + case 302: + case 303: + if ( 315 == atoi(pair->value) ) + last_packet = 1; + break; + case 65: + cur_group = strdup(pair->value); + break; + case 7: + newbud = y_new0(struct yahoo_buddy, 1); + newbud->id = strdup(pair->value); + if(cur_group) + newbud->group = strdup(cur_group); + else { + struct yahoo_buddy *lastbud = (struct yahoo_buddy *)y_list_nth( + yd->buddies, y_list_length(yd->buddies)-1)->data; + newbud->group = strdup(lastbud->group); + } + + yd->buddies = y_list_append(yd->buddies, newbud); + + break; + } + } + + /* we could be getting multiple packets here */ + if (last_packet) + return; + + YAHOO_CALLBACK(ext_yahoo_got_buddies)(yd->client_id, yd->buddies); + + + /*** We login at the very end of the packet communication */ + if (!yd->logged_in) { + yd->logged_in = TRUE; + if(yd->current_status < 0) + yd->current_status = yd->initial_status; + YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_OK, NULL); + } +} + static void yahoo_process_list(struct yahoo_input_data *yid, struct yahoo_packet *pkt) { struct yahoo_data *yd = yid->yd; @@ -1548,7 +1636,8 @@ static void yahoo_process_list(struct yahoo_input_data *yid, struct yahoo_packet yd->cookie_c = getcookie(pair->value); } - if(yd->cookie_y && yd->cookie_t && yd->cookie_c) + // if(yd->cookie_y && yd->cookie_t && yd->cookie_c) + if(yd->cookie_y && yd->cookie_t) YAHOO_CALLBACK(ext_yahoo_got_cookies)(yd->client_id); break; @@ -2225,6 +2314,22 @@ static void yahoo_process_auth_0x0b(struct yahoo_input_data *yid, const char *se free(crypt_hash); } +static void yahoo_process_auth_0x10(struct yahoo_input_data *yid, const char *seed, const char *sn) +{ + char *url; + + yid->yd->login_cookie = strdup(seed); + + url = g_strdup_printf( + "https://login.yahoo.com/config/pwtoken_get?" + "src=ymsgr&ts=&login=%s&passwd=%s&chal=%s", + yid->yd->user, yid->yd->password, seed); + + http_dorequest_url(url, yahoo_process_auth_response, yid); + + g_free(url); +} + static void yahoo_process_auth(struct yahoo_input_data *yid, struct yahoo_packet *pkt) { char *seed = NULL; @@ -2253,6 +2358,10 @@ static void yahoo_process_auth(struct yahoo_input_data *yid, struct yahoo_packet case 1: yahoo_process_auth_0x0b(yid, seed, sn); break; + case 2: + /* HTTPS */ + yahoo_process_auth_0x10(yid, seed, sn); + break; default: /* call error */ WARNING(("unknown auth type %d", m)); @@ -2660,6 +2769,8 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack case YAHOO_SERVICE_GAMELOGOFF: case YAHOO_SERVICE_IDACT: case YAHOO_SERVICE_IDDEACT: + case YAHOO_SERVICE_Y6_STATUS_UPDATE: + case YAHOO_SERVICE_Y8_STATUS: yahoo_process_status(yid, pkt); break; case YAHOO_SERVICE_NOTIFY: @@ -2755,6 +2866,8 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack case YAHOO_SERVICE_PICTURE_UPLOAD: yahoo_process_picture_upload(yid, pkt); break; + case YAHOO_SERVICE_Y8_LIST: /* Buddy List */ + yahoo_process_buddy_list(yid, pkt); default: WARNING(("unknown service 0x%02x", pkt->service)); yahoo_dump_unhandled(pkt); @@ -3531,6 +3644,189 @@ static void yahoo_process_webcam_connection(struct yahoo_input_data *yid, int ov && yahoo_get_webcam_data(yid) == 1); } +//#define LOG(x...) printf x + +static void yahoo_process_auth_response(struct http_request *req) +{ + char *line_end; + char *token; + char *cookie; + + int error_code = 0; + int is_ymsgr = 0; + + struct yahoo_data *yd = NULL; + struct yahoo_input_data *yid = req->data; + + unsigned char crypt_hash[25]; + + md5_byte_t result[16]; + md5_state_t ctx; + + struct yahoo_packet *packet =NULL; + + token = req->reply_body; + line_end = strstr(token, "\r\n"); + + if (line_end) { + *line_end = '\0'; + + line_end+=2; + } + + error_code = atoi((char *)token); + + switch(error_code) { + case 0: + /* successful */ + LOG(("successful\n")); + break; + case 1212: + /* Incorrect ID or password */ + LOG(("Incorrect ID or password\n")); + + return; + case 1213: + /* Security lock from too many failed login attempts */ + LOG(("Security lock from too many failed login attempts\n")); + + return; + + case 1214: + /* Security lock */ + LOG(("Security lock\n")); + + return; + + case 1235: + /* User ID not taken yet */ + LOG(("User ID not taken yet\n")); + + return; + + case 1216: + /* Seems to be a lock, but shows the same generic User ID/Password failure */ + LOG(("Seems to be a lock, but shows the same generic User ID/Password failure\n")); + + return; + case 100: + /* Username and password cannot be blank */ + LOG(("Username and password cannot be blank\n")); + + return; + default: + /* Unknown error code */ + LOG(("Unknown Error\n")); + + return; + } + + if ( !strncmp(line_end, "ymsgr=", 6) ) { + is_ymsgr = 1; + } + else if ( strncmp(line_end, "crumb=", 6) ) { + LOG(("Oops! There was no ymsgr=. Where do I get my token from now :(")); + LOG(("I got this:\n\n%s\n",line_end)); + return; + /* Error */ + } + + token = line_end+6; + + line_end = strstr(token, "\r\n"); + + if(line_end) { + *line_end = '\0'; + line_end+=2; + } + + /* Go for the crumb */ + if(is_ymsgr) { + char *url; + + url = g_strdup_printf( + "https://login.yahoo.com/config/pwtoken_login?" + "src=ymsgr&ts=&token=%s", token); + + http_dorequest_url(url, yahoo_process_auth_response, yid); + g_free(url); + + return; + } + + /* token is actually crumb */ + + if(!line_end) { + /* We did not get our cookies. Cry. */ + } + + cookie = strstr(req->reply_headers, "Set-Cookie: Y="); + + if(!cookie) { + /* Cry. */ + LOG(("NO Y Cookie!")); + return; + } + + cookie+=14; + + line_end = strstr(cookie, "\r\n"); + *line_end = '\0'; + + LOG(("Cookie length: %d", strlen(cookie))); + + yid->yd->cookie_y = strdup(cookie); + *line_end = ';'; + + cookie = strstr(req->reply_headers, "Set-Cookie: T="); + if(!cookie) { + LOG(("NO T Cookie!")); + /* Cry. */ + return; + } + + cookie+=14; + + line_end = strstr(cookie, "\r\n"); + *line_end = '\0'; + + yid->yd->cookie_t = strdup(cookie); + + LOG(("My Cookies ::\n Y: %s\nT: %s\n\n", yid->yd->cookie_y, yid->yd->cookie_t)); + + md5_init(&ctx); + md5_append(&ctx, (md5_byte_t *)token, strlen(token)); + md5_append(&ctx, (md5_byte_t *)yid->yd->login_cookie, strlen(yid->yd->login_cookie)); + md5_finish(&ctx, result); + + to_y64(crypt_hash, result, 16); + + yd = yid->yd; + + //yid = find_input_by_id_and_type(yd->client_id, YAHOO_CONNECTION_PAGER); + + packet = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->initial_status, yd->session_id); + yahoo_packet_hash(packet, 1, yd->user); + yahoo_packet_hash(packet, 0, yd->user); + yahoo_packet_hash(packet, 277, yd->cookie_y); + yahoo_packet_hash(packet, 278, yd->cookie_t); + yahoo_packet_hash(packet, 307, crypt_hash); + yahoo_packet_hash(packet, 244, "2097087"); /* Rekkanoryo says this is the build number */ + yahoo_packet_hash(packet, 2, yd->user); + yahoo_packet_hash(packet, 2, "1"); + yahoo_packet_hash(packet, 98, "us"); /* TODO Put country code */ + yahoo_packet_hash(packet, 135, "9.0.0.1389"); + + yahoo_send_packet(yid, packet, 0); + + yahoo_packet_free(packet); + + /* We don't need this anymore */ + free(yd->login_cookie); + yd->login_cookie = NULL; +} + + static void (*yahoo_process_connection[])(struct yahoo_input_data *, int over) = { yahoo_process_pager_connection, yahoo_process_ft_connection, @@ -3538,7 +3834,7 @@ static void (*yahoo_process_connection[])(struct yahoo_input_data *, int over) = yahoo_process_webcam_master_connection, yahoo_process_webcam_connection, yahoo_process_chatcat_connection, - yahoo_process_search_connection + yahoo_process_search_connection, }; int yahoo_read_ready(int id, int fd, void *data) @@ -3556,7 +3852,7 @@ int yahoo_read_ready(int id, int fd, void *data) len = read(fd, buf, sizeof(buf)); } while(len == -1 && errno == EINTR); - if(len == -1 && errno == EAGAIN) /* we'll try again later */ + if(len == -1 && (errno == EAGAIN||errno == EINTR)) /* we'll try again later */ return 1; if (len <= 0) { @@ -4145,7 +4441,7 @@ void yahoo_stealth_buddy(int id, const char *who, int unstealth) if (!yd->logged_in) return; - pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH_PERM, YAHOO_STATUS_AVAILABLE, yd->session_id); yahoo_packet_hash(pkt, 1, yd->user); yahoo_packet_hash(pkt, 7, who); yahoo_packet_hash(pkt, 31, unstealth?"2":"1"); diff --git a/protocols/yahoo/yahoo2_types.h b/protocols/yahoo/yahoo2_types.h index df1756eb..7453e487 100644 --- a/protocols/yahoo/yahoo2_types.h +++ b/protocols/yahoo/yahoo2_types.h @@ -84,7 +84,7 @@ enum yahoo_log_level { YAHOO_LOG_DEBUG }; -#define YAHOO_PROTO_VER 0x000b +#define YAHOO_PROTO_VER 0x0010 /* Yahoo style/color directives */ #define YAHOO_COLOR_BLACK "\033[30m" @@ -114,7 +114,8 @@ enum yahoo_connection_type { YAHOO_CONNECTION_WEBCAM_MASTER, YAHOO_CONNECTION_WEBCAM, YAHOO_CONNECTION_CHATCAT, - YAHOO_CONNECTION_SEARCH + YAHOO_CONNECTION_SEARCH, + YAHOO_CONNECTION_AUTH, }; enum yahoo_webcam_direction_type { -- cgit v1.2.3 From c3e349e0847b5b936d1040c56ea427a7f2ce0d7c Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 3 Oct 2009 23:25:36 +0100 Subject: Cleaned up Yahoo! fix: Error handling, and also not crashing when the connection disappears again before authentication finishes. --- protocols/yahoo/libyahoo2.c | 143 ++++++++++++++++++++------------------------ 1 file changed, 66 insertions(+), 77 deletions(-) (limited to 'protocols') diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index 52655240..deaa46df 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -92,9 +92,6 @@ char *strchr (), *strrchr (); static void yahoo_process_auth_response(struct http_request *req); -/* What's this used for actually? */ -static void _yahoo_http_connected(int id, int fd, int error, void *data); - #ifdef USE_STRUCT_CALLBACKS struct yahoo_callbacks *yc=NULL; @@ -1532,6 +1529,7 @@ static void yahoo_process_buddy_list(struct yahoo_input_data *yid, struct yahoo_ last_packet = 1; break; case 65: + g_free(cur_group); cur_group = strdup(pair->value); break; case 7: @@ -1550,6 +1548,8 @@ static void yahoo_process_buddy_list(struct yahoo_input_data *yid, struct yahoo_ break; } } + + g_free(cur_group); /* we could be getting multiple packets here */ if (last_packet) @@ -1557,7 +1557,6 @@ static void yahoo_process_buddy_list(struct yahoo_input_data *yid, struct yahoo_ YAHOO_CALLBACK(ext_yahoo_got_buddies)(yd->client_id, yd->buddies); - /*** We login at the very end of the packet communication */ if (!yd->logged_in) { yd->logged_in = TRUE; @@ -1636,7 +1635,6 @@ static void yahoo_process_list(struct yahoo_input_data *yid, struct yahoo_packet yd->cookie_c = getcookie(pair->value); } - // if(yd->cookie_y && yd->cookie_t && yd->cookie_c) if(yd->cookie_y && yd->cookie_t) YAHOO_CALLBACK(ext_yahoo_got_cookies)(yd->client_id); @@ -3644,7 +3642,7 @@ static void yahoo_process_webcam_connection(struct yahoo_input_data *yid, int ov && yahoo_get_webcam_data(yid) == 1); } -//#define LOG(x...) printf x +/* #define LOG(x...) printf x */ static void yahoo_process_auth_response(struct http_request *req) { @@ -3655,15 +3653,22 @@ static void yahoo_process_auth_response(struct http_request *req) int error_code = 0; int is_ymsgr = 0; - struct yahoo_data *yd = NULL; struct yahoo_input_data *yid = req->data; - unsigned char crypt_hash[25]; + char crypt_hash[25]; md5_byte_t result[16]; md5_state_t ctx; - struct yahoo_packet *packet =NULL; + struct yahoo_packet *packet = NULL; + + if (y_list_find(inputs, yid) == NULL) + return; + + if (req->status_code != 200) { + error_code = 3000 + req->status_code; + goto FAIL; + } token = req->reply_body; line_end = strstr(token, "\r\n"); @@ -3671,54 +3676,46 @@ static void yahoo_process_auth_response(struct http_request *req) if (line_end) { *line_end = '\0'; - line_end+=2; + line_end += 2; + } + + if (sscanf(token, "%d", &error_code) != 1) { + error_code = 3000; + goto FAIL; } - - error_code = atoi((char *)token); switch(error_code) { case 0: /* successful */ - LOG(("successful\n")); break; + case 1212: - /* Incorrect ID or password */ LOG(("Incorrect ID or password\n")); + error_code = YAHOO_LOGIN_PASSWD; + goto FAIL; - return; case 1213: - /* Security lock from too many failed login attempts */ LOG(("Security lock from too many failed login attempts\n")); - - return; + error_code = YAHOO_LOGIN_LOCK; + goto FAIL; case 1214: - /* Security lock */ LOG(("Security lock\n")); - - return; + goto FAIL; case 1235: - /* User ID not taken yet */ LOG(("User ID not taken yet\n")); - - return; + error_code = YAHOO_LOGIN_UNAME; + goto FAIL; case 1216: - /* Seems to be a lock, but shows the same generic User ID/Password failure */ LOG(("Seems to be a lock, but shows the same generic User ID/Password failure\n")); + goto FAIL; - return; - case 100: - /* Username and password cannot be blank */ - LOG(("Username and password cannot be blank\n")); - - return; default: /* Unknown error code */ LOG(("Unknown Error\n")); - - return; + goto FAIL; } if ( !strncmp(line_end, "ymsgr=", 6) ) { @@ -3727,8 +3724,8 @@ static void yahoo_process_auth_response(struct http_request *req) else if ( strncmp(line_end, "crumb=", 6) ) { LOG(("Oops! There was no ymsgr=. Where do I get my token from now :(")); LOG(("I got this:\n\n%s\n",line_end)); - return; - /* Error */ + error_code = 2201; + goto FAIL; } token = line_end+6; @@ -3737,7 +3734,7 @@ static void yahoo_process_auth_response(struct http_request *req) if(line_end) { *line_end = '\0'; - line_end+=2; + line_end += 2; } /* Go for the crumb */ @@ -3747,8 +3744,9 @@ static void yahoo_process_auth_response(struct http_request *req) url = g_strdup_printf( "https://login.yahoo.com/config/pwtoken_login?" "src=ymsgr&ts=&token=%s", token); - + http_dorequest_url(url, yahoo_process_auth_response, yid); + g_free(url); return; @@ -3760,59 +3758,45 @@ static void yahoo_process_auth_response(struct http_request *req) /* We did not get our cookies. Cry. */ } - cookie = strstr(req->reply_headers, "Set-Cookie: Y="); - - if(!cookie) { + if((cookie = strstr(req->reply_headers, "Set-Cookie: Y=")) && + (line_end = strstr(cookie + 14, "\r\n"))) { + *line_end = '\0'; + yid->yd->cookie_y = strdup(cookie + 14); + *line_end = ';'; + } else { /* Cry. */ LOG(("NO Y Cookie!")); - return; + error_code = 2202; + goto FAIL; } - cookie+=14; - - line_end = strstr(cookie, "\r\n"); - *line_end = '\0'; - - LOG(("Cookie length: %d", strlen(cookie))); - - yid->yd->cookie_y = strdup(cookie); - *line_end = ';'; - - cookie = strstr(req->reply_headers, "Set-Cookie: T="); - if(!cookie) { - LOG(("NO T Cookie!")); + if((cookie = strstr(req->reply_headers, "Set-Cookie: T=")) && + (line_end = strstr(cookie + 14, "\r\n"))) { + *line_end = '\0'; + yid->yd->cookie_t = strdup(cookie + 14); + *line_end = ';'; + } else { /* Cry. */ - return; + LOG(("NO T Cookie!")); + error_code = 2203; + goto FAIL; } - cookie+=14; - - line_end = strstr(cookie, "\r\n"); - *line_end = '\0'; - - yid->yd->cookie_t = strdup(cookie); - - LOG(("My Cookies ::\n Y: %s\nT: %s\n\n", yid->yd->cookie_y, yid->yd->cookie_t)); - md5_init(&ctx); md5_append(&ctx, (md5_byte_t *)token, strlen(token)); md5_append(&ctx, (md5_byte_t *)yid->yd->login_cookie, strlen(yid->yd->login_cookie)); md5_finish(&ctx, result); - to_y64(crypt_hash, result, 16); - - yd = yid->yd; + to_y64((unsigned char*)crypt_hash, result, 16); - //yid = find_input_by_id_and_type(yd->client_id, YAHOO_CONNECTION_PAGER); - - packet = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->initial_status, yd->session_id); - yahoo_packet_hash(packet, 1, yd->user); - yahoo_packet_hash(packet, 0, yd->user); - yahoo_packet_hash(packet, 277, yd->cookie_y); - yahoo_packet_hash(packet, 278, yd->cookie_t); + packet = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yid->yd->initial_status, yid->yd->session_id); + yahoo_packet_hash(packet, 1, yid->yd->user); + yahoo_packet_hash(packet, 0, yid->yd->user); + yahoo_packet_hash(packet, 277, yid->yd->cookie_y); + yahoo_packet_hash(packet, 278, yid->yd->cookie_t); yahoo_packet_hash(packet, 307, crypt_hash); yahoo_packet_hash(packet, 244, "2097087"); /* Rekkanoryo says this is the build number */ - yahoo_packet_hash(packet, 2, yd->user); + yahoo_packet_hash(packet, 2, yid->yd->user); yahoo_packet_hash(packet, 2, "1"); yahoo_packet_hash(packet, 98, "us"); /* TODO Put country code */ yahoo_packet_hash(packet, 135, "9.0.0.1389"); @@ -3822,8 +3806,13 @@ static void yahoo_process_auth_response(struct http_request *req) yahoo_packet_free(packet); /* We don't need this anymore */ - free(yd->login_cookie); - yd->login_cookie = NULL; + free(yid->yd->login_cookie); + yid->yd->login_cookie = NULL; + + return; + +FAIL: + YAHOO_CALLBACK(ext_yahoo_login_response)(yid->yd->client_id, error_code, NULL); } -- cgit v1.2.3 From bdad4079b4bbc8209bf17c81cafbf699f8c6d90d Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 4 Oct 2009 19:28:41 +0100 Subject: Fixing a crash bug that causes crashes only with buggy Jabber conference servers, sending a "you left this chat" without first acknowledging you entering it. --- protocols/jabber/conference.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'protocols') diff --git a/protocols/jabber/conference.c b/protocols/jabber/conference.c index 08bef4f5..f434c58a 100644 --- a/protocols/jabber/conference.c +++ b/protocols/jabber/conference.c @@ -284,12 +284,15 @@ void jabber_chat_pkt_presence( struct im_connection *ic, struct jabber_buddy *bu } else if( type ) /* type can only be NULL or "unavailable" in this function */ { - s = strchr( bud->ext_jid, '/' ); - if( s ) *s = 0; - imcb_chat_remove_buddy( chat, bud->ext_jid, NULL ); - if( bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS ) - imcb_remove_buddy( ic, bud->ext_jid, NULL ); - if( s ) *s = '/'; + if( ( bud->flags & JBFLAG_IS_CHATROOM ) && bud->ext_jid ) + { + s = strchr( bud->ext_jid, '/' ); + if( s ) *s = 0; + imcb_chat_remove_buddy( chat, bud->ext_jid, NULL ); + if( bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS ) + imcb_remove_buddy( ic, bud->ext_jid, NULL ); + if( s ) *s = '/'; + } if( bud == jc->me ) jabber_chat_free( chat ); -- cgit v1.2.3 From fa295e3620bdf928b6a853ec7e42b8c7fc5262be Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 10 Oct 2009 14:39:51 +0100 Subject: Added imcb_ask_auth() instead of reimplementing authorization requests in every protocol module. --- protocols/nogaim.c | 61 +++++++++++++++++++++++++++++++++++++++++++----------- protocols/nogaim.h | 13 +++++++++++- 2 files changed, 61 insertions(+), 13 deletions(-) (limited to 'protocols') diff --git a/protocols/nogaim.c b/protocols/nogaim.c index fd445324..710b7645 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -505,33 +505,70 @@ void imcb_buddy_nick_hint( struct im_connection *ic, char *handle, char *nick ) } } -/* prpl.c */ -struct show_got_added_data +struct imcb_ask_cb_data { struct im_connection *ic; char *handle; }; -void show_got_added_no( void *data ) +static void imcb_ask_auth_cb_no( void *data ) { - g_free( ((struct show_got_added_data*)data)->handle ); + struct imcb_ask_cb_data *cbd = data; + + cbd->ic->acc->prpl->auth_deny( cbd->ic, cbd->handle ); + + g_free( cbd->handle ); + g_free( cbd ); +} + +static void imcb_ask_auth_cb_yes( void *data ) +{ + struct imcb_ask_cb_data *cbd = data; + + cbd->ic->acc->prpl->auth_allow( cbd->ic, cbd->handle ); + + g_free( cbd->handle ); + g_free( cbd ); +} + +void imcb_ask_auth( struct im_connection *ic, const char *handle, const char *realname ) +{ + struct imcb_ask_cb_data *data = g_new0( struct imcb_ask_cb_data, 1 ); + char *s, *realname_ = NULL; + + if( realname != NULL ) + realname_ = g_strdup_printf( " (%s)", realname ); + + s = g_strdup_printf( "The user %s%s wants to add you to his/her buddy list.", + handle, realname_ ?: "" ); + + g_free( realname_ ); + + data->ic = ic; + data->handle = g_strdup( handle ); + query_add( ic->irc, ic, s, imcb_ask_auth_cb_yes, imcb_ask_auth_cb_no, data ); +} + + +static void imcb_ask_add_cb_no( void *data ) +{ + g_free( ((struct imcb_ask_cb_data*)data)->handle ); g_free( data ); } -void show_got_added_yes( void *data ) +static void imcb_ask_add_cb_yes( void *data ) { - struct show_got_added_data *sga = data; + struct imcb_ask_cb_data *cbd = data; - sga->ic->acc->prpl->add_buddy( sga->ic, sga->handle, NULL ); - /* imcb_add_buddy( sga->ic, NULL, sga->handle, sga->handle ); */ + cbd->ic->acc->prpl->add_buddy( cbd->ic, cbd->handle, NULL ); - return show_got_added_no( data ); + return imcb_ask_add_cb_no( data ); } -void imcb_ask_add( struct im_connection *ic, char *handle, const char *realname ) +void imcb_ask_add( struct im_connection *ic, const char *handle, const char *realname ) { - struct show_got_added_data *data = g_new0( struct show_got_added_data, 1 ); + struct imcb_ask_cb_data *data = g_new0( struct imcb_ask_cb_data, 1 ); char *s; /* TODO: Make a setting for this! */ @@ -542,7 +579,7 @@ void imcb_ask_add( struct im_connection *ic, char *handle, const char *realname data->ic = ic; data->handle = g_strdup( handle ); - query_add( ic->irc, ic, s, show_got_added_yes, show_got_added_no, data ); + query_add( ic->irc, ic, s, imcb_ask_add_cb_yes, imcb_ask_add_cb_no, data ); } diff --git a/protocols/nogaim.h b/protocols/nogaim.h index ddfff07e..1e5df503 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -223,6 +223,10 @@ struct prpl { /* Mainly for AOL, since they think "Bung hole" == "Bu ngho le". *sigh* * - Most protocols will just want to set this to g_strcasecmp().*/ int (* handle_cmp) (const char *who1, const char *who2); + + /* Implement these callbacks if you want to use imcb_ask_auth() */ + void (* auth_allow) (struct im_connection *, const char *who); + void (* auth_deny) (struct im_connection *, const char *who); }; /* im_api core stuff. */ @@ -251,13 +255,20 @@ G_MODULE_EXPORT void imc_logout( struct im_connection *ic, int allow_reconnect ) G_MODULE_EXPORT void imcb_log( struct im_connection *ic, char *format, ... ) G_GNUC_PRINTF( 2, 3 ); /* To tell the user an error, ie. before logging out when an error occurs. */ G_MODULE_EXPORT void imcb_error( struct im_connection *ic, char *format, ... ) G_GNUC_PRINTF( 2, 3 ); + /* To ask a your about something. * - 'msg' is the question. * - 'data' can be your custom struct - it will be passed to the callbacks. * - 'doit' or 'dont' will be called depending of the answer of the user. */ G_MODULE_EXPORT void imcb_ask( struct im_connection *ic, char *msg, void *data, query_callback doit, query_callback dont ); -G_MODULE_EXPORT void imcb_ask_add( struct im_connection *ic, char *handle, const char *realname ); + +/* Two common questions you may want to ask: + * - X added you to his contact list, allow? + * - X is not in your contact list, want to add? + */ +G_MODULE_EXPORT void imcb_ask_auth( struct im_connection *ic, const char *handle, const char *realname ); +G_MODULE_EXPORT void imcb_ask_add( struct im_connection *ic, const char *handle, const char *realname ); /* Buddy management */ /* This function should be called for each handle which are visible to the -- cgit v1.2.3 From ba168953ffe832133cf236df73e574fa54f8d911 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 10 Oct 2009 14:48:44 +0100 Subject: More Yahoo! fixes: Adding and removing buddies works, and for the first time buddy add requests are actually handled; from what I can see this simply didn't exist in libyahoo2 yet so far. :-( I melded pieces of changes from http://geny.sf.net/ to make this stuff work. --- protocols/yahoo/libyahoo2.c | 147 ++++++++++++++++++++++++++++--------- protocols/yahoo/yahoo.c | 30 +++++++- protocols/yahoo/yahoo2.h | 3 + protocols/yahoo/yahoo2_callbacks.h | 12 +++ protocols/yahoo/yahoo2_types.h | 16 +++- 5 files changed, 167 insertions(+), 41 deletions(-) (limited to 'protocols') diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index deaa46df..d6cab9e1 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -211,33 +211,23 @@ enum yahoo_service { /* these are easier to see in hex */ YAHOO_SERVICE_CHATLOGOUT = 0xa0, YAHOO_SERVICE_CHATPING, YAHOO_SERVICE_COMMENT = 0xa8, - YAHOO_SERVICE_GAME_INVITE = 0xb7, - YAHOO_SERVICE_STEALTH_PERM = 0xb9, - YAHOO_SERVICE_STEALTH_SESSION = 0xba, - YAHOO_SERVICE_AVATAR = 0xbc, + YAHOO_SERVICE_STEALTH = 0xb9, YAHOO_SERVICE_PICTURE_CHECKSUM = 0xbd, YAHOO_SERVICE_PICTURE = 0xbe, YAHOO_SERVICE_PICTURE_UPDATE = 0xc1, YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2, - YAHOO_SERVICE_YAB_UPDATE = 0xc4, - YAHOO_SERVICE_Y6_VISIBLE_TOGGLE = 0xc5, /* YMSG13, key 13: 2 = invisible, 1 = visible */ - YAHOO_SERVICE_Y6_STATUS_UPDATE = 0xc6, /* YMSG13 */ - YAHOO_SERVICE_PICTURE_STATUS = 0xc7, /* YMSG13, key 213: 0 = none, 1 = avatar, 2 = picture */ - YAHOO_SERVICE_VERIFY_ID_EXISTS = 0xc8, - YAHOO_SERVICE_AUDIBLE = 0xd0, - YAHOO_SERVICE_Y7_PHOTO_SHARING = 0xd2, - YAHOO_SERVICE_Y7_CONTACT_DETAILS = 0xd3,/* YMSG13 */ - YAHOO_SERVICE_Y7_CHAT_SESSION = 0xd4, - YAHOO_SERVICE_Y7_AUTHORIZATION = 0xd6, /* YMSG13 */ - YAHOO_SERVICE_Y7_FILETRANSFER = 0xdc, /* YMSG13 */ - YAHOO_SERVICE_Y7_FILETRANSFERINFO, /* YMSG13 */ - YAHOO_SERVICE_Y7_FILETRANSFERACCEPT, /* YMSG13 */ - YAHOO_SERVICE_Y7_MINGLE = 0xe1, /* YMSG13 */ - YAHOO_SERVICE_Y7_CHANGE_GROUP = 0xe7, /* YMSG13 */ - YAHOO_SERVICE_Y8_STATUS = 0xf0, /* YMSG15 */ - YAHOO_SERVICE_Y8_LIST = 0Xf1, /* YMSG15 */ - YAHOO_SERVICE_WEBLOGIN = 0x0226, - YAHOO_SERVICE_SMS_MSG = 0x02ea + YAHOO_SERVICE_Y6_VISIBILITY=0xc5, + YAHOO_SERVICE_Y6_STATUS_UPDATE=0xc6, + YAHOO_PHOTOSHARE_INIT=0xd2, + YAHOO_SERVICE_CONTACT_YMSG13=0xd6, + YAHOO_PHOTOSHARE_PREV=0xd7, + YAHOO_PHOTOSHARE_KEY=0xd8, + YAHOO_PHOTOSHARE_TRANS=0xda, + YAHOO_FILE_TRANSFER_INIT_YMSG13=0xdc, + YAHOO_FILE_TRANSFER_GET_YMSG13=0xdd, + YAHOO_FILE_TRANSFER_PUT_YMSG13=0xde, + YAHOO_SERVICE_YMSG15_STATUS=0xf0, + YAHOO_SERVICE_YMSG15_BUDDY_LIST=0xf1, }; struct yahoo_pair { @@ -775,7 +765,7 @@ static void yahoo_send_packet(struct yahoo_input_data *yid, struct yahoo_packet if( yid->type == YAHOO_CONNECTION_FT ) yahoo_send_data(yid->fd, data, len); else - yahoo_add_to_send_queue(yid, data, len); + yahoo_add_to_send_queue(yid, data, len); FREE(data); } @@ -1495,9 +1485,15 @@ static void yahoo_process_status(struct yahoo_input_data *yid, struct yahoo_pack struct user *u = users->data; if (u->name != NULL) { - if (pkt->service == YAHOO_SERVICE_LOGOFF || u->flags == 0) { + if (pkt->service == YAHOO_SERVICE_LOGOFF) { /* || u->flags == 0) { Not in YMSG16 */ YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, u->name, YAHOO_STATUS_OFFLINE, NULL, 1, 0, 0); } else { + /* Key 47 always seems to be 1 for YMSG16 */ + if(!u->state) + u->away = 0; + else + u->away = 1; + YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, u->name, u->state, u->msg, u->away, u->idle, u->mobile); } } @@ -2514,7 +2510,7 @@ static void yahoo_process_buddyadd(struct yahoo_input_data *yid, struct yahoo_pa bud->real_name = NULL; yd->buddies = y_list_append(yd->buddies, bud); - + /* Possibly called already, but at least the call above doesn't seem to happen every time (not anytime I tried). */ YAHOO_CALLBACK(ext_yahoo_contact_added)(yd->client_id, me, who, NULL); @@ -2523,6 +2519,26 @@ static void yahoo_process_buddyadd(struct yahoo_input_data *yid, struct yahoo_pa /* YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, who, status, NULL, (status==YAHOO_STATUS_AVAILABLE?0:1)); */ } +static void yahoo_process_contact_ymsg13(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +{ + char* who=NULL; + char* me=NULL; + char* msg=NULL; + YList *l; + for (l = pkt->hash; l; l = l->next) { + struct yahoo_pair *pair = l->data; + if (pair->key == 4) + who = pair->value; + else if (pair->key == 5) + me = pair->value; + else + DEBUG_MSG(("unknown key: %d = %s", pair->key, pair->value)); + } + + if(pkt->status==3) + YAHOO_CALLBACK(ext_yahoo_contact_auth_request)(yid->yd->client_id, me, who, msg); +} + static void yahoo_process_buddydel(struct yahoo_input_data *yid, struct yahoo_packet *pkt) { struct yahoo_data *yd = yid->yd; @@ -2734,7 +2750,7 @@ static void yahoo_process_webcam_key(struct yahoo_input_data *yid, struct yahoo_ char *who = NULL; YList *l; - yahoo_dump_unhandled(pkt); + // yahoo_dump_unhandled(pkt); for (l = pkt->hash; l; l = l->next) { struct yahoo_pair *pair = l->data; if (pair->key == 5) @@ -2756,6 +2772,7 @@ static void yahoo_process_webcam_key(struct yahoo_input_data *yid, struct yahoo_ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_packet *pkt) { DEBUG_MSG(("yahoo_packet_process: 0x%02x", pkt->service)); + yahoo_dump_unhandled(pkt); switch (pkt->service) { case YAHOO_SERVICE_USERSTAT: @@ -2768,7 +2785,7 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack case YAHOO_SERVICE_IDACT: case YAHOO_SERVICE_IDDEACT: case YAHOO_SERVICE_Y6_STATUS_UPDATE: - case YAHOO_SERVICE_Y8_STATUS: + case YAHOO_SERVICE_YMSG15_STATUS: yahoo_process_status(yid, pkt); break; case YAHOO_SERVICE_NOTIFY: @@ -2782,6 +2799,7 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack case YAHOO_SERVICE_NEWMAIL: yahoo_process_mail(yid, pkt); break; + case YAHOO_SERVICE_REJECTCONTACT: case YAHOO_SERVICE_NEWCONTACT: yahoo_process_contact(yid, pkt); break; @@ -2822,6 +2840,9 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack case YAHOO_SERVICE_ADDBUDDY: yahoo_process_buddyadd(yid, pkt); break; + case YAHOO_SERVICE_CONTACT_YMSG13: + yahoo_process_contact_ymsg13(yid,pkt); + break; case YAHOO_SERVICE_REMBUDDY: yahoo_process_buddydel(yid, pkt); break; @@ -2850,7 +2871,6 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack case YAHOO_SERVICE_CHATLOGON: case YAHOO_SERVICE_CHATLOGOFF: case YAHOO_SERVICE_CHATMSG: - case YAHOO_SERVICE_REJECTCONTACT: case YAHOO_SERVICE_PEERTOPEER: WARNING(("unhandled service 0x%02x", pkt->service)); yahoo_dump_unhandled(pkt); @@ -2864,7 +2884,7 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack case YAHOO_SERVICE_PICTURE_UPLOAD: yahoo_process_picture_upload(yid, pkt); break; - case YAHOO_SERVICE_Y8_LIST: /* Buddy List */ + case YAHOO_SERVICE_YMSG15_BUDDY_LIST: /* Buddy List */ yahoo_process_buddy_list(yid, pkt); default: WARNING(("unknown service 0x%02x", pkt->service)); @@ -4044,7 +4064,7 @@ void yahoo_send_typing(int id, const char *from, const char *who, int typ) pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_NOTIFY, yd->session_id); yahoo_packet_hash(pkt, 5, who); - yahoo_packet_hash(pkt, 4, from?from:yd->user); + yahoo_packet_hash(pkt, 1, from?from:yd->user); yahoo_packet_hash(pkt, 14, " "); yahoo_packet_hash(pkt, 13, typ ? "1" : "0"); yahoo_packet_hash(pkt, 49, "TYPING"); @@ -4346,12 +4366,24 @@ void yahoo_add_buddy(int id, const char *who, const char *group, const char *msg if (!yd->logged_in) return; - pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id); - yahoo_packet_hash(pkt, 1, yd->user); - yahoo_packet_hash(pkt, 7, who); - yahoo_packet_hash(pkt, 65, group); + pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YPACKET_STATUS_DEFAULT, yd->session_id); + if (msg != NULL) /* add message/request "it's me add me" */ yahoo_packet_hash(pkt, 14, msg); + else + yahoo_packet_hash(pkt,14,""); + + yahoo_packet_hash(pkt, 65, group); + yahoo_packet_hash(pkt, 97, "1"); + yahoo_packet_hash(pkt, 1, yd->user); + yahoo_packet_hash(pkt, 302, "319"); + yahoo_packet_hash(pkt, 300, "319"); + yahoo_packet_hash(pkt, 7, who); + yahoo_packet_hash(pkt, 334, "0"); + yahoo_packet_hash(pkt, 301, "319"); + yahoo_packet_hash(pkt, 303, "319"); + + yahoo_send_packet(yid, pkt, 0); yahoo_packet_free(pkt); } @@ -4375,6 +4407,49 @@ void yahoo_remove_buddy(int id, const char *who, const char *group) yahoo_packet_free(pkt); } +void yahoo_accept_buddy_ymsg13(int id,const char* me,const char* who){ + struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_data *yd; + + if(!yid) + return; + yd = yid->yd; + + struct yahoo_packet* pkt=NULL; + pkt= yahoo_packet_new(YAHOO_SERVICE_CONTACT_YMSG13,YAHOO_STATUS_AVAILABLE,0); + + yahoo_packet_hash(pkt,1,me ?: yd->user); + yahoo_packet_hash(pkt,5,who); + yahoo_packet_hash(pkt,13,"1"); + yahoo_packet_hash(pkt,334,"0"); + yahoo_send_packet(yid, pkt, 0); + yahoo_packet_free(pkt); +} + +void yahoo_reject_buddy_ymsg13(int id,const char* me,const char* who,const char* msg){ + struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_data *yd; + + if(!yid) + return; + yd = yid->yd; + + struct yahoo_packet* pkt=NULL; + pkt= yahoo_packet_new(YAHOO_SERVICE_CONTACT_YMSG13,YAHOO_STATUS_AVAILABLE,0); + + yahoo_packet_hash(pkt,1,me ?: yd->user); + yahoo_packet_hash(pkt,5,who); +// yahoo_packet_hash(pkt,241,YAHOO_PROTO_VER); + yahoo_packet_hash(pkt,13,"2"); + yahoo_packet_hash(pkt,334,"0"); + yahoo_packet_hash(pkt,97,"1"); + yahoo_packet_hash(pkt,14,msg?:""); + + yahoo_send_packet(yid, pkt, 0); + yahoo_packet_free(pkt); + +} + void yahoo_reject_buddy(int id, const char *who, const char *msg) { struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); @@ -4430,7 +4505,7 @@ void yahoo_stealth_buddy(int id, const char *who, int unstealth) if (!yd->logged_in) return; - pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH_PERM, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH, YAHOO_STATUS_AVAILABLE, yd->session_id); yahoo_packet_hash(pkt, 1, yd->user); yahoo_packet_hash(pkt, 7, who); yahoo_packet_hash(pkt, 31, unstealth?"2":"1"); diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c index 3e844c55..ea1b4dec 100644 --- a/protocols/yahoo/yahoo.c +++ b/protocols/yahoo/yahoo.c @@ -347,6 +347,20 @@ static struct groupchat *byahoo_chat_with( struct im_connection *ic, char *who ) return c; } +static void byahoo_auth_allow( struct im_connection *ic, const char *who ) +{ + struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data; + + yahoo_accept_buddy_ymsg13( yd->y2_id, NULL, who ); +} + +static void byahoo_auth_deny( struct im_connection *ic, const char *who ) +{ + struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data; + + yahoo_reject_buddy_ymsg13( yd->y2_id, NULL, who, NULL ); +} + void byahoo_initmodule( ) { struct prpl *ret = g_new0(struct prpl, 1); @@ -372,6 +386,9 @@ void byahoo_initmodule( ) ret->handle_cmp = g_strcasecmp; + ret->auth_allow = byahoo_auth_allow; + ret->auth_deny = byahoo_auth_deny; + register_protocol(ret); } @@ -921,11 +938,18 @@ void ext_yahoo_chat_yahooerror( int id, const char *me ) { } +void ext_yahoo_contact_auth_request( int id, const char *myid, const char *who, const char *msg ) +{ + struct im_connection *ic = byahoo_get_ic_by_id( id ); + + imcb_ask_auth( ic, who, NULL ); +} + void ext_yahoo_contact_added( int id, const char *myid, const char *who, const char *msg ) { - /* Groups schmoups. If I want to handle groups properly I can get the - buddy data from some internal libyahoo2 structure. */ - imcb_add_buddy( byahoo_get_ic_by_id( id ), (char*) who, NULL ); + struct im_connection *ic = byahoo_get_ic_by_id( id ); + + imcb_add_buddy( ic, (char*) who, NULL ); } void ext_yahoo_rejected( int id, const char *who, const char *msg ) diff --git a/protocols/yahoo/yahoo2.h b/protocols/yahoo/yahoo2.h index e54e09fb..2184a321 100644 --- a/protocols/yahoo/yahoo2.h +++ b/protocols/yahoo/yahoo2.h @@ -216,6 +216,9 @@ const char * yahoo_get_profile_url( void ); void yahoo_buddyicon_request(int id, const char *who); +void yahoo_accept_buddy_ymsg13(int,const char*,const char*); +void yahoo_reject_buddy_ymsg13(int,const char*,const char*,const char*); + #include "yahoo_httplib.h" #ifdef __cplusplus diff --git a/protocols/yahoo/yahoo2_callbacks.h b/protocols/yahoo/yahoo2_callbacks.h index b7f4e99b..e2c8ea42 100644 --- a/protocols/yahoo/yahoo2_callbacks.h +++ b/protocols/yahoo/yahoo2_callbacks.h @@ -359,6 +359,18 @@ void YAHOO_CALLBACK_TYPE(ext_yahoo_conf_message)(int id, const char *me, const c void YAHOO_CALLBACK_TYPE(ext_yahoo_got_file)(int id, const char *me, const char *who, const char *url, long expires, const char *msg, const char *fname, unsigned long fesize); +/* + * Name: ext_yahoo_contact_auth_request + * Called when a contact wants to add you to his/her contact list + * Params: + * id - the id that identifies the server connection + * myid - the identity s/he added + * who - who did it + * msg - any message sent + */ +void YAHOO_CALLBACK_TYPE(ext_yahoo_contact_auth_request)(int id, const char *myid, const char *who, const char *msg); + + /* * Name: ext_yahoo_contact_added * Called when a contact is added to your list diff --git a/protocols/yahoo/yahoo2_types.h b/protocols/yahoo/yahoo2_types.h index 7453e487..3507e13a 100644 --- a/protocols/yahoo/yahoo2_types.h +++ b/protocols/yahoo/yahoo2_types.h @@ -56,7 +56,20 @@ enum yahoo_login_status { YAHOO_LOGIN_PASSWD = 13, YAHOO_LOGIN_LOCK = 14, YAHOO_LOGIN_DUPL = 99, - YAHOO_LOGIN_SOCK = -1 + YAHOO_LOGIN_SOCK = -1, +}; + +enum ypacket_status { + YPACKET_STATUS_DISCONNECTED = -1, + YPACKET_STATUS_DEFAULT = 0, + YPACKET_STATUS_SERVERACK = 1, + YPACKET_STATUS_GAME = 0x2, + YPACKET_STATUS_AWAY = 0x4, + YPACKET_STATUS_CONTINUED = 0x5, + YPACKET_STATUS_INVISIBLE = 12, + YPACKET_STATUS_NOTIFY = 0x16, /* TYPING */ + YPACKET_STATUS_WEBLOGIN = 0x5a55aa55, + YPACKET_STATUS_OFFLINE = 0x5a55aa56 }; enum yahoo_error { @@ -132,7 +145,6 @@ enum yahoo_stealth_visibility_type { /* chat member attribs */ #define YAHOO_CHAT_MALE 0x8000 #define YAHOO_CHAT_FEMALE 0x10000 -#define YAHOO_CHAT_FEMALE 0x10000 #define YAHOO_CHAT_DUNNO 0x400 #define YAHOO_CHAT_WEBCAM 0x10 -- cgit v1.2.3 From 037b66a34beef59e7c591ee868516f2305cea906 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 10 Oct 2009 15:57:05 +0100 Subject: Fixed an ugly bug in the write handler that may have caused many weird bugs for a while already by only sending one packet even if more of them were generated during an event cycle. --- protocols/yahoo/yahoo.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'protocols') diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c index ea1b4dec..96f619ed 100644 --- a/protocols/yahoo/yahoo.c +++ b/protocols/yahoo/yahoo.c @@ -468,9 +468,7 @@ gboolean byahoo_write_ready_callback( gpointer data, gint source, b_input_condit { struct byahoo_write_ready_data *d = data; - yahoo_write_ready( d->id, d->fd, d->data ); - - return FALSE; + return yahoo_write_ready( d->id, d->fd, d->data ); } void ext_yahoo_login_response( int id, int succ, const char *url ) -- cgit v1.2.3 From 7ea8697c345d5d1e3f237a392b293abca948cdfa Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 10 Oct 2009 16:00:16 +0100 Subject: Setting Yahoo! away states works again. --- protocols/yahoo/libyahoo2.c | 53 +++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 23 deletions(-) (limited to 'protocols') diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index d6cab9e1..e7005e38 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -4079,7 +4079,7 @@ void yahoo_set_away(int id, enum yahoo_status state, const char *msg, int away) struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt = NULL; - int service; + int old_status; char s[4]; if(!yid) @@ -4087,38 +4087,45 @@ void yahoo_set_away(int id, enum yahoo_status state, const char *msg, int away) yd = yid->yd; - if (msg) { + old_status = yd->current_status; + + if (msg && strncmp(msg,"Invisible",9)) { yd->current_status = YAHOO_STATUS_CUSTOM; } else { yd->current_status = state; } - if (yd->current_status == YAHOO_STATUS_AVAILABLE) - service = YAHOO_SERVICE_ISBACK; - else - service = YAHOO_SERVICE_ISAWAY; + /* Thank you libpurple :) */ + if (yd->current_status == YAHOO_STATUS_INVISIBLE) { + pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0); + yahoo_packet_hash(pkt, 13, "2"); + yahoo_send_packet(yid, pkt, 0); + yahoo_packet_free(pkt); + + return; + } + + pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, yd->current_status, yd->session_id); + snprintf(s, sizeof(s), "%d", yd->current_status); + yahoo_packet_hash(pkt, 10, s); - if ((away == 2) && (yd->current_status == YAHOO_STATUS_AVAILABLE)) { - pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_BRB, yd->session_id); - yahoo_packet_hash(pkt, 10, "999"); - yahoo_packet_hash(pkt, 47, "2"); - }else { - pkt = yahoo_packet_new(service, YAHOO_STATUS_AVAILABLE, yd->session_id); - snprintf(s, sizeof(s), "%d", yd->current_status); - yahoo_packet_hash(pkt, 10, s); - if (yd->current_status == YAHOO_STATUS_CUSTOM) { - yahoo_packet_hash(pkt, 19, msg); - yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0"); - } else { - yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0"); - } - - - + if (yd->current_status == YAHOO_STATUS_CUSTOM) { + yahoo_packet_hash(pkt, 19, msg); + } else { + yahoo_packet_hash(pkt, 19, ""); } + + yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0"); yahoo_send_packet(yid, pkt, 0); yahoo_packet_free(pkt); + + if(old_status == YAHOO_STATUS_INVISIBLE) { + pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0); + yahoo_packet_hash(pkt, 13, "1"); + yahoo_send_packet(yid, pkt, 0); + yahoo_packet_free(pkt); + } } void yahoo_logoff(int id) -- cgit v1.2.3 From e71cfbc35f3d2f3aa4da9e72776505d945429cbe Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Tue, 13 Oct 2009 23:33:12 +0100 Subject: Turns out I *did* implement HTTPS auth for Yahoo! myself already, but I kept it as a patch somewhere in my homedir because I thought I didn't need it. I like this code more so I'll use it instead. --- protocols/yahoo/libyahoo2.c | 362 ++++++++++++++++++++++---------------------- 1 file changed, 178 insertions(+), 184 deletions(-) (limited to 'protocols') diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index e7005e38..1d943df7 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -90,8 +90,6 @@ char *strchr (), *strrchr (); #include "base64.h" #include "http_client.h" -static void yahoo_process_auth_response(struct http_request *req); - #ifdef USE_STRUCT_CALLBACKS struct yahoo_callbacks *yc=NULL; @@ -2308,22 +2306,193 @@ static void yahoo_process_auth_0x0b(struct yahoo_input_data *yid, const char *se free(crypt_hash); } +struct yahoo_https_auth_data +{ + struct yahoo_input_data *yid; + char *token; + char *chal; +}; + +static void yahoo_https_auth_token_init(struct yahoo_https_auth_data *had); +static void yahoo_https_auth_token_finish(struct http_request *req); +static void yahoo_https_auth_init(struct yahoo_https_auth_data *had); +static void yahoo_https_auth_finish(struct http_request *req); + +/* Extract a value from a login.yahoo.com response. Assume CRLF-linebreaks + and FAIL miserably if they're not there... */ +static char *yahoo_ha_find_key(char *response, char *key) +{ + char *s, *end; + int len = strlen(key); + + s = response; + do { + if (strncmp(s, key, len) == 0 && s[len] == '=') { + s += len + 1; + if ((end = strchr(s, '\r'))) + return g_strndup(s, end - s); + else + return g_strdup(s); + } + + if ((s = strchr(s, '\n'))) + s ++; + } while (s && *s); + + return NULL; +} + +static enum yahoo_status yahoo_https_status_parse(int code) +{ + switch (code) + { + case 1212: return YAHOO_LOGIN_PASSWD; + case 1213: return YAHOO_LOGIN_LOCK; + case 1235: return YAHOO_LOGIN_UNAME; + default: return (enum yahoo_status) code; + } +} + static void yahoo_process_auth_0x10(struct yahoo_input_data *yid, const char *seed, const char *sn) { - char *url; + struct yahoo_https_auth_data *had = g_new0(struct yahoo_https_auth_data, 1); + + had->yid = yid; + had->chal = g_strdup(seed); + + yahoo_https_auth_token_init(had); +} - yid->yd->login_cookie = strdup(seed); +static void yahoo_https_auth_token_init(struct yahoo_https_auth_data *had) +{ + struct yahoo_input_data *yid = had->yid; + struct yahoo_data *yd = yid->yd; + struct http_request *req; + char *login, *passwd, *chal; + char *url; + + login = g_strndup(yd->user, 3 * strlen(yd->user)); + http_encode(login); + passwd = g_strndup(yd->password, 3 * strlen(yd->password)); + http_encode(passwd); + chal = g_strndup(had->chal, 3 * strlen(had->chal)); + http_encode(chal); + + url = g_strdup_printf("https://login.yahoo.com/config/pwtoken_get?src=ymsgr&ts=%d&login=%s&passwd=%s&chal=%s", + (int) time(NULL), login, passwd, chal); + + req = http_dorequest_url(url, yahoo_https_auth_token_finish, had); + + g_free(url); + g_free(chal); + g_free(passwd); + g_free(login); +} - url = g_strdup_printf( - "https://login.yahoo.com/config/pwtoken_get?" - "src=ymsgr&ts=&login=%s&passwd=%s&chal=%s", - yid->yd->user, yid->yd->password, seed); +static void yahoo_https_auth_token_finish(struct http_request *req) +{ + struct yahoo_https_auth_data *had = req->data; + struct yahoo_input_data *yid = had->yid; + struct yahoo_data *yd = yid->yd; + int st; + + if (req->status_code != 200) { + YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 2000 + req->status_code, NULL); + goto fail; + } + + if (sscanf(req->reply_body, "%d", &st) != 1 || st != 0) { + YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, yahoo_https_status_parse(st), NULL); + goto fail; + } + + if ((had->token = yahoo_ha_find_key(req->reply_body, "ymsgr")) == NULL) { + YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 3001, NULL); + goto fail; + } + + return yahoo_https_auth_init(had); + +fail: + g_free(had->token); + g_free(had->chal); + g_free(had); +} - http_dorequest_url(url, yahoo_process_auth_response, yid); +static void yahoo_https_auth_init(struct yahoo_https_auth_data *had) +{ + struct http_request *req; + char *url; + + url = g_strdup_printf("https://login.yahoo.com/config/pwtoken_login?src=ymsgr&ts=%d&token=%s", + (int) time(NULL), had->token); + + req = http_dorequest_url(url, yahoo_https_auth_finish, had); g_free(url); } +static void yahoo_https_auth_finish(struct http_request *req) +{ + struct yahoo_https_auth_data *had = req->data; + struct yahoo_input_data *yid = had->yid; + struct yahoo_data *yd = yid->yd; + struct yahoo_packet *pack; + char *crumb; + int st; + + md5_byte_t result[16]; + md5_state_t ctx; + + unsigned char yhash[32]; + + if (req->status_code != 200) { + YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 2000 + req->status_code, NULL); + goto fail; + } + + if (sscanf(req->reply_body, "%d", &st) != 1 || st != 0) { + YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, yahoo_https_status_parse(st), NULL); + goto fail; + } + + if ((yd->cookie_y = yahoo_ha_find_key(req->reply_body, "Y")) == NULL || + (yd->cookie_t = yahoo_ha_find_key(req->reply_body, "T")) == NULL || + (crumb = yahoo_ha_find_key(req->reply_body, "crumb")) == NULL) { + YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 3002, NULL); + goto fail; + } + + md5_init(&ctx); + md5_append(&ctx, (unsigned char*) crumb, 11); + md5_append(&ctx, (unsigned char*) had->chal, strlen(had->chal)); + md5_finish(&ctx, result); + to_y64(yhash, result, 16); + + pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->initial_status, yd->session_id); + yahoo_packet_hash(pack, 1, yd->user); + yahoo_packet_hash(pack, 0, yd->user); + yahoo_packet_hash(pack, 277, yd->cookie_y); + yahoo_packet_hash(pack, 278, yd->cookie_t); + yahoo_packet_hash(pack, 307, (char*) yhash); + yahoo_packet_hash(pack, 244, "524223"); + yahoo_packet_hash(pack, 2, yd->user); + yahoo_packet_hash(pack, 2, "1"); + yahoo_packet_hash(pack, 98, "us"); + yahoo_packet_hash(pack, 135, "7.5.0.647"); + + yahoo_send_packet(yid, pack, 0); + + yahoo_packet_free(pack); + + return; + +fail: + g_free(had->token); + g_free(had->chal); + g_free(had); +} + static void yahoo_process_auth(struct yahoo_input_data *yid, struct yahoo_packet *pkt) { char *seed = NULL; @@ -2353,7 +2522,6 @@ static void yahoo_process_auth(struct yahoo_input_data *yid, struct yahoo_packet yahoo_process_auth_0x0b(yid, seed, sn); break; case 2: - /* HTTPS */ yahoo_process_auth_0x10(yid, seed, sn); break; default: @@ -3662,180 +3830,6 @@ static void yahoo_process_webcam_connection(struct yahoo_input_data *yid, int ov && yahoo_get_webcam_data(yid) == 1); } -/* #define LOG(x...) printf x */ - -static void yahoo_process_auth_response(struct http_request *req) -{ - char *line_end; - char *token; - char *cookie; - - int error_code = 0; - int is_ymsgr = 0; - - struct yahoo_input_data *yid = req->data; - - char crypt_hash[25]; - - md5_byte_t result[16]; - md5_state_t ctx; - - struct yahoo_packet *packet = NULL; - - if (y_list_find(inputs, yid) == NULL) - return; - - if (req->status_code != 200) { - error_code = 3000 + req->status_code; - goto FAIL; - } - - token = req->reply_body; - line_end = strstr(token, "\r\n"); - - if (line_end) { - *line_end = '\0'; - - line_end += 2; - } - - if (sscanf(token, "%d", &error_code) != 1) { - error_code = 3000; - goto FAIL; - } - - switch(error_code) { - case 0: - /* successful */ - break; - - case 1212: - LOG(("Incorrect ID or password\n")); - error_code = YAHOO_LOGIN_PASSWD; - goto FAIL; - - case 1213: - LOG(("Security lock from too many failed login attempts\n")); - error_code = YAHOO_LOGIN_LOCK; - goto FAIL; - - case 1214: - LOG(("Security lock\n")); - goto FAIL; - - case 1235: - LOG(("User ID not taken yet\n")); - error_code = YAHOO_LOGIN_UNAME; - goto FAIL; - - case 1216: - LOG(("Seems to be a lock, but shows the same generic User ID/Password failure\n")); - goto FAIL; - - default: - /* Unknown error code */ - LOG(("Unknown Error\n")); - goto FAIL; - } - - if ( !strncmp(line_end, "ymsgr=", 6) ) { - is_ymsgr = 1; - } - else if ( strncmp(line_end, "crumb=", 6) ) { - LOG(("Oops! There was no ymsgr=. Where do I get my token from now :(")); - LOG(("I got this:\n\n%s\n",line_end)); - error_code = 2201; - goto FAIL; - } - - token = line_end+6; - - line_end = strstr(token, "\r\n"); - - if(line_end) { - *line_end = '\0'; - line_end += 2; - } - - /* Go for the crumb */ - if(is_ymsgr) { - char *url; - - url = g_strdup_printf( - "https://login.yahoo.com/config/pwtoken_login?" - "src=ymsgr&ts=&token=%s", token); - - http_dorequest_url(url, yahoo_process_auth_response, yid); - - g_free(url); - - return; - } - - /* token is actually crumb */ - - if(!line_end) { - /* We did not get our cookies. Cry. */ - } - - if((cookie = strstr(req->reply_headers, "Set-Cookie: Y=")) && - (line_end = strstr(cookie + 14, "\r\n"))) { - *line_end = '\0'; - yid->yd->cookie_y = strdup(cookie + 14); - *line_end = ';'; - } else { - /* Cry. */ - LOG(("NO Y Cookie!")); - error_code = 2202; - goto FAIL; - } - - if((cookie = strstr(req->reply_headers, "Set-Cookie: T=")) && - (line_end = strstr(cookie + 14, "\r\n"))) { - *line_end = '\0'; - yid->yd->cookie_t = strdup(cookie + 14); - *line_end = ';'; - } else { - /* Cry. */ - LOG(("NO T Cookie!")); - error_code = 2203; - goto FAIL; - } - - md5_init(&ctx); - md5_append(&ctx, (md5_byte_t *)token, strlen(token)); - md5_append(&ctx, (md5_byte_t *)yid->yd->login_cookie, strlen(yid->yd->login_cookie)); - md5_finish(&ctx, result); - - to_y64((unsigned char*)crypt_hash, result, 16); - - packet = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yid->yd->initial_status, yid->yd->session_id); - yahoo_packet_hash(packet, 1, yid->yd->user); - yahoo_packet_hash(packet, 0, yid->yd->user); - yahoo_packet_hash(packet, 277, yid->yd->cookie_y); - yahoo_packet_hash(packet, 278, yid->yd->cookie_t); - yahoo_packet_hash(packet, 307, crypt_hash); - yahoo_packet_hash(packet, 244, "2097087"); /* Rekkanoryo says this is the build number */ - yahoo_packet_hash(packet, 2, yid->yd->user); - yahoo_packet_hash(packet, 2, "1"); - yahoo_packet_hash(packet, 98, "us"); /* TODO Put country code */ - yahoo_packet_hash(packet, 135, "9.0.0.1389"); - - yahoo_send_packet(yid, packet, 0); - - yahoo_packet_free(packet); - - /* We don't need this anymore */ - free(yid->yd->login_cookie); - yid->yd->login_cookie = NULL; - - return; - -FAIL: - YAHOO_CALLBACK(ext_yahoo_login_response)(yid->yd->client_id, error_code, NULL); -} - - static void (*yahoo_process_connection[])(struct yahoo_input_data *, int over) = { yahoo_process_pager_connection, yahoo_process_ft_connection, -- cgit v1.2.3 From 99c8f1357f1ab85f3a98727cb8877403d965e3da Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 17 Oct 2009 15:48:21 +0100 Subject: Valgrind pointed me at some memory leaks in the Yahoo! codek, including one that existed for a while already. Fixed. --- protocols/yahoo/libyahoo2.c | 8 +++++--- protocols/yahoo/yahoo.c | 31 +++++++++++++++++-------------- 2 files changed, 22 insertions(+), 17 deletions(-) (limited to 'protocols') diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index 1d943df7..a1755cc9 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -2485,9 +2485,8 @@ static void yahoo_https_auth_finish(struct http_request *req) yahoo_packet_free(pack); - return; - fail: + g_free(crumb); g_free(had->token); g_free(had->chal); g_free(had); @@ -4134,7 +4133,10 @@ void yahoo_logoff(int id) LOG(("yahoo_logoff: current status: %d", yd->current_status)); - if(yd->current_status != -1) { + if(yd->current_status != -1 && 0) { + /* Meh. Don't send this. The event handlers are not going to + get to do this so it'll just leak memory. And the TCP + connection reset will hopefully be clear enough. */ pkt = yahoo_packet_new(YAHOO_SERVICE_LOGOFF, YAHOO_STATUS_AVAILABLE, yd->session_id); yd->current_status = -1; diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c index 96f619ed..ac57d4b6 100644 --- a/protocols/yahoo/yahoo.c +++ b/protocols/yahoo/yahoo.c @@ -253,20 +253,23 @@ static void byahoo_set_away( struct im_connection *ic, char *state, char *msg ) static GList *byahoo_away_states( struct im_connection *ic ) { - GList *m = NULL; - - m = g_list_append( m, "Available" ); - m = g_list_append( m, "Be Right Back" ); - m = g_list_append( m, "Busy" ); - m = g_list_append( m, "Not At Home" ); - m = g_list_append( m, "Not At Desk" ); - m = g_list_append( m, "Not In Office" ); - m = g_list_append( m, "On Phone" ); - m = g_list_append( m, "On Vacation" ); - m = g_list_append( m, "Out To Lunch" ); - m = g_list_append( m, "Stepped Out" ); - m = g_list_append( m, "Invisible" ); - m = g_list_append( m, GAIM_AWAY_CUSTOM ); + static GList *m = NULL; + + if( m == NULL ) + { + m = g_list_append( m, "Available" ); + m = g_list_append( m, "Be Right Back" ); + m = g_list_append( m, "Busy" ); + m = g_list_append( m, "Not At Home" ); + m = g_list_append( m, "Not At Desk" ); + m = g_list_append( m, "Not In Office" ); + m = g_list_append( m, "On Phone" ); + m = g_list_append( m, "On Vacation" ); + m = g_list_append( m, "Out To Lunch" ); + m = g_list_append( m, "Stepped Out" ); + m = g_list_append( m, "Invisible" ); + m = g_list_append( m, GAIM_AWAY_CUSTOM ); + } return m; } -- cgit v1.2.3 From 74349eb5b77e2143289ef98201d03870e0d2366a Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 17 Oct 2009 16:13:40 +0100 Subject: If you can't find what you expect in an IQ packet, it doesn't mean it's incorrect, so stop spamming. Ideally it should return a feature-not- implemented but I'll do that later. --- protocols/jabber/iq.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'protocols') diff --git a/protocols/jabber/iq.c b/protocols/jabber/iq.c index 38c5a5a9..875b5c81 100644 --- a/protocols/jabber/iq.c +++ b/protocols/jabber/iq.c @@ -50,10 +50,11 @@ xt_status jabber_pkt_iq( struct xt_node *node, gpointer data ) else if( strcmp( type, "get" ) == 0 ) { if( !( ( c = xt_find_node( node->children, "query" ) ) || - ( c = xt_find_node( node->children, "ping" ) ) ) || /* O_o WHAT is wrong with just ????? */ + ( c = xt_find_node( node->children, "ping" ) ) ) || !( s = xt_find_attr( c, "xmlns" ) ) ) { - imcb_log( ic, "Warning: Received incomplete IQ-%s packet", type ); + /* Sigh. Who decided to suddenly invent new elements + instead of just sticking with ? */ return XT_HANDLED; } -- cgit v1.2.3