changeset 10464:61ef9a964574

[gaim-migrate @ 11739] SecurID support for AIM. This is untested. I'll try to get it tested in the next few days. I'm backporting this to oldstatus. If you don't know what SecurID, google around for it. Basically it's an optional additional authentication method that AOL members can opt for (and pay an extra fee). After entering your password, you are prompted for a 6 digit number from a digit readout/ keychain-sized LCD screen. This number is pseudo-random and changes every 60 seconds. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sun, 02 Jan 2005 07:20:38 +0000
parents 9bed28273ec7
children 2c8d71687ea5
files src/plugin.c src/protocols/oscar/aim.h src/protocols/oscar/aim_cbtypes.h src/protocols/oscar/auth.c src/protocols/oscar/bstream.c src/protocols/oscar/oscar.c
diffstat 6 files changed, 138 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugin.c	Fri Dec 31 16:34:22 2004 +0000
+++ b/src/plugin.c	Sun Jan 02 07:20:38 2005 +0000
@@ -979,7 +979,6 @@
 													(GCompareFunc)compare_prpl);
 	}
 
-
 #endif /* GAIM_PLUGINS */
 }
 
--- a/src/protocols/oscar/aim.h	Fri Dec 31 16:34:22 2004 +0000
+++ b/src/protocols/oscar/aim.h	Sun Jan 02 07:20:38 2005 +0000
@@ -214,6 +214,15 @@
 	"us", "en", \
 }
 
+#define CLIENTINFO_AIM_5_9_3702 { \
+	"AOL Instant Messenger, version 5.9.3702/WIN32", \
+	0x0109, \
+	0x0005, 0x0009, \
+	0x0000, 0x0e76, \
+	0x00000111, \
+	"us", "en", \
+}
+
 #define CLIENTINFO_ICHAT_1_0 { \
 	"Apple iChat", \
 	0x311a, \
@@ -549,6 +558,8 @@
 faim_export int aim_sendflapver(aim_session_t *sess, aim_conn_t *conn);
 faim_export int aim_request_login(aim_session_t *sess, aim_conn_t *conn, const char *sn);
 faim_export int aim_send_login(aim_session_t *, aim_conn_t *, const char *, const char *, struct client_info_s *, const char *key);
+/* 0x000b */ faim_export int aim_auth_securid_send(aim_session_t *sess, const char *securid);
+
 faim_export void aim_purge_rxqueue(aim_session_t *);
 faim_export void aim_cleansnacs(aim_session_t *, int maxage);
 
--- a/src/protocols/oscar/aim_cbtypes.h	Fri Dec 31 16:34:22 2004 +0000
+++ b/src/protocols/oscar/aim_cbtypes.h	Sun Jan 02 07:20:38 2005 +0000
@@ -241,6 +241,8 @@
 #define AIM_CB_ATH_LOGINRESPONSE 0x0003
 #define AIM_CB_ATH_AUTHREQ 0x0006
 #define AIM_CB_ATH_AUTHRESPONSE 0x0007
+#define AIM_CB_ATH_SECURID_REQUEST 0x000a
+#define AIM_CB_ATH_SECURID_RESPONSE 0x000b
 
 /*
  * SNAC Family: Email
--- a/src/protocols/oscar/auth.c	Fri Dec 31 16:34:22 2004 +0000
+++ b/src/protocols/oscar/auth.c	Sun Jan 02 07:20:38 2005 +0000
@@ -468,15 +468,22 @@
 
 	aim_sendflapver(sess, conn);
 
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2+2+strlen(sn) /*+8*/ )))
+	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2+2+strlen(sn)+8 )))
 		return -ENOMEM;
 
 	snacid = aim_cachesnac(sess, 0x0017, 0x0006, 0x0000, NULL, 0);
 	aim_putsnac(&fr->data, 0x0017, 0x0006, 0x0000, snacid);
 
 	aim_tlvlist_add_raw(&tl, 0x0001, strlen(sn), sn);
