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

📄 yahoo.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	 * plus 3 bytes.  The 3 bytes are found by looping, and they represent the offsets	 * into particular functions we'll later call to potentially alter the magic key.	 *	 * %-)	 */	magic_cnt = 1;	x = 0;	do {		unsigned int	bl = 0;		unsigned int	cl = magic[magic_cnt++];		if (magic_cnt >= magic_len)			break;		if (cl > 0x7F) {			if (cl < 0xe0)				bl = cl = (cl & 0x1f) << 6;			else {				bl = magic[magic_cnt++];				cl = (cl & 0x0f) << 6;				bl = ((bl & 0x3f) + cl) << 6;			}			cl = magic[magic_cnt++];			bl = (cl & 0x3f) + bl;		} else			bl = cl;		comparison_src[x++] = (bl & 0xff00) >> 8;		comparison_src[x++] = bl & 0xff;	} while (x < 20);	/* First four bytes are magic key. */	memcpy(&magic_key_char[0], comparison_src, 4);	magic_4 = magic_key_char[0] | (magic_key_char[1]<<8) | (magic_key_char[2]<<16) | (magic_key_char[3]<<24);	/*	 * Magic: Phase 4.  Determine what function to use later by getting outside/inside	 * loop values until we match our previous buffer.	 */	for (x = 0; x < 65535; x++) {		int			leave = 0;		for (y = 0; y < 5; y++) {			unsigned char	test[3];			/* Calculate buffer. */			test[0] = x;			test[1] = x >> 8;			test[2] = y;			purple_cipher_context_reset(md5_ctx, NULL);			purple_cipher_context_append(md5_ctx, magic_key_char, 4);			purple_cipher_context_append(md5_ctx, test, 3);			purple_cipher_context_digest(md5_ctx, sizeof(md5_digest),									   md5_digest, NULL);			if (!memcmp(md5_digest, comparison_src+4, 16)) {				leave = 1;				break;			}		}		if (leave == 1)			break;	}	/* If y != 0, we need some help. */	if (y != 0) {		unsigned int	updated_key;		/* Update magic stuff.		 * Call it twice because Yahoo's encryption is super bad ass.		 */		updated_key = yahoo_auth_finalCountdown(magic_4, 0x60, y, x);		updated_key = yahoo_auth_finalCountdown(updated_key, 0x60, y, x);		magic_key_char[0] = updated_key & 0xff;		magic_key_char[1] = (updated_key >> 8) & 0xff;		magic_key_char[2] = (updated_key >> 16) & 0xff;		magic_key_char[3] = (updated_key >> 24) & 0xff;	}	enc_pass = yahoo_string_encode(gc, pass, NULL);	/* Get password and crypt hashes as per usual. */	purple_cipher_context_reset(md5_ctx, NULL);	purple_cipher_context_append(md5_ctx, (const guchar *)enc_pass, strlen(enc_pass));	purple_cipher_context_digest(md5_ctx, sizeof(md5_digest),							   md5_digest, NULL);	to_y64(password_hash, md5_digest, 16);	crypt_result = yahoo_crypt(enc_pass, "$1$_2S43d5f$");	g_free(enc_pass);	enc_pass = NULL;	purple_cipher_context_reset(md5_ctx, NULL);	purple_cipher_context_append(md5_ctx, (const guchar *)crypt_result, strlen(crypt_result));	purple_cipher_context_digest(md5_ctx, sizeof(md5_digest),							   md5_digest, NULL);	to_y64(crypt_hash, md5_digest, 16);	/* Our first authentication response is based off of the password hash. */	for (x = 0; x < (int)strlen(password_hash); x++)		pass_hash_xor1[cnt++] = password_hash[x] ^ 0x36;	if (cnt < 64)		memset(&(pass_hash_xor1[cnt]), 0x36, 64-cnt);	cnt = 0;	for (x = 0; x < (int)strlen(password_hash); x++)		pass_hash_xor2[cnt++] = password_hash[x] ^ 0x5c;	if (cnt < 64)		memset(&(pass_hash_xor2[cnt]), 0x5c, 64-cnt);	/*	 * The first context gets the password hash XORed with 0x36 plus a magic value	 * which we previously extrapolated from our challenge.	 */	purple_cipher_context_append(sha1_ctx1, pass_hash_xor1, 64);	if (y >= 3)		purple_cipher_context_set_option(sha1_ctx1, "sizeLo", GINT_TO_POINTER(0x1ff));	purple_cipher_context_append(sha1_ctx1, magic_key_char, 4);	purple_cipher_context_digest(sha1_ctx1, sizeof(digest1), digest1, NULL);	/*	 * The second context gets the password hash XORed with 0x5c plus the SHA-1 digest	 * of the first context.	 */	purple_cipher_context_append(sha1_ctx2, pass_hash_xor2, 64);	purple_cipher_context_append(sha1_ctx2, digest1, 20);	purple_cipher_context_digest(sha1_ctx2, sizeof(digest2), digest2, NULL);	/*	 * 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_6, byte);		strcat(resp_6, "=");		lookup = (val >> 0x06);		lookup &= 0x1f;		if (lookup >= strlen(alphabet2))			break;		sprintf(byte, "%c", alphabet2[lookup]);		strcat(resp_6, byte);		lookup = (val >> 0x01);		lookup &= 0x1f;		if (lookup >= strlen(alphabet2))			break;		sprintf(byte, "%c", alphabet2[lookup]);		strcat(resp_6, byte);		lookup = (val & 0x01);		if (lookup >= strlen(delimit_lookup))			break;		sprintf(byte, "%c", delimit_lookup[lookup]);		strcat(resp_6, byte);	}	/* Our second authentication response is based off of the crypto hash. */	cnt = 0;	memset(&digest1, 0, 20);	memset(&digest2, 0, 20);	for (x = 0; x < (int)strlen(crypt_hash); x++)		crypt_hash_xor1[cnt++] = crypt_hash[x] ^ 0x36;	if (cnt < 64)		memset(&(crypt_hash_xor1[cnt]), 0x36, 64-cnt);	cnt = 0;	for (x = 0; x < (int)strlen(crypt_hash); x++)		crypt_hash_xor2[cnt++] = crypt_hash[x] ^ 0x5c;	if (cnt < 64)		memset(&(crypt_hash_xor2[cnt]), 0x5c, 64-cnt);	purple_cipher_context_reset(sha1_ctx1, NULL);	purple_cipher_context_reset(sha1_ctx2, NULL);	/*	 * The first context gets the password hash XORed with 0x36 plus a magic value	 * which we previously extrapolated from our challenge.	 */	purple_cipher_context_append(sha1_ctx1, crypt_hash_xor1, 64);	if (y >= 3) {		purple_cipher_context_set_option(sha1_ctx1, "sizeLo",									   GINT_TO_POINTER(0x1ff));	}	purple_cipher_context_append(sha1_ctx1, magic_key_char, 4);	purple_cipher_context_digest(sha1_ctx1, sizeof(digest1), digest1, NULL);	/*	 * The second context gets the password hash XORed with 0x5c plus the SHA-1 digest	 * of the first context.	 */	purple_cipher_context_append(sha1_ctx2, crypt_hash_xor2, 64);	purple_cipher_context_append(sha1_ctx2, digest1, 20);	purple_cipher_context_digest(sha1_ctx2, sizeof(digest2), digest2, NULL);	/*	 * 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);	}	purple_debug_info("yahoo", "yahoo status: %d\n", yd->current_status);	pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP,	yd->current_status, 0);	yahoo_packet_hash(pack, "sssss", 0, name, 6, resp_6, 96, resp_96, 1,	                  name, 135, "6,0,0,1710");	if (yd->picture_checksum)		yahoo_packet_hash_int(pack, 192, yd->picture_checksum);	yahoo_packet_send_and_free(pack, yd);	purple_cipher_context_destroy(md5_ctx);	purple_cipher_context_destroy(sha1_ctx1);	purple_cipher_context_destroy(sha1_ctx2);	g_free(password_hash);	g_free(crypt_hash);}static void yahoo_process_auth(PurpleConnection *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:		case 2: /* This case seems to work, could probably use testing */			yahoo_process_auth_new(gc, seed);			break;		default:			buf = g_strdup_printf(_("The Yahoo server has requested the use of an unrecognized "						"authentication method.  You will probably not be able "						"to successfully sign on to Yahoo.  Check %s for updates."), PURPLE_WEBSITE);			purple_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(PurpleBuddy *buddy) {	PurpleGroup *group;	PurpleAccount *account;	gchar *name;	if (!buddy)		return;	group = purple_buddy_get_group(buddy);	name = g_strdup(buddy->name);	account = buddy->account;	purple_debug(PURPLE_DEBUG_INFO, "blist",		"Removing '%s' from buddy list.\n", buddy->name);	purple_account_remove_buddy(account, buddy, group);	purple_blist_remove_buddy(buddy);	serv_add_deny(account->gc, name);	g_free(name);}static void keep_buddy(PurpleBuddy *b) {	purple_privacy_deny_remove(b->account, b->name, 1);}static void yahoo_process_ignore(PurpleConnection *gc, struct yahoo_packet *pkt) {	PurpleBuddy *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 = purple_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);		purple_request_yes_no(gc, NULL, _("Ignore buddy?"), buf, 0,						gc->account, who, NULL,						b,						G_CALLBACK(ignore_buddy),						G_CALLBACK(keep_buddy));		break;	case 2:	case 3:	case 0:	default:		break;	}}static void yahoo_process_authresp(PurpleConnection *gc, struct yahoo_packet *pkt){#ifdef TRY_WEBMESSENGER_LOGIN	struct yahoo_data *yd = gc->proto_data;#endif	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 screen name."));		break;	case 13:#ifdef TRY_WEBMESSENGER_LOGIN		if (!yd->wm) {			PurpleUtilFetchUrlData *url_data;			yd->wm = TRUE;			if (yd->fd >= 0)				close(yd->fd);			if (gc->inpa)				purple_input_remove(gc->inpa);			url_data = purple_util_fetch_url(WEBMESSENGER_URL, TRUE,					"Purple/" VERSION, FALSE, yahoo_login_page_cb, gc);			if (url_data != NULL)				yd->url_datas = g_slist_prepend(yd->url_datas, url_data);			return;		}#endif		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;	purple_connection_error(gc, fullmsg);	g_free(msg);	g_free(fullmsg);}static void yahoo_process_addbuddy(PurpleConnection *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;		}

⌨️ 快捷键说明

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