changeset 17192:c72295a65f7a

Fix signing on to AIM with an AOL screen name with a password of more than 8 characters. For someone AOL passwords get truncated to 8 characters. No idea why, but at least they send us a flag to let us know that the password should be truncated.
author Mark Doliner <mark@kingant.net>
date Wed, 23 May 2007 06:24:15 +0000
parents 12d0ad970a15
children 7befa48ab574
files libpurple/protocols/oscar/family_auth.c libpurple/protocols/oscar/oscar.c libpurple/protocols/oscar/oscar.h
diffstat 3 files changed, 37 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/oscar/family_auth.c	Tue May 22 13:00:00 2007 +0000
+++ b/libpurple/protocols/oscar/family_auth.c	Wed May 23 06:24:15 2007 +0000
@@ -79,7 +79,7 @@
 
 #ifdef USE_OLD_MD5
 static int
-aim_encode_password_md5(const char *password, const char *key, guint8 *digest)
+aim_encode_password_md5(const char *password, size_t password_len, const char *key, guint8 *digest)
 {
 	PurpleCipher *cipher;
 	PurpleCipherContext *context;
@@ -88,7 +88,7 @@
 
 	context = purple_cipher_context_new(cipher, NULL);
 	purple_cipher_context_append(context, (const guchar *)key, strlen(key));
-	purple_cipher_context_append(context, (const guchar *)password, strlen(password));
+	purple_cipher_context_append(context, (const guchar *)password, password_len);
 	purple_cipher_context_append(context, (const guchar *)AIM_MD5_STRING, strlen(AIM_MD5_STRING));
 	purple_cipher_context_digest(context, 16, digest, NULL);
 	purple_cipher_context_destroy(context);
@@ -97,7 +97,7 @@
 }
 #else
 static int
-aim_encode_password_md5(const char *password, const char *key, guint8 *digest)
+aim_encode_password_md5(const char *password, size_t password_len, const char *key, guint8 *digest)
 {
 	PurpleCipher *cipher;
 	PurpleCipherContext *context;
@@ -106,7 +106,7 @@
 	cipher = purple_ciphers_find_cipher("md5");
 
 	context = purple_cipher_context_new(cipher, NULL);
-	purple_cipher_context_append(context, (const guchar *)password, strlen(password));
+	purple_cipher_context_append(context, (const guchar *)password, password_len);
 	purple_cipher_context_digest(context, 16, passdigest, NULL);
 	purple_cipher_context_destroy(context);
 
@@ -198,12 +198,13 @@
  *
  */
 int
-aim_send_login(OscarData *od, FlapConnection *conn, const char *sn, const char *password, ClientInfo *ci, const char *key)
+aim_send_login(OscarData *od, FlapConnection *conn, const char *sn, const char *password, gboolean truncate_pass, ClientInfo *ci, const char *key)
 {
 	FlapFrame *frame;
 	aim_tlvlist_t *tl = NULL;
 	guint8 digest[16];
 	aim_snacid_t snacid;
+	size_t password_len;
 
 	if (!ci || !sn || !password)
 		return -EINVAL;
@@ -221,18 +222,16 @@
 
 	aim_tlvlist_add_str(&tl, 0x0001, sn);
 
-	/* Truncate ICQ passwords, if necessary */
-	if (isdigit(sn[0]) && (strlen(password) > MAXICQPASSLEN))
-	{
-		char truncated[MAXICQPASSLEN + 1];
-		strncpy(truncated, password, MAXICQPASSLEN);
-		truncated[MAXICQPASSLEN] = 0;
-		aim_encode_password_md5(truncated, key, digest);
-	}
-	else
-	{
-		aim_encode_password_md5(password, key, digest);
-	}
+	/* Truncate ICQ and AOL passwords, if necessary */
+	password_len = strlen(password);
+fprintf(stderr, "1 password_len=%zu\n", password_len);
+	if (isdigit(sn[0]) && (password_len > MAXICQPASSLEN))
+		password_len = MAXICQPASSLEN;
+	else if (truncate_pass && password_len > 8)
+		password_len = 8;
+fprintf(stderr, "2 password_len=%zu\n", password_len);
+
+	aim_encode_password_md5(password, password_len, key, digest);
 
 	aim_tlvlist_add_raw(&tl, 0x0025, 16, digest);
 
@@ -520,18 +519,29 @@
 	int keylen, ret = 1;
 	aim_rxcallback_t userfunc;
 	char *keystr;
+	aim_tlvlist_t *tlvlist;
+	gboolean truncate_pass;
 
 	keylen = byte_stream_get16(bs);
 	keystr = byte_stream_getstr(bs, keylen);
+	tlvlist = aim_tlvlist_read(bs);
+
+	/*
+	 * If the truncate_pass TLV exists then we should truncate the
+	 * user's password to 8 characters.  This flag is sent when you
+	 * try to log in with an AOL user's screen name.
+	 */
+	truncate_pass = aim_tlv_gettlv(tlvlist, 0x0026, 1) != NULL;
 
 	/* XXX - When GiantGrayPanda signed on AIM I got a thing asking me to register
 	 * for the netscape network.  This SNAC had a type 0x0058 TLV with length 10.
 	 * Data is 0x0007 0004 3e19 ae1e 0006 0004 0000 0005 */
 
 	if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
-		ret = userfunc(od, conn, frame, keystr);
+		ret = userfunc(od, conn, frame, keystr, (int)truncate_pass);
 
 	free(keystr);
+	aim_tlvlist_free(&tlvlist);
 
 	return ret;
 }
--- a/libpurple/protocols/oscar/oscar.c	Tue May 22 13:00:00 2007 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Wed May 23 06:24:15 2007 +0000
@@ -1625,16 +1625,19 @@
 	ClientInfo info = CLIENTINFO_PURPLE;
 	va_list ap;
 	char *key;
+	gboolean truncate_pass;
 
 	gc = od->gc;
 	account = purple_connection_get_account(gc);
 
 	va_start(ap, fr);
 	key = va_arg(ap, char *);
+	truncate_pass = va_arg(ap, int);
 	va_end(ap);
 
 	aim_send_login(od, conn, purple_account_get_username(account),
-				   purple_connection_get_password(gc), &info, key);
+			purple_connection_get_password(gc), truncate_pass,
+			&info, key);
 
 	purple_connection_update_progress(gc, _("Password sent"), 2, OSCAR_CONNECT_STEPS);
 	ck[2] = 0x6c;
--- a/libpurple/protocols/oscar/oscar.h	Tue May 22 13:00:00 2007 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Wed May 23 06:24:15 2007 +0000
@@ -274,6 +274,10 @@
 	"us", "en", \
 }
 
+/*
+ * TODO: Use PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION, and
+ *       PURPLE_MICRO_VERSION?  Or did that break things?
+ */
 #define CLIENTINFO_PURPLE { \
 	"Purple/" VERSION, \
 	0x0109, \
@@ -574,7 +578,7 @@
 
 void aim_clientready(OscarData *od, FlapConnection *conn);
 int aim_request_login(OscarData *od, FlapConnection *conn, const char *sn);
-int aim_send_login(OscarData *, FlapConnection *, const char *, const char *, ClientInfo *, const char *key);
+int aim_send_login(OscarData *od, FlapConnection *conn, const char *sn, const char *password, gboolean truncate_pass, ClientInfo *ci, const char *key);
 /* 0x000b */ int aim_auth_securid_send(OscarData *od, const char *securid);
 
 void aim_cleansnacs(OscarData *, int maxage);