-/*	aim_tlvlist_add_noval(&tl, 0x004b);
-	aim_tlvlist_add_noval(&tl, 0x005a); */
+
+	/*
+	 * These are sent in logins for recent WinAIM clients.  Maybe tells
+	 * the server we're able to handle SecurID requests?  That's a complete
+	 * guess.
+	 */
+	aim_tlvlist_add_noval(&tl, 0x004b);
+	aim_tlvlist_add_noval(&tl, 0x005a);
+
 	aim_tlvlist_write(&fr->data, &tl);
 	aim_tlvlist_free(&tl);
 
@@ -515,6 +522,53 @@
 	return ret;
 }
 
+/**
+ * Subtype 0x000a
+ *
+ * Receive SecurID request.
+ */
+static int got_securid_request(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
+{
+	int ret = 0;
+	aim_rxcallback_t userfunc;
+
+	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
+		ret = userfunc(sess, rx);
+
+	return ret;
+}
+
+/**
+ * Subtype 0x000b
+ *
+ * Send SecurID response.
+ */
+faim_export int aim_auth_securid_send(aim_session_t *sess, const char *securid)
+{
+	aim_conn_t *conn;
+	aim_frame_t *fr;
+	aim_snacid_t snacid;
+	int len;
+
+	if (!sess || !(conn = aim_getconn_type_all(sess, AIM_CONN_TYPE_AUTH)) || !securid)
+		return -EINVAL;
+
+	len = strlen(securid);
+
+	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x01, 10+2+len)))
+		return -ENOMEM;
+
+	snacid = aim_cachesnac(sess, AIM_CB_FAM_ATH, AIM_CB_ATH_SECURID_RESPONSE, 0x0000, NULL, 0);
+	aim_putsnac(&fr->data, AIM_CB_FAM_ATH, AIM_CB_ATH_SECURID_RESPONSE, 0x0000, 0);
+
+	aimbs_put16(&fr->data, len);
+	aimbs_putraw(&fr->data, securid, len);
+
+	aim_tx_enqueue(sess, fr);
+
+	return 0;
+}
+
 static void auth_shutdown(aim_session_t *sess, aim_module_t *mod)
 {
 	if (sess->authinfo) {
@@ -540,6 +594,8 @@
 		return parse(sess, mod, rx, snac, bs);
 	else if (snac->subtype == 0x0007)
 		return keyparse(sess, mod, rx, snac, bs);
+	else if (snac->subtype == 0x000a)
+		return got_securid_request(sess, mod, rx, snac, bs);
 
 	return 0;
 }
--- a/src/protocols/oscar/bstream.c	Fri Dec 31 16:34:22 2004 +0000
+++ b/src/protocols/oscar/bstream.c	Sun Jan 02 07:20:38 2005 +0000
@@ -5,11 +5,11 @@
  */
 
 #define FAIM_INTERNAL
-#include <aim.h> 
+#include <aim.h>
 
 faim_internal int aim_bstream_init(aim_bstream_t *bs, fu8_t *data, int len)
 {
-	
+
 	if (!bs)
 		return -1;
 
@@ -62,67 +62,67 @@
 
 faim_internal fu8_t aimbs_get8(aim_bstream_t *bs)
 {
-	
+
 	if (aim_bstream_empty(bs) < 1)
 		return 0; /* XXX throw an exception */
-	
+
 	bs->offset++;
-	
+
 	return aimutil_get8(bs->data + bs->offset - 1);
 }
 
 faim_internal fu16_t aimbs_get16(aim_bstream_t *bs)
 {
-	
+
 	if (aim_bstream_empty(bs) < 2)
 		return 0; /* XXX throw an exception */
-	
+
 	bs->offset += 2;
-	
+
 	return aimutil_get16(bs->data + bs->offset - 2);
 }
 
 faim_internal fu32_t aimbs_get32(aim_bstream_t *bs)
 {
-	
+
 	if (aim_bstream_empty(bs) < 4)
 		return 0; /* XXX throw an exception */
-	
+
 	bs->offset += 4;
-	
+
 	return aimutil_get32(bs->data + bs->offset - 4);
 }
 
 faim_internal fu8_t aimbs_getle8(aim_bstream_t *bs)
 {
-	
+
 	if (aim_bstream_empty(bs) < 1)
 		return 0; /* XXX throw an exception */
-	
+
 	bs->offset++;
-	
+
 	return aimutil_getle8(bs->data + bs->offset - 1);
 }
 
 faim_internal fu16_t aimbs_getle16(aim_bstream_t *bs)
 {
-	
+
 	if (aim_bstream_empty(bs) < 2)
 		return 0; /* XXX throw an exception */
-	
+
 	bs->offset += 2;
-	
+
 	return aimutil_getle16(bs->data + bs->offset - 2);
 }
 
 faim_internal fu32_t aimbs_getle32(aim_bstream_t *bs)
 {
-	
+
 	if (aim_bstream_empty(bs) < 4)
 		return 0; /* XXX throw an exception */
-	
+
 	bs->offset += 4;
-	
+
 	return aimutil_getle32(bs->data + bs->offset - 4);
 }
 
--- a/src/protocols/oscar/oscar.c	Fri Dec 31 16:34:22 2004 +0000
+++ b/src/protocols/oscar/oscar.c	Sun Jan 02 07:20:38 2005 +0000
@@ -219,6 +219,7 @@
 /* All the libfaim->gaim callback functions */
 static int gaim_parse_auth_resp  (aim_session_t *, aim_frame_t *, ...);
 static int gaim_parse_login      (aim_session_t *, aim_frame_t *, ...);
+static int gaim_parse_auth_securid_request(aim_session_t *, aim_frame_t *, ...);
 static int gaim_handle_redirect  (aim_session_t *, aim_frame_t *, ...);
 static int gaim_info_change      (aim_session_t *, aim_frame_t *, ...);
 static int gaim_account_confirm  (aim_session_t *, aim_frame_t *, ...);
@@ -1783,8 +1784,9 @@
 	}
 
 	aim_conn_addhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, gaim_connerr, 0);
+	aim_conn_addhandler(sess, conn, 0x0017, 0x0003, gaim_parse_auth_resp, 0);
 	aim_conn_addhandler(sess, conn, 0x0017, 0x0007, gaim_parse_login, 0);
-	aim_conn_addhandler(sess, conn, 0x0017, 0x0003, gaim_parse_auth_resp, 0);
+	aim_conn_addhandler(sess, conn, AIM_CB_FAM_ATH, AIM_CB_ATH_SECURID_REQUEST, gaim_parse_auth_securid_request, 0);
 
 	conn->status |= AIM_CONN_STATUS_INPROGRESS;
 	if (gaim_proxy_connect(account, gaim_account_get_string(account, "server", FAIM_LOGIN_SERVER),
@@ -2339,6 +2341,49 @@
 	return 1;
 }
 
+static void
+gaim_parse_auth_securid_request_yes_cb(gpointer user_data, const char *msg)
+{
+	GaimConnection *gc = user_data;
+	OscarData *od = gc->proto_data;
+	aim_session_t *sess = od->sess;
+
+	aim_auth_securid_send(sess, msg);
+}
+
+static void
+gaim_parse_auth_securid_request_no_cb(gpointer user_data, const char *value)
+{
+	GaimConnection *gc = user_data;
+	OscarData *od = gc->proto_data;
+
+	/* Disconnect */
+	gc->wants_to_die = TRUE;
+	gaim_connection_error(gc, _("The SecurID key entered is invalid."));
+	od->killme = TRUE;
+}
+
+static int
+gaim_parse_auth_securid_request(aim_session_t *sess, aim_frame_t *fr, ...)
+{
+	GaimConnection *gc = sess->aux_data;
+	GaimAccount *account = gaim_connection_get_account(gc);
+	gchar *primary;
+
+	gaim_debug_info("oscar", "Got SecurID request\n");
+
+	primary = g_strdup_printf("Enter the SecurID key for %s.", gaim_account_get_username(account));
+	gaim_request_input(gc, NULL, _("Enter SecurID"), primary,
+					   _("Enter the 6 digit number from the digital display."),
+					   FALSE, FALSE, NULL,
+					   _("OK"), G_CALLBACK(gaim_parse_auth_securid_request_yes_cb),
+					   _("Cancel"), G_CALLBACK(gaim_parse_auth_securid_request_no_cb),
+					   gc);
+	g_free(primary);
+
+	return 1;
+}
+
 /* XXX - Should use gaim_url_fetch for the below stuff */
 struct pieceofcrap {
 	GaimConnection *gc;