Index: protocols/yahoo/libyahoo2.c
===================================================================
--- protocols/yahoo/libyahoo2.c	(revision 01827732cb3d5289e8071d8317b95d5c4043857c)
+++ protocols/yahoo/libyahoo2.c	(revision 4fefb772f530cd15ef3e92606532d3c6b193d96b)
@@ -89,4 +89,10 @@
 
 #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
@@ -169,4 +175,5 @@
 	YAHOO_SERVICE_GOTGROUPRENAME, /* < 1, 36(old), 37(new) */
 	YAHOO_SERVICE_SYSMESSAGE = 0x14,
+	YAHOO_SERVICE_SKINNAME = 0x15,
 	YAHOO_SERVICE_PASSTHROUGH2 = 0x16,
 	YAHOO_SERVICE_CONFINVITE = 0x18,
@@ -192,4 +199,5 @@
 	YAHOO_SERVICE_LIST,
 	YAHOO_SERVICE_AUTH = 0x57,
+	YAHOO_SERVICE_AUTHBUDDY = 0x6d,
 	YAHOO_SERVICE_ADDBUDDY = 0x83,
 	YAHOO_SERVICE_REMBUDDY,
@@ -197,4 +205,5 @@
 	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,
@@ -202,12 +211,35 @@
 	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
 };
 
@@ -733,5 +765,5 @@
 
 	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);
@@ -1480,4 +1512,60 @@
 }
 
+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)
 {
@@ -1549,5 +1637,6 @@
 			} 
 
-			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);
 
@@ -2226,4 +2315,20 @@
 }
 
+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)
 {
@@ -2253,4 +2358,8 @@
 		case 1:
 			yahoo_process_auth_0x0b(yid, seed, sn);
+			break;
+		case 2:
+			/* HTTPS */
+			yahoo_process_auth_0x10(yid, seed, sn);
 			break;
 		default:
@@ -2661,4 +2770,6 @@
 	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;
@@ -2756,4 +2867,6 @@
 		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));
@@ -3532,4 +3645,187 @@
 }
 
+//#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,
@@ -3539,5 +3835,5 @@
 	yahoo_process_webcam_connection,
 	yahoo_process_chatcat_connection,
-	yahoo_process_search_connection
+	yahoo_process_search_connection,
 };
 
@@ -3557,5 +3853,5 @@
 	} 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;
 
@@ -4146,5 +4442,5 @@
 		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);
Index: protocols/yahoo/yahoo2_types.h
===================================================================
--- protocols/yahoo/yahoo2_types.h	(revision 01827732cb3d5289e8071d8317b95d5c4043857c)
+++ protocols/yahoo/yahoo2_types.h	(revision 4fefb772f530cd15ef3e92606532d3c6b193d96b)
@@ -85,5 +85,5 @@
 };
 
-#define YAHOO_PROTO_VER 0x000b
+#define YAHOO_PROTO_VER 0x0010
 
 /* Yahoo style/color directives */
@@ -115,5 +115,6 @@
 	YAHOO_CONNECTION_WEBCAM,
 	YAHOO_CONNECTION_CHATCAT,
-	YAHOO_CONNECTION_SEARCH
+	YAHOO_CONNECTION_SEARCH,
+	YAHOO_CONNECTION_AUTH,
 };
 
