/* aim_auth.c Deals with the authorizer. */ #define FAIM_INTERNAL #include /* this just pushes the passed cookie onto the passed connection -- NO SNAC! */ faim_export int aim_auth_sendcookie(struct aim_session_t *sess, struct aim_conn_t *conn, unsigned char *chipsahoy) { struct command_tx_struct *newpacket; int curbyte=0; if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0001, 4+2+2+AIM_COOKIELEN))) return -1; newpacket->lock = 1; curbyte += aimutil_put16(newpacket->data+curbyte, 0x0000); curbyte += aimutil_put16(newpacket->data+curbyte, 0x0001); curbyte += aimutil_put16(newpacket->data+curbyte, 0x0006); curbyte += aimutil_put16(newpacket->data+curbyte, AIM_COOKIELEN); memcpy(newpacket->data+curbyte, chipsahoy, AIM_COOKIELEN); return aim_tx_enqueue(sess, newpacket); } /* * This is sent back as a general response to the login command. * It can be either an error or a success, depending on the * precense of certain TLVs. * * The client should check the value passed as errorcode. If * its nonzero, there was an error. * */ static int parse(struct aim_session_t *sess, aim_module_t *mod, struct command_rx_struct *rx, aim_modsnac_t *snac, unsigned char *data, int datalen) { struct aim_tlvlist_t *tlvlist; int ret = 0; aim_rxcallback_t userfunc; char *sn = NULL, *bosip = NULL, *errurl = NULL, *email = NULL; unsigned char *cookie = NULL; int errorcode = 0, regstatus = 0; int latestbuild = 0, latestbetabuild = 0; char *latestrelease = NULL, *latestbeta = NULL; char *latestreleaseurl = NULL, *latestbetaurl = NULL; char *latestreleaseinfo = NULL, *latestbetainfo = NULL; /* * Read block of TLVs. All further data is derived * from what is parsed here. * */ tlvlist = aim_readtlvchain(data, datalen); /* * No matter what, we should have a screen name. */ memset(sess->sn, 0, sizeof(sess->sn)); if (aim_gettlv(tlvlist, 0x0001, 1)) { sn = aim_gettlv_str(tlvlist, 0x0001, 1); strncpy(sess->sn, sn, sizeof(sess->sn)); } /* * Check for an error code. If so, we should also * have an error url. */ if (aim_gettlv(tlvlist, 0x0008, 1)) errorcode = aim_gettlv16(tlvlist, 0x0008, 1); if (aim_gettlv(tlvlist, 0x0004, 1)) errurl = aim_gettlv_str(tlvlist, 0x0004, 1); /* * BOS server address. */ if (aim_gettlv(tlvlist, 0x0005, 1)) bosip = aim_gettlv_str(tlvlist, 0x0005, 1); /* * Authorization cookie. */ if (aim_gettlv(tlvlist, 0x0006, 1)) { struct aim_tlv_t *tmptlv; tmptlv = aim_gettlv(tlvlist, 0x0006, 1); if ((cookie = malloc(tmptlv->length))) memcpy(cookie, tmptlv->value, tmptlv->length); } /* * The email address attached to this account * Not available for ICQ logins. */ if (aim_gettlv(tlvlist, 0x0011, 1)) email = aim_gettlv_str(tlvlist, 0x0011, 1); /* * The registration status. (Not real sure what it means.) * Not available for ICQ logins. * * 1 = No disclosure * 2 = Limited disclosure * 3 = Full disclosure * * This has to do with whether your email address is available * to other users or not. AFAIK, this feature is no longer used. * */ if (aim_gettlv(tlvlist, 0x0013, 1)) regstatus = aim_gettlv16(tlvlist, 0x0013, 1); if (aim_gettlv(tlvlist, 0x0040, 1)) latestbetabuild = aim_gettlv32(tlvlist, 0x0040, 1); if (aim_gettlv(tlvlist, 0x0041, 1)) latestbetaurl = aim_gettlv_str(tlvlist, 0x0041, 1); if (aim_gettlv(tlvlist, 0x0042, 1)) latestbetainfo = aim_gettlv_str(tlvlist, 0x0042, 1); if (aim_gettlv(tlvlist, 0x0043, 1)) latestbeta = aim_gettlv_str(tlvlist, 0x0043, 1); if (aim_gettlv(tlvlist, 0x0048, 1)) ; /* no idea what this is */ if (aim_gettlv(tlvlist, 0x0044, 1)) latestbuild = aim_gettlv32(tlvlist, 0x0044, 1); if (aim_gettlv(tlvlist, 0x0045, 1)) latestreleaseurl = aim_gettlv_str(tlvlist, 0x0045, 1); if (aim_gettlv(tlvlist, 0x0046, 1)) latestreleaseinfo = aim_gettlv_str(tlvlist, 0x0046, 1); if (aim_gettlv(tlvlist, 0x0047, 1)) latestrelease = aim_gettlv_str(tlvlist, 0x0047, 1); if (aim_gettlv(tlvlist, 0x0049, 1)) ; /* no idea what this is */ if ((userfunc = aim_callhandler(sess, rx->conn, snac?snac->family:0x0017, snac?snac->subtype:0x0003))) ret = userfunc(sess, rx, sn, errorcode, errurl, regstatus, email, bosip, cookie, latestrelease, latestbuild, latestreleaseurl, latestreleaseinfo, latestbeta, latestbetabuild, latestbetaurl, latestbetainfo); if (sn) free(sn); if (bosip) free(bosip); if (errurl) free(errurl); if (email) free(email); if (cookie) free(cookie); if (latestrelease) free(latestrelease); if (latestreleaseurl) free(latestreleaseurl); if (latestbeta) free(latestbeta); if (latestbetaurl) free(latestbetaurl); if (latestreleaseinfo) free(latestreleaseinfo); if (latestbetainfo) free(latestbetainfo); aim_freetlvchain(&tlvlist); return ret; } /* * Middle handler for 0017/0007 SNACs. Contains the auth key prefixed * by only its length in a two byte word. * * Calls the client, which should then use the value to call aim_send_login. * */ static int keyparse(struct aim_session_t *sess, aim_module_t *mod, struct command_rx_struct *rx, aim_modsnac_t *snac, unsigned char *data, int datalen) { unsigned char *key; int keylen; int ret = 1; aim_rxcallback_t userfunc; keylen = aimutil_get16(data); if (!(key = malloc(keylen+1))) return ret; memcpy(key, data+2, keylen); key[keylen] = '\0'; if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) ret = userfunc(sess, rx, (char *)key); free(key); return ret; } static int snachandler(struct aim_session_t *sess, aim_module_t *mod, struct command_rx_struct *rx, aim_modsnac_t *snac, unsigned char *data, int datalen) { if (snac->subtype == 0x0003) return parse(sess, mod, rx, snac, data, datalen); else if (snac->subtype == 0x0007) return keyparse(sess, mod, rx, snac, data, datalen); return 0; } faim_internal int auth_modfirst(struct aim_session_t *sess, aim_module_t *mod) { mod->family = 0x0017; mod->version = 0x0000; mod->flags = 0; strncpy(mod->name, "auth", sizeof(mod->name)); mod->snachandler = snachandler; return 0; }