Changeset a39ede7 for protocols/oscar/auth.c
- Timestamp:
- 2018-03-31T02:04:45Z (7 years ago)
- Branches:
- master
- Children:
- 246b98b
- Parents:
- 9459ca2
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/oscar/auth.c
r9459ca2 ra39ede7 7 7 8 8 #include "md5.h" 9 10 static int aim_encode_password(const char *password, unsigned char *encoded);11 9 12 10 /* … … 56 54 57 55 aim_tx_enqueue(sess, fr); 58 59 return 0;60 }61 62 /*63 * This is a bit confusing.64 *65 * Normal SNAC login goes like this:66 * - connect67 * - server sends flap version68 * - client sends flap version69 * - client sends screen name (17/6)70 * - server sends hash key (17/7)71 * - client sends auth request (17/2 -- aim_send_login)72 * - server yells73 *74 * XOR login (for ICQ) goes like this:75 * - connect76 * - server sends flap version77 * - client sends auth request which contains flap version (aim_send_login)78 * - server yells79 *80 * For the client API, we make them implement the most complicated version,81 * and for the simpler version, we fake it and make it look like the more82 * complicated process.83 *84 * This is done by giving the client a faked key, just so we can convince85 * them to call aim_send_login right away, which will detect the session86 * flag that says this is XOR login and ignore the key, sending an ICQ87 * login request instead of the normal SNAC one.88 *89 * As soon as AOL makes ICQ log in the same way as AIM, this is /gone/.90 *91 * XXX This may cause problems if the client relies on callbacks only92 * being called from the context of aim_rxdispatch()...93 *94 */95 static int goddamnicq(aim_session_t *sess, aim_conn_t *conn, const char *sn)96 {97 aim_frame_t fr;98 aim_rxcallback_t userfunc;99 100 sess->flags &= ~AIM_SESS_FLAGS_SNACLOGIN;101 sess->flags |= AIM_SESS_FLAGS_XORLOGIN;102 103 fr.conn = conn;104 105 if ((userfunc = aim_callhandler(sess, conn, 0x0017, 0x0007))) {106 userfunc(sess, &fr, "");107 }108 56 109 57 return 0; … … 123 71 aim_snacid_t snacid; 124 72 aim_tlvlist_t *tl = NULL; 125 struct im_connection *ic = sess->aux_data;126 73 127 74 if (!sess || !conn || !sn) { … … 129 76 } 130 77 131 if (g_ascii_isdigit(sn[0]) && set_getbool(&ic->acc->set, "old_icq_auth")) {132 return goddamnicq(sess, conn, sn);133 }134 135 78 sess->flags |= AIM_SESS_FLAGS_SNACLOGIN; 136 79 … … 146 89 aim_addtlvtochain_raw(&tl, 0x0001, strlen(sn), (guint8 *) sn); 147 90 aim_writetlvchain(&fr->data, &tl); 148 aim_freetlvchain(&tl);149 150 aim_tx_enqueue(sess, fr);151 152 return 0;153 }154 155 /*156 * Part two of the ICQ hack. Note the ignoring of the key and clientinfo.157 */158 static int goddamnicq2(aim_session_t *sess, aim_conn_t *conn, const char *sn, const char *password)159 {160 static const char clientstr[] = { "ICQ Inc. - Product of ICQ (TM) 2001b.5.17.1.3642.85" };161 static const char lang[] = { "en" };162 static const char country[] = { "us" };163 aim_frame_t *fr;164 aim_tlvlist_t *tl = NULL;165 guint8 *password_encoded;166 167 if (!(password_encoded = (guint8 *) g_malloc(strlen(password)))) {168 return -ENOMEM;169 }170 171 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x01, 1152))) {172 g_free(password_encoded);173 return -ENOMEM;174 }175 176 aim_encode_password(password, password_encoded);177 178 aimbs_put32(&fr->data, 0x00000001);179 aim_addtlvtochain_raw(&tl, 0x0001, strlen(sn), (guint8 *) sn);180 aim_addtlvtochain_raw(&tl, 0x0002, strlen(password), password_encoded);181 aim_addtlvtochain_raw(&tl, 0x0003, strlen(clientstr), (guint8 *) clientstr);182 aim_addtlvtochain16(&tl, 0x0016, 0x010a); /* cliend ID */183 aim_addtlvtochain16(&tl, 0x0017, 0x0005); /* major version */184 aim_addtlvtochain16(&tl, 0x0018, 0x0011); /* minor version */185 aim_addtlvtochain16(&tl, 0x0019, 0x0001); /* point version */186 aim_addtlvtochain16(&tl, 0x001a, 0x0e3a); /* build */187 aim_addtlvtochain32(&tl, 0x0014, 0x00000055); /* distribution chan */188 aim_addtlvtochain_raw(&tl, 0x000f, strlen(lang), (guint8 *) lang);189 aim_addtlvtochain_raw(&tl, 0x000e, strlen(country), (guint8 *) country);190 191 aim_writetlvchain(&fr->data, &tl);192 193 g_free(password_encoded);194 91 aim_freetlvchain(&tl); 195 92 … … 280 177 } 281 178 282 /*283 * What the XORLOGIN flag _really_ means is that its an ICQ login,284 * which is really stupid and painful, so its not done here.285 *286 */287 if (sess->flags & AIM_SESS_FLAGS_XORLOGIN) {288 return goddamnicq2(sess, conn, sn, password);289 }290 291 292 179 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152))) { 293 180 return -ENOMEM; … … 341 228 md5_append(&state, (const md5_byte_t *) AIM_MD5_STRING, strlen(AIM_MD5_STRING)); 342 229 md5_finish(&state, (md5_byte_t *) digest); 343 344 return 0;345 }346 347 /**348 * aim_encode_password - Encode a password using old XOR method349 * @password: incoming password350 * @encoded: buffer to put encoded password351 *352 * This takes a const pointer to a (null terminated) string353 * containing the unencoded password. It also gets passed354 * an already allocated buffer to store the encoded password.355 * This buffer should be the exact length of the password without356 * the null. The encoded password buffer /is not %NULL terminated/.357 *358 * The encoding_table seems to be a fixed set of values. We'll359 * hope it doesn't change over time!360 *361 * This is only used for the XOR method, not the better MD5 method.362 *363 */364 static int aim_encode_password(const char *password, guint8 *encoded)365 {366 guint8 encoding_table[] = {367 /* v2.1 table, also works for ICQ */368 0xf3, 0x26, 0x81, 0xc4,369 0x39, 0x86, 0xdb, 0x92,370 0x71, 0xa3, 0xb9, 0xe6,371 0x53, 0x7a, 0x95, 0x7c372 };373 int i;374 375 for (i = 0; i < strlen(password); i++) {376 encoded[i] = (password[i] ^ encoding_table[i]);377 }378 230 379 231 return 0;
Note: See TracChangeset
for help on using the changeset viewer.