Beispiel #1
0
/*
 * Inverse of aim_info_extract()
 */
int
aim_putuserinfo(ByteStream *bs, aim_userinfo_t *info)
{
	GSList *tlvlist = NULL;

	if (!bs || !info)
		return -EINVAL;

	byte_stream_put8(bs, strlen(info->bn));
	byte_stream_putstr(bs, info->bn);

	byte_stream_put16(bs, info->warnlevel);

	if (info->present & AIM_USERINFO_PRESENT_FLAGS)
		aim_tlvlist_add_16(&tlvlist, 0x0001, info->flags);
	if (info->present & AIM_USERINFO_PRESENT_MEMBERSINCE)
		aim_tlvlist_add_32(&tlvlist, 0x0002, info->membersince);
	if (info->present & AIM_USERINFO_PRESENT_ONLINESINCE)
		aim_tlvlist_add_32(&tlvlist, 0x0003, info->onlinesince);
	if (info->present & AIM_USERINFO_PRESENT_IDLE)
		aim_tlvlist_add_16(&tlvlist, 0x0004, info->idletime);

/* XXX - So, ICQ_OSCAR_SUPPORT is never defined anywhere... */
#ifdef ICQ_OSCAR_SUPPORT
	if (atoi(info->bn) != 0) {
		if (info->present & AIM_USERINFO_PRESENT_ICQEXTSTATUS)
			aim_tlvlist_add_16(&tlvlist, 0x0006, info->icqinfo.status);
		if (info->present & AIM_USERINFO_PRESENT_ICQIPADDR)
			aim_tlvlist_add_32(&tlvlist, 0x000a, info->icqinfo.ipaddr);
	}
#endif

	if (info->present & AIM_USERINFO_PRESENT_CAPABILITIES)
		aim_tlvlist_add_caps(&tlvlist, 0x000d, info->capabilities);

	if (info->present & AIM_USERINFO_PRESENT_SESSIONLEN)
		aim_tlvlist_add_32(&tlvlist, (guint16)((info->flags & AIM_FLAG_AOL) ? 0x0010 : 0x000f), info->sessionlen);

	byte_stream_put16(bs, aim_tlvlist_count(tlvlist));
	aim_tlvlist_write(bs, &tlvlist);
	aim_tlvlist_free(tlvlist);

	return 0;
}
Beispiel #2
0
/*
 * Part two of the ICQ hack.  Note the ignoring of the key.
 */
static int
goddamnicq2(OscarData *od, FlapConnection *conn, const char *sn, const char *password, ClientInfo *ci)
{
	FlapFrame *frame;
	GSList *tlvlist = NULL;
	int passwdlen;
	guint8 *password_encoded;
	guint32 distrib;

	passwdlen = strlen(password);
	password_encoded = (guint8 *)g_malloc(passwdlen+1);
	if (passwdlen > MAXICQPASSLEN)
		passwdlen = MAXICQPASSLEN;

	frame = flap_frame_new(od, 0x01, 1152);

	aim_encode_password(password, password_encoded);

	distrib = oscar_get_ui_info_int(
			od->icq ? "prpl-icq-distid" : "prpl-aim-distid",
			ci->distrib);

	byte_stream_put32(&frame->data, 0x00000001); /* FLAP Version */
	aim_tlvlist_add_str(&tlvlist, 0x0001, sn);
	aim_tlvlist_add_raw(&tlvlist, 0x0002, passwdlen, password_encoded);

	if (ci->clientstring != NULL)
		aim_tlvlist_add_str(&tlvlist, 0x0003, ci->clientstring);
	else {
		gchar *clientstring = oscar_get_clientstring();
		aim_tlvlist_add_str(&tlvlist, 0x0003, clientstring);
		g_free(clientstring);
	}
	aim_tlvlist_add_16(&tlvlist, 0x0016, (guint16)ci->clientid);
	aim_tlvlist_add_16(&tlvlist, 0x0017, (guint16)ci->major);
	aim_tlvlist_add_16(&tlvlist, 0x0018, (guint16)ci->minor);
	aim_tlvlist_add_16(&tlvlist, 0x0019, (guint16)ci->point);
	aim_tlvlist_add_16(&tlvlist, 0x001a, (guint16)ci->build);
	aim_tlvlist_add_32(&tlvlist, 0x0014, distrib); /* distribution chan */
	aim_tlvlist_add_str(&tlvlist, 0x000f, ci->lang);
	aim_tlvlist_add_str(&tlvlist, 0x000e, ci->country);

	aim_tlvlist_write(&frame->data, &tlvlist);

	g_free(password_encoded);
	aim_tlvlist_free(tlvlist);

	flap_connection_send(conn, frame);

	return 0;
}
Beispiel #3
0
/*
 * Subtype 0x0002
 *
 * This is the initial login request packet.
 *
 * NOTE!! If you want/need to make use of the aim_sendmemblock() function,
 * then the client information you send here must exactly match the
 * executable that you're pulling the data from.
 *
 * Java AIM 1.1.19:
 *   clientstring = "AOL Instant Messenger (TM) version 1.1.19 for Java built 03/24/98, freeMem 215871 totalMem 1048567, i686, Linus, #2 SMP Sun Feb 11 03:41:17 UTC 2001 2.4.1-ac9, IBM Corporation, 1.1.8, 45.3, Tue Mar 27 12:09:17 PST 2001"
 *   clientid = 0x0001
 *   major  = 0x0001
 *   minor  = 0x0001
 *   point = (not sent)
 *   build  = 0x0013
 *   unknown= (not sent)
 *
 * AIM for Linux 1.1.112:
 *   clientstring = "AOL Instant Messenger (SM)"
 *   clientid = 0x1d09
 *   major  = 0x0001
 *   minor  = 0x0001
 *   point = 0x0001
 *   build  = 0x0070
 *   unknown= 0x0000008b
 *   serverstore = 0x01
 *
 * @param truncate_pass Truncate the password to 8 characters.  This
 *        usually happens for AOL accounts.  We are told that we
 *        should truncate it if the 0x0017/0x0007 SNAC contains
 *        a TLV of type 0x0026 with data 0x0000.
 * @param allow_multiple_logins Allow multiple logins? If TRUE, the AIM
 *        server will prompt the user when multiple logins occur. If
 *        FALSE, existing connections (on other clients) will be
 *        disconnected automatically as we connect.
 */
int
aim_send_login(OscarData *od, FlapConnection *conn, const char *sn, const char *password, gboolean truncate_pass, ClientInfo *ci, const char *key, gboolean allow_multiple_logins)
{
	FlapFrame *frame;
	GSList *tlvlist = NULL;
	guint8 digest[16];
	aim_snacid_t snacid;
	size_t password_len;
	guint32 distrib;

	if (!ci || !sn || !password)
		return -EINVAL;

#ifdef USE_XOR_FOR_ICQ
	/* If we're signing on an ICQ account then use the older, XOR login method */
	if (aim_snvalid_icq(sn))
		return goddamnicq2(od, conn, sn, password, ci);
#endif

	frame = flap_frame_new(od, 0x02, 1152);

	snacid = aim_cachesnac(od, SNAC_FAMILY_AUTH, 0x0002, 0x0000, NULL, 0);
	aim_putsnac(&frame->data, SNAC_FAMILY_AUTH, 0x0002, 0x0000, snacid);

	aim_tlvlist_add_str(&tlvlist, 0x0001, sn);

	/* Truncate ICQ and AOL passwords, if necessary */
	password_len = strlen(password);
	if (oscar_util_valid_name_icq(sn) && (password_len > MAXICQPASSLEN))
		password_len = MAXICQPASSLEN;
	else if (truncate_pass && password_len > 8)
		password_len = 8;

	aim_encode_password_md5(password, password_len, key, digest);

	distrib = oscar_get_ui_info_int(
			od->icq ? "prpl-icq-distid" : "prpl-aim-distid",
			ci->distrib);

	aim_tlvlist_add_raw(&tlvlist, 0x0025, 16, digest);

#ifndef USE_OLD_MD5
	aim_tlvlist_add_noval(&tlvlist, 0x004c);
#endif

	if (ci->clientstring != NULL)
		aim_tlvlist_add_str(&tlvlist, 0x0003, ci->clientstring);
	else {
		gchar *clientstring = oscar_get_clientstring();
		aim_tlvlist_add_str(&tlvlist, 0x0003, clientstring);
		g_free(clientstring);
	}
	aim_tlvlist_add_16(&tlvlist, 0x0016, (guint16)ci->clientid);
	aim_tlvlist_add_16(&tlvlist, 0x0017, (guint16)ci->major);
	aim_tlvlist_add_16(&tlvlist, 0x0018, (guint16)ci->minor);
	aim_tlvlist_add_16(&tlvlist, 0x0019, (guint16)ci->point);
	aim_tlvlist_add_16(&tlvlist, 0x001a, (guint16)ci->build);
	aim_tlvlist_add_32(&tlvlist, 0x0014, distrib);
	aim_tlvlist_add_str(&tlvlist, 0x000f, ci->lang);
	aim_tlvlist_add_str(&tlvlist, 0x000e, ci->country);

	/*
	 * If set, old-fashioned buddy lists will not work. You will need
	 * to use SSI.
	 */
	aim_tlvlist_add_8(&tlvlist, 0x004a, (allow_multiple_logins ? 0x01 : 0x03));

	aim_tlvlist_write(&frame->data, &tlvlist);

	aim_tlvlist_free(tlvlist);

	flap_connection_send(conn, frame);

	return 0;
}