예제 #1
0
/*
 * send_login(int socket, char *sn, char *password)
 *
 * 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.
 *
 * WinAIM 4.8.2540
 *   clientstring = "AOL Instant Messenger (SM), version 4.8.2540/WIN32"
 *   clientid = 0x0109
 *   major = 0x0004
 *   minor = 0x0008
 *   point = 0x0000
 *   build = 0x09ec
 *   t(0x0014) = 0x000000af
 *   t(0x004a) = 0x01
 *
 * WinAIM 4.3.2188:
 *   clientstring = "AOL Instant Messenger (SM), version 4.3.2188/WIN32"
 *   clientid = 0x0109
 *   major = 0x0400
 *   minor = 0x0003
 *   point = 0x0000
 *   build = 0x088c
 *   unknown = 0x00000086
 *   lang = "en"
 *   country = "us"
 *   unknown4a = 0x01
 *
 * Latest WinAIM that libfaim can emulate without server-side buddylists:
 *   clientstring = "AOL Instant Messenger (SM), version 4.1.2010/WIN32"
 *   clientid = 0x0004
 *   major  = 0x0004
 *   minor  = 0x0001
 *   point = 0x0000
 *   build  = 0x07da
 *   unknown= 0x0000004b
 *
 * WinAIM 3.5.1670:
 *   clientstring = "AOL Instant Messenger (SM), version 3.5.1670/WIN32"
 *   clientid = 0x0004
 *   major =  0x0003
 *   minor =  0x0005
 *   point = 0x0000
 *   build =  0x0686
 *   unknown =0x0000002a
 *
 * 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
 *
 */
int aim_send_login(aim_session_t *sess, aim_conn_t *conn, const char *sn, const char *password,
                   struct client_info_s *ci, const char *key)
{
	aim_frame_t *fr;
	aim_tlvlist_t *tl = NULL;
	guint8 digest[16];
	aim_snacid_t snacid;

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

	/*
	 * What the XORLOGIN flag _really_ means is that its an ICQ login,
	 * which is really stupid and painful, so its not done here.
	 *
	 */
	if (sess->flags & AIM_SESS_FLAGS_XORLOGIN) {
		return goddamnicq2(sess, conn, sn, password);
	}


	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152))) {
		return -ENOMEM;
	}

	snacid = aim_cachesnac(sess, 0x0017, 0x0002, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x0017, 0x0002, 0x0000, snacid);

	aim_addtlvtochain_raw(&tl, 0x0001, strlen(sn), (guint8 *) sn);

	aim_encode_password_md5(password, key, digest);
	aim_addtlvtochain_raw(&tl, 0x0025, 16, digest);

	/*
	 * Newer versions of winaim have an empty type x004c TLV here.
	 */

	if (ci->clientstring) {
		aim_addtlvtochain_raw(&tl, 0x0003, strlen(ci->clientstring), (guint8 *) ci->clientstring);
	}
	aim_addtlvtochain16(&tl, 0x0016, (guint16) ci->clientid);
	aim_addtlvtochain16(&tl, 0x0017, (guint16) ci->major);
	aim_addtlvtochain16(&tl, 0x0018, (guint16) ci->minor);
	aim_addtlvtochain16(&tl, 0x0019, (guint16) ci->point);
	aim_addtlvtochain16(&tl, 0x001a, (guint16) ci->build);
	aim_addtlvtochain_raw(&tl, 0x000e, strlen(ci->country), (guint8 *) ci->country);
	aim_addtlvtochain_raw(&tl, 0x000f, strlen(ci->lang), (guint8 *) ci->lang);

	/*
	 * If set, old-fashioned buddy lists will not work. You will need
	 * to use SSI.
	 */
	aim_addtlvtochain8(&tl, 0x004a, 0x01);

	aim_writetlvchain(&fr->data, &tl);

	aim_freetlvchain(&tl);

	aim_tx_enqueue(sess, fr);

	return 0;
}
예제 #2
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;
}