⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yahoo.c

📁 yahoo message protocol stack
💻 C
📖 第 1 页 / 共 5 页
字号:
	shaUpdate(&ctx2, crypt_hash_xor2, 64);	shaUpdate(&ctx2, digest1, 20);	shaFinal(&ctx2, digest2);		/* 	 * Now that we have digest2, use it to fetch characters from an alphabet to construct	 * our first authentication response.	 */		for (x = 0; x < 20; x += 2) {		unsigned int	val = 0;		unsigned int	lookup = 0;				char			byte[6];				memset(&byte, 0, 6);				/* First two bytes of digest stuffed together.		 */				val = digest2[x];		val <<= 8;		val += digest2[x+1];		lookup = (val >> 0x0b);		lookup &= 0x1f;		if (lookup >= strlen(alphabet1))			break;		sprintf(byte, "%c", alphabet1[lookup]);		strcat(resp_96, byte);		strcat(resp_96, "=");				lookup = (val >> 0x06);		lookup &= 0x1f;		if (lookup >= strlen(alphabet2))			break;		sprintf(byte, "%c", alphabet2[lookup]);		strcat(resp_96, byte);				lookup = (val >> 0x01);		lookup &= 0x1f;		if (lookup >= strlen(alphabet2))			break;		sprintf(byte, "%c", alphabet2[lookup]);		strcat(resp_96, byte);				lookup = (val & 0x01);		if (lookup >= strlen(delimit_lookup))			break;		sprintf(byte, "%c", delimit_lookup[lookup]);		strcat(resp_96, byte);	}		pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP,	YAHOO_STATUS_AVAILABLE, 0);	yahoo_packet_hash(pack, 0, name);	yahoo_packet_hash(pack, 6, resp_6);	yahoo_packet_hash(pack, 96, resp_96);	yahoo_packet_hash(pack, 1, name);	yahoo_packet_hash(pack, 135, "6,0,0,1710");	if (yd->picture_checksum) {		char *cksum = g_strdup_printf("%d", yd->picture_checksum);		yahoo_packet_hash(pack, 192, cksum);		g_free(cksum);	}	yahoo_send_packet(yd, pack);	yahoo_packet_free(pack);	g_free(password_hash);	g_free(crypt_hash);}static void yahoo_process_auth(GaimConnection *gc, struct yahoo_packet *pkt){	char *seed = NULL;	char *sn   = NULL;	GSList *l = pkt->hash;	int m = 0;	gchar *buf;	while (l) {		struct yahoo_pair *pair = l->data;		if (pair->key == 94)			seed = pair->value;		if (pair->key == 1)			sn = pair->value;		if (pair->key == 13)			m = atoi(pair->value);		l = l->next;	}	if (seed) {		switch (m) {		case 0:			yahoo_process_auth_old(gc, seed);			break;		case 1:			yahoo_process_auth_new(gc, seed);			break;		default:			buf = g_strdup_printf(_("The Yahoo server has requested the use of an unrecognized "						"authentication method.  This version of Gaim will likely not be able "						"to successfully sign on to Yahoo.  Check %s for updates."), GAIM_WEBSITE);			gaim_notify_error(gc, "", _("Failed Yahoo! Authentication"),					  buf);			g_free(buf);			yahoo_process_auth_new(gc, seed); /* Can't hurt to try it anyway. */		}	}}static void ignore_buddy(GaimBuddy *buddy) {	GaimGroup *group;	GaimConversation *conv;	GaimAccount *account;	gchar *name;	if (!buddy)		return;	group = gaim_find_buddys_group(buddy);	name = g_strdup(buddy->name);	account = buddy->account;	gaim_debug(GAIM_DEBUG_INFO, "blist",		"Removing '%s' from buddy list.\n", buddy->name);	serv_remove_buddy(account->gc, buddy, group);	gaim_blist_remove_buddy(buddy);	serv_add_deny(account->gc, name);	conv = gaim_find_conversation_with_account(name, account);	if (conv != NULL)		gaim_conversation_update(conv, GAIM_CONV_UPDATE_REMOVE);	g_free(name);}static void keep_buddy(GaimBuddy *b) {	gaim_privacy_deny_remove(b->account, b->name, 1);}static void yahoo_process_ignore(GaimConnection *gc, struct yahoo_packet *pkt) {	GaimBuddy *b;	GSList *l;	gchar *who = NULL;	gchar *sn = NULL;	gchar buf[BUF_LONG];	gint ignore = 0;	gint status = 0;	for (l = pkt->hash; l; l = l->next) {		struct yahoo_pair *pair = l->data;		switch (pair->key) {		case 0:			who = pair->value;			break;		case 1:			sn = pair->value;			break;		case 13:			ignore = strtol(pair->value, NULL, 10);			break;		case 66:			status = strtol(pair->value, NULL, 10);			break;		default:			break;		}	}	switch (status) {	case 12:		b = gaim_find_buddy(gc->account, who);		g_snprintf(buf, sizeof(buf), _("You have tried to ignore %s, but the "					"user is on your buddy list.  Clicking \"Yes\" "					"will remove and ignore the buddy."), who);		gaim_request_yes_no(gc, NULL, _("Ignore buddy?"), buf, 0, b,						G_CALLBACK(ignore_buddy),						G_CALLBACK(keep_buddy));		break;	case 2:	case 3:	case 0:	default:		break;	}}static void yahoo_process_authresp(GaimConnection *gc, struct yahoo_packet *pkt){	struct yahoo_data *yd = gc->proto_data;	GSList *l = pkt->hash;	int err = 0;	char *msg;	char *url = NULL;	char *fullmsg;	while (l) {		struct yahoo_pair *pair = l->data;		if (pair->key == 66)			err = strtol(pair->value, NULL, 10);		if (pair->key == 20)			url = pair->value;		l = l->next;	}	switch (err) {	case 3:		msg = g_strdup(_("Invalid username."));		break;	case 13:		if (!yd->wm) {			yd->wm = TRUE;			if (yd->fd >= 0)				close(yd->fd);			if (gc->inpa)				gaim_input_remove(gc->inpa);			gaim_url_fetch(WEBMESSENGER_URL, TRUE, "Gaim/" VERSION, FALSE,			               yahoo_login_page_cb, gc);			gaim_notify_warning(gc, NULL, _("Normal authentication failed!"),			                    _("The normal authentication method has failed. "			                      "This means either your password is incorrect, "			                      "or Yahoo!'s authentication scheme has changed. "			                      "Gaim will now attempt to log in using Web "			                      "Messenger authentication, which will result "			                      "in reduced functionality and features."));			return;		}		msg = g_strdup(_("Incorrect password."));		break;	case 14:		msg = g_strdup(_("Your account is locked, please log in to the Yahoo! website."));		break;	default:		msg = g_strdup_printf(_("Unknown error number %d. Logging into the Yahoo! website may fix this."), err);	}	if (url)		fullmsg = g_strdup_printf("%s\n%s", msg, url);	else		fullmsg = g_strdup(msg);	gc->wants_to_die = TRUE;	gaim_connection_error(gc, fullmsg);	g_free(msg);	g_free(fullmsg);}static void yahoo_process_addbuddy(GaimConnection *gc, struct yahoo_packet *pkt){	int err = 0;	char *who = NULL;	char *group = NULL;	char *decoded_group;	char *buf;	YahooFriend *f;	GSList *l = pkt->hash;	while (l) {		struct yahoo_pair *pair = l->data;		switch (pair->key) {		case 66:			err = strtol(pair->value, NULL, 10);			break;		case 7:			who = pair->value;			break;		case 65:			group = pair->value;			break;		}		l = l->next;	}	if (!who)		return;	if (!group)		group = "";	if (!err || (err == 2)) { /* 0 = ok, 2 = already on serv list */		f = yahoo_friend_find_or_new(gc, who);		yahoo_update_status(gc, who, f);		return;	}	decoded_group = yahoo_string_decode(gc, group, FALSE);	buf = g_strdup_printf(_("Could not add buddy %s to group %s to the server list on account %s."),				who, decoded_group, gaim_connection_get_display_name(gc));	if (!gaim_conv_present_error(who, gaim_connection_get_account(gc), buf))		gaim_notify_error(gc, NULL, _("Could not add buddy to server list"), buf);	g_free(buf);	g_free(decoded_group);}static void yahoo_process_p2p(GaimConnection *gc, struct yahoo_packet *pkt){	GSList *l = pkt->hash;	char *who = NULL;	char *base64 = NULL;	char *decoded;	int len;	while (l) {		struct yahoo_pair *pair = l->data;		switch (pair->key) {		case 5:			/* our identity */			break;		case 4:			who = pair->value;			break;		case 1:			/* who again, the master identity this time? */			break;		case 12:			base64 = pair->value;			/* so, this is an ip address. in base64. decoded it's in ascii.			   after strtol, it's in reversed byte order. Who thought this up?*/			break;		/*			TODO: figure these out			yahoo: Key: 61          Value: 0			yahoo: Key: 2   Value:			yahoo: Key: 13          Value: 0			yahoo: Key: 49          Value: PEERTOPEER			yahoo: Key: 140         Value: 1			yahoo: Key: 11          Value: -1786225828		*/		}		l = l->next;	}	if (base64) {		guint32 ip;		char *tmp2;		YahooFriend *f;		gaim_base64_decode(base64, &decoded, &len);		if (len) {			char *tmp = gaim_str_binary_to_ascii(decoded, len);			gaim_debug_info("yahoo", "Got P2P service packet (from server): who = %s, ip = %s\n", who, tmp);			g_free(tmp);		}		tmp2 = g_strndup(decoded, len); /* so its \0 terminated...*/		ip = strtol(tmp2, NULL, 10);		g_free(tmp2);		g_free(decoded);		tmp2 = g_strdup_printf("%u.%u.%u.%u", ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) & 0xff,		                       (ip >> 24) & 0xff);		f = yahoo_friend_find(gc, who);		if (f)			yahoo_friend_set_ip(f, tmp2);		g_free(tmp2);	}}static void yahoo_process_audible(GaimConnection *gc, struct yahoo_packet *pkt){	char *who = NULL, *msg = NULL;	GSList *l = pkt->hash;	while (l) {		struct yahoo_pair *pair = l->data;		switch (pair->key) {		case 4:			who = pair->value;			break;		case 5:			/* us */			break;		case 230:			/* the audible, in foo.bar.baz format */			break;		case 231:			/* the text of the audible */			msg = pair->value;			break;		case 232:			/* weird number (md5 hash?), like 8ebab9094156135f5dcbaccbeee662a5c5fd1420 */			break;		}		l = l->next;	}	if (!who || !msg)		return;	if (!g_utf8_validate(msg, -1, NULL)) {		gaim_debug_misc("yahoo", "Warning, nonutf8 audible, ignoring!\n");		return;	}	serv_got_im(gc, who, msg, 0, time(NULL));}static void yahoo_packet_process(GaimConnection *gc, struct yahoo_packet *pkt){	switch (pkt->service) {	case YAHOO_SERVICE_LOGON:	case YAHOO_SERVICE_LOGOFF:	case YAHOO_SERVICE_ISAWAY:	case YAHOO_SERVICE_ISBACK:	case YAHOO_SERVICE_GAMELOGON:	case YAHOO_SERVICE_GAMELOGOFF:	case YAHOO_SERVICE_CHATLOGON:	case YAHOO_SERVICE_CHATLOGOFF:	case YAHOO_SERVICE_YAHOO6_STATUS_UPDATE:		yahoo_process_status(gc, pkt);		break;	case YAHOO_SERVICE_NOTIFY:		yahoo_process_notify(gc, pkt);		break;	case YAHOO_SERVICE_MESSAGE:	case YAHOO_SERVICE_GAMEMSG:	case YAHOO_SERVICE_CHATMSG:		yahoo_process_message(gc, pkt);		break;	case YAHOO_SERVICE_SYSMESSAGE:		yahoo_process_sysmessage(gc, pkt);			break;	case YAHOO_SERVICE_NEWMAIL:		yahoo_process_mail(gc, pkt);		break;	case YAHOO_SERVICE_NEWCONTACT:		yahoo_process_contact(gc, pkt);		break;	case YAHOO_SERVICE_AUTHRESP:		yahoo_process_authresp(gc, pkt);		break;	case YAHOO_SERVICE_LIST:		yahoo_process_list(gc, pkt);		break;	case YAHOO_SERVICE_AUTH:		yahoo_process_auth(gc, pkt);		break;	case YAHOO_SERVICE_ADDBUDDY:		yahoo_process_addbuddy(gc, pkt);		break;	case YAHOO_SERVICE_IGNORECONTACT:		yahoo_process_ignore(gc, pkt);		break;	case YAHOO_SERVICE_CONFINVITE:	case YAHOO_SERVICE_CONFADDINVITE:		yahoo_process_conference_invite(gc, pkt);		break;	case YAHOO_SERVICE_CONFDECLINE:		yahoo_process_conference_decline(gc, pkt);		break;	case YAHOO_SERVICE_CONFLOGON:		yahoo_process_conference_logon(gc, pkt);		break;	case YAHOO_SERVICE_CONFLOGOFF:		yahoo_process_conference_logoff(gc, pkt);		break;	case YAHOO_SERVICE_CONFMSG:		yahoo_process_conference_message(gc, pkt);		break;	case YAHOO_SERVICE_CHATONLINE:		yahoo_process_chat_online(gc, pkt);		break;	case YAHOO_SERVICE_CHATLOGOUT:		yahoo_process_chat_logout(gc, pkt);		break;	case YAHOO_SERVICE_CHATGOTO:		yahoo_process_chat_goto(gc, pkt);		break;	case YAHOO_SERVICE_CHATJOIN:		yahoo_process_chat_join(gc, pkt);		break;	case YAHOO_SERVICE_CHATLEAVE: /* XXX is this right? */	case YAHOO_SERVICE_CHATEXIT:		yahoo_process_chat_exit(gc, pkt);		break;	case YAHOO_SERVICE_CHATINVITE: /* XXX never seen this one, might not do it right */	case YAHOO_SERVICE_CHATADDINVITE:		yahoo_process_chat_addinvite(gc, pkt);		break;	case YAHOO_SERVICE_COMMENT:		yahoo_process_chat_message(gc, pkt);		break;	case YAHOO_SERVICE_P2PFILEXFER:	case YAHOO_SERVICE_FILETRANSFER:		yahoo_process_filetransfer(gc, pkt);		break;	case YAHOO_SERVICE_PEEPTOPEER:		yahoo_process_p2p(gc, pkt);		break;	case YAHOO_SERVICE_PICTURE:		yahoo_process_picture(gc, pkt);		break;	case YAHOO_SERVICE_PICTURE_UPDATE:		yahoo_process_picture_update(gc, pkt);		break;	case YAHOO_SERVICE_PICTURE_CHECKSUM:		yahoo_process_picture_checksum(gc, pkt);		break;	case YAHOO_SERVICE_PICTURE_UPLOAD:		yahoo_process_picture_upload(gc, pkt);		break;	case YAHOO_SERVICE_AUDIBLE:		yahoo_process_audible(gc, pkt);	default:		gaim_debug(GAIM_DEBUG_ERROR, "yahoo",				   "Unhandled service 0x%02x\n", pkt->service);		break;	}}static void yahoo_pending(gpointer data, gint source, GaimInputCondition cond){	GaimConnection *gc = data;	struct yahoo_data *yd = gc->proto_data;	char buf[1024];	int len;	len = read(yd->fd, buf, sizeof(buf));	if (len <= 0) {		gaim_connection_error(gc, _("Unable to read"));		return;	}	yd->rxqueue = g_realloc(yd->rxqueue, len + yd->rxlen);	memcpy(yd->rxqueue + yd->rxlen, buf, len);	yd->rxlen += len;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -