# HG changeset patch # User Mark Doliner # Date 1104650438 0 # Node ID 61ef9a964574d00fd224f638dc28b3c20154ba7f # Parent 9bed28273ec742349e5dce6a73e7fef5a202346d [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 diff -r 9bed28273ec7 -r 61ef9a964574 src/plugin.c --- 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 */ } diff -r 9bed28273ec7 -r 61ef9a964574 src/protocols/oscar/aim.h --- 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); diff -r 9bed28273ec7 -r 61ef9a964574 src/protocols/oscar/aim_cbtypes.h --- 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 diff -r 9bed28273ec7 -r 61ef9a964574 src/protocols/oscar/auth.c --- 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; } diff -r 9bed28273ec7 -r 61ef9a964574 src/protocols/oscar/bstream.c --- 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 +#include 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); } diff -r 9bed28273ec7 -r 61ef9a964574 src/protocols/oscar/oscar.c --- 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;