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

📄 family_oservice.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	/*	 * Send only the versions that the server cares about (that it	 * marked as supporting in the server ready SNAC).	 */	for (cur = conn->groups; cur != NULL; cur = cur->next)	{		aim_module_t *mod;		if ((mod = aim__findmodulebygroup(od, GPOINTER_TO_UINT(cur->data))))		{			byte_stream_put16(&frame->data, mod->family);			byte_stream_put16(&frame->data, mod->version);		}	}	flap_connection_send(conn, frame);}/* Subtype 0x0018 - Host versions */static inthostversions(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs){	int vercount;	guint8 *versions;	/* This is frivolous. (Thank you SmarterChild.) */	vercount = byte_stream_empty(bs)/4;	versions = byte_stream_getraw(bs, byte_stream_empty(bs));	g_free(versions);	/*	 * Now request rates.	 */	aim_srv_reqrates(od, conn);	return 1;}/** * Subtype 0x001e - Extended Status/Extra Info. * * These settings are transient, not server-stored (i.e. they only * apply to this session, and must be re-set the next time you sign * on). * * You can set your ICQ status (available, away, do not disturb, * etc.), or whether your IP address should be hidden or not, or * if your status is visible on ICQ web sites, and you can set * your IP address info and what not. * * You can also set your "available" message.  This is currently * only supported by iChat, Purple and other 3rd party clients. * * These are the same TLVs seen in user info.  You can * also set 0x0008 and 0x000c. */intaim_srv_setextrainfo(OscarData *od,		gboolean seticqstatus, guint32 icqstatus,		gboolean setavailmsg, const char *availmsg, const char *itmsurl){	FlapConnection *conn;	FlapFrame *frame;	aim_snacid_t snacid;	GSList *tlvlist = NULL;	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM)))		return -EINVAL;	if (seticqstatus)	{		aim_tlvlist_add_32(&tlvlist, 0x0006, icqstatus |				AIM_ICQ_STATE_HIDEIP | AIM_ICQ_STATE_DIRECTREQUIREAUTH);	}#if 0	if (other_stuff_that_isnt_implemented)	{		aim_tlvlist_add_raw(&tlvlist, 0x000c, 0x0025,				chunk_of_x25_bytes_with_ip_address_etc);		aim_tlvlist_add_raw(&tlvlist, 0x0011, 0x0005, unknown 0x01 61 10 f6 41);		aim_tlvlist_add_16(&tlvlist, 0x0012, unknown 0x00 00);	}#endif	if (setavailmsg)	{		int availmsglen, itmsurllen;		ByteStream tmpbs;		availmsglen = (availmsg != NULL) ? strlen(availmsg) : 0;		itmsurllen = (itmsurl != NULL) ? strlen(itmsurl) : 0;		byte_stream_new(&tmpbs, availmsglen + 8 + itmsurllen + 8);		byte_stream_put16(&tmpbs, 0x0002);		byte_stream_put8(&tmpbs, 0x04); /* Flags */		byte_stream_put8(&tmpbs, availmsglen + 4);		byte_stream_put16(&tmpbs, availmsglen);		if (availmsglen > 0)			byte_stream_putstr(&tmpbs, availmsg);		byte_stream_put16(&tmpbs, 0x0000);		byte_stream_put16(&tmpbs, 0x0009);		byte_stream_put8(&tmpbs, 0x04); /* Flags */		byte_stream_put8(&tmpbs, itmsurllen + 4);		byte_stream_put16(&tmpbs, itmsurllen);		if (itmsurllen > 0)			byte_stream_putstr(&tmpbs, itmsurl);		byte_stream_put16(&tmpbs, 0x0000);		aim_tlvlist_add_raw(&tlvlist, 0x001d,				byte_stream_curpos(&tmpbs), tmpbs.data);		g_free(tmpbs.data);	}	frame = flap_frame_new(od, 0x02, 10 + aim_tlvlist_size(tlvlist));	snacid = aim_cachesnac(od, 0x0001, 0x001e, 0x0000, NULL, 0);	aim_putsnac(&frame->data, 0x0001, 0x001e, 0x0000, snacid);	aim_tlvlist_write(&frame->data, &tlvlist);	aim_tlvlist_free(tlvlist);	flap_connection_send(conn, frame);	return 0;}/** * Starting this past week (26 Mar 2001, say), AOL has started sending * this nice little extra SNAC.  AFAIK, it has never been used until now. * * The request contains eight bytes.  The first four are an offset, the * second four are a length. * * The offset is an offset into aim.exe when it is mapped during execution * on Win32.  So far, AOL has only been requesting bytes in static regions * of memory.  (I won't put it past them to start requesting data in * less static regions -- regions that are initialized at run time, but still * before the client receives this request.) * * When the client receives the request, it adds it to the current ds * (0x00400000) and dereferences it, copying the data into a buffer which * it then runs directly through the MD5 hasher.  The 16 byte output of * the hash is then sent back to the server. * * If the client does not send any data back, or the data does not match * the data that the specific client should have, the client will get the * following message from "AOL Instant Messenger": *    "You have been disconnected from the AOL Instant Message Service (SM) *     for accessing the AOL network using unauthorized software.  You can *     download a FREE, fully featured, and authorized client, here *     http://www.aol.com/aim/download2.html" * The connection is then closed, receiving disconnect code 1, URL * http://www.aim.aol.com/errors/USER_LOGGED_OFF_NEW_LOGIN.html. * * Note, however, that numerous inconsistencies can cause the above error, * not just sending back a bad hash.  Do not immediatly suspect this code * if you get disconnected.  AOL and the open/free software community have * played this game for a couple years now, generating the above message * on numerous ocassions. * * Anyway, neener.  We win again. * *//* Subtype 0x001f - Client verification */static intmemrequest(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs){	int ret = 0;	aim_rxcallback_t userfunc;	guint32 offset, len;	GSList *tlvlist;	char *modname;	offset = byte_stream_get32(bs);	len = byte_stream_get32(bs);	tlvlist = aim_tlvlist_read(bs);	modname = aim_tlv_getstr(tlvlist, 0x0001, 1);	purple_debug_info("oscar", "Got memory request for data at 0x%08lx (%d bytes) of requested %s\n", offset, len, modname ? modname : "aim.exe");	if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))		ret = userfunc(od, conn, frame, offset, len, modname);	g_free(modname);	aim_tlvlist_free(tlvlist);	return ret;}/* Subtype 0x0020 - Client verification reply */intaim_sendmemblock(OscarData *od, FlapConnection *conn, guint32 offset, guint32 len, const guint8 *buf, guint8 flag){	FlapFrame *frame;	aim_snacid_t snacid;	if (!od || !conn)		return -EINVAL;	frame = flap_frame_new(od, 0x02, 10+2+16);	snacid = aim_cachesnac(od, 0x0001, 0x0020, 0x0000, NULL, 0);	aim_putsnac(&frame->data, 0x0001, 0x0020, 0x0000, snacid);	byte_stream_put16(&frame->data, 0x0010); /* md5 is always 16 bytes */	if ((flag == AIM_SENDMEMBLOCK_FLAG_ISHASH) && buf && (len == 0x10)) { /* we're getting a hash */		byte_stream_putraw(&frame->data, buf, 0x10);	} else if (buf && (len > 0)) { /* use input buffer */		PurpleCipher *cipher;		PurpleCipherContext *context;		guchar digest[16];		cipher = purple_ciphers_find_cipher("md5");		context = purple_cipher_context_new(cipher, NULL);		purple_cipher_context_append(context, buf, len);		purple_cipher_context_digest(context, 16, digest, NULL);		purple_cipher_context_destroy(context);		byte_stream_putraw(&frame->data, digest, 0x10);	} else if (len == 0) { /* no length, just hash NULL (buf is optional) */		PurpleCipher *cipher;		PurpleCipherContext *context;		guchar digest[16];		guint8 nil = '\0';		/*		 * I'm not sure if we really need the empty append with the		 * new MD5 functions, so I'll leave it in, just in case.		 */		cipher = purple_ciphers_find_cipher("md5");		context = purple_cipher_context_new(cipher, NULL);		purple_cipher_context_append(context, &nil, 0);		purple_cipher_context_digest(context, 16, digest, NULL);		purple_cipher_context_destroy(context);		byte_stream_putraw(&frame->data, digest, 0x10);	} else {		/*		 * This data is correct for AIM 3.5.1670.		 *		 * Using these blocks is as close to "legal" as you can get		 * without using an AIM binary.		 *		 */		if ((offset == 0x03ffffff) && (len == 0x03ffffff)) {#if 1 /* with "AnrbnrAqhfzcd" */			byte_stream_put32(&frame->data, 0x44a95d26);			byte_stream_put32(&frame->data, 0xd2490423);			byte_stream_put32(&frame->data, 0x93b8821f);			byte_stream_put32(&frame->data, 0x51c54b01);#else /* no filename */			byte_stream_put32(&frame->data, 0x1df8cbae);			byte_stream_put32(&frame->data, 0x5523b839);			byte_stream_put32(&frame->data, 0xa0e10db3);			byte_stream_put32(&frame->data, 0xa46d3b39);#endif		} else			purple_debug_warning("oscar", "sendmemblock: unknown hash request\n");	}	flap_connection_send(conn, frame);	return 0;}/* * Subtype 0x0021 - Receive our extended status * * This is used for iChat's "available" messages, and maybe ICQ extended * status messages?  It's also used to tell the client whether or not it * needs to upload an SSI buddy icon... who engineers this stuff, anyway? */static intaim_parse_extstatus(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs){	int ret = 0;	aim_rxcallback_t userfunc;	guint16 type;	guint8 flags, length;	type = byte_stream_get16(bs);	flags = byte_stream_get8(bs);	length = byte_stream_get8(bs);	/*	 * A flag of 0x01 could mean "this is the checksum we have for you"	 * A flag of 0x40 could mean "I don't have your icon, upload it"	 */	if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) {		switch (type) {		case 0x0000:		case 0x0001: { /* buddy icon checksum */			/* not sure what the difference between 1 and 0 is */			guint8 *md5 = byte_stream_getraw(bs, length);			ret = userfunc(od, conn, frame, type, flags, length, md5);			g_free(md5);			} break;		case 0x0002: { /* available message */			/* there is a second length that is just for the message */			char *msg = byte_stream_getstr(bs, byte_stream_get16(bs));			ret = userfunc(od, conn, frame, msg);			g_free(msg);			} break;		}	}	return ret;}static intsnachandler(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs){	if (snac->subtype == 0x0003)		return hostonline(od, conn, mod, frame, snac, bs);	else if (snac->subtype == 0x0005)		return redirect(od, conn, mod, frame, snac, bs);	else if (snac->subtype == 0x0007)		return rateresp(od, conn, mod, frame, snac, bs);	else if (snac->subtype == 0x000a)		return ratechange(od, conn, mod, frame, snac, bs);	else if (snac->subtype == 0x000b)		return serverpause(od, conn, mod, frame, snac, bs);	else if (snac->subtype == 0x000d)		return serverresume(od, conn, mod, frame, snac, bs);	else if (snac->subtype == 0x000f)		return selfinfo(od, conn, mod, frame, snac, bs);	else if (snac->subtype == 0x0010)		return evilnotify(od, conn, mod, frame, snac, bs);	else if (snac->subtype == 0x0012)		return migrate(od, conn, mod, frame, snac, bs);	else if (snac->subtype == 0x0013)		return motd(od, conn, mod, frame, snac, bs);	else if (snac->subtype == 0x0018)		return hostversions(od, conn, mod, frame, snac, bs);	else if (snac->subtype == 0x001f)		return memrequest(od, conn, mod, frame, snac, bs);	else if (snac->subtype == 0x0021)		return aim_parse_extstatus(od, conn, mod, frame, snac, bs);	return 0;}int service_modfirst(OscarData *od, aim_module_t *mod){	mod->family = 0x0001;	mod->version = 0x0003;	mod->toolid = 0x0110;	mod->toolversion = 0x0629;	mod->flags = 0;	strncpy(mod->name, "oservice", sizeof(mod->name));	mod->snachandler = snachandler;	return 0;}

⌨️ 快捷键说明

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