Mercurial > pidgin
comparison src/protocols/yahoo/yahoo.c @ 10684:72a5babfa8b4
[gaim-migrate @ 12231]
the cipher api that grim has been working on for ages is finally done!! big
congrats and thanks to him!!
lots of modified files in this commit. it builds here.
moved the md5 files to src/protocols/oscar so that it continues to depend
on nothing in gaim. everything else uses the new centralized cipher api.
I'm not sure if src/md5.* needs to be removed or not, so I left it there.
someone let me know or do it directly.
someone check if these need to be added to potfiles.in
and let there be much rejoicing!
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Fri, 11 Mar 2005 13:05:31 +0000 |
parents | 54ac161a876e |
children | b256ce6b85b8 |
comparison
equal
deleted
inserted
replaced
10683:e11f3e1599d4 | 10684:72a5babfa8b4 |
---|---|
24 #include "internal.h" | 24 #include "internal.h" |
25 | 25 |
26 #include "account.h" | 26 #include "account.h" |
27 #include "accountopt.h" | 27 #include "accountopt.h" |
28 #include "blist.h" | 28 #include "blist.h" |
29 #include "cipher.h" | |
29 #include "cmds.h" | 30 #include "cmds.h" |
30 #include "debug.h" | 31 #include "debug.h" |
31 #include "notify.h" | 32 #include "notify.h" |
32 #include "privacy.h" | 33 #include "privacy.h" |
33 #include "prpl.h" | 34 #include "prpl.h" |
35 #include "request.h" | 36 #include "request.h" |
36 #include "server.h" | 37 #include "server.h" |
37 #include "util.h" | 38 #include "util.h" |
38 #include "version.h" | 39 #include "version.h" |
39 | 40 |
40 #include "sha.h" | |
41 #include "yahoo.h" | 41 #include "yahoo.h" |
42 #include "yahoo_packet.h" | 42 #include "yahoo_packet.h" |
43 #include "yahoo_friend.h" | 43 #include "yahoo_friend.h" |
44 #include "yahoochat.h" | 44 #include "yahoochat.h" |
45 #include "ycht.h" | 45 #include "ycht.h" |
46 #include "yahoo_auth.h" | 46 #include "yahoo_auth.h" |
47 #include "yahoo_filexfer.h" | 47 #include "yahoo_filexfer.h" |
48 #include "yahoo_picture.h" | 48 #include "yahoo_picture.h" |
49 #include "md5.h" | |
50 | 49 |
51 extern char *yahoo_crypt(const char *, const char *); | 50 extern char *yahoo_crypt(const char *, const char *); |
52 | 51 |
53 /* #define YAHOO_DEBUG */ | 52 /* #define YAHOO_DEBUG */ |
54 | 53 |
928 * will soon do so in the rest of the world. | 927 * will soon do so in the rest of the world. |
929 * | 928 * |
930 * The new clients use this authentication method. I warn you in advance, it's | 929 * The new clients use this authentication method. I warn you in advance, it's |
931 * bizarre, convoluted, inordinately complicated. It's also no more secure than | 930 * bizarre, convoluted, inordinately complicated. It's also no more secure than |
932 * crypt() was. The only purpose this scheme could serve is to prevent third | 931 * crypt() was. The only purpose this scheme could serve is to prevent third |
933 * part clients from connecting to their servers. | 932 * party clients from connecting to their servers. |
934 * | 933 * |
935 * Sorry, Yahoo. | 934 * Sorry, Yahoo. |
936 */ | 935 */ |
937 | 936 |
938 md5_byte_t result[16]; | 937 GaimCipher *cipher; |
939 md5_state_t ctx; | 938 GaimCipherContext *context; |
939 guint8 digest[16]; | |
940 | 940 |
941 char *crypt_result; | 941 char *crypt_result; |
942 char password_hash[25]; | 942 char password_hash[25]; |
943 char crypt_hash[25]; | 943 char crypt_hash[25]; |
944 char *hash_string_p = g_malloc(50 + strlen(name)); | 944 char *hash_string_p = g_malloc(50 + strlen(name)); |
952 char result96[25]; | 952 char result96[25]; |
953 | 953 |
954 sv = seed[15]; | 954 sv = seed[15]; |
955 sv = sv % 8; | 955 sv = sv % 8; |
956 | 956 |
957 md5_init(&ctx); | 957 cipher = gaim_ciphers_find_cipher("md5"); |
958 md5_append(&ctx, pass, strlen(pass)); | 958 context = gaim_cipher_context_new(cipher, NULL); |
959 md5_finish(&ctx, result); | 959 |
960 to_y64(password_hash, result, 16); | 960 gaim_cipher_context_append(context, pass, strlen(pass)); |
961 | 961 gaim_cipher_context_digest(context, NULL, digest); |
962 md5_init(&ctx); | 962 |
963 to_y64(password_hash, digest, 16); | |
964 | |
963 crypt_result = yahoo_crypt(pass, "$1$_2S43d5f$"); | 965 crypt_result = yahoo_crypt(pass, "$1$_2S43d5f$"); |
964 md5_append(&ctx, crypt_result, strlen(crypt_result)); | 966 |
965 md5_finish(&ctx, result); | 967 gaim_cipher_context_reset(context, NULL); |
966 to_y64(crypt_hash, result, 16); | 968 gaim_cipher_context_append(context, crypt_result, strlen(crypt_result)); |
969 gaim_cipher_context_digest(context, NULL, digest); | |
970 to_y64(crypt_hash, digest, 16); | |
967 | 971 |
968 switch (sv) { | 972 switch (sv) { |
969 case 1: | 973 case 1: |
970 case 6: | 974 case 6: |
971 checksum = seed[seed[9] % 16]; | 975 checksum = seed[seed[9] % 16]; |
1004 g_snprintf(hash_string_c, strlen(name) + 50, | 1008 g_snprintf(hash_string_c, strlen(name) + 50, |
1005 "%c%s%s%s", checksum, crypt_hash, name, seed); | 1009 "%c%s%s%s", checksum, crypt_hash, name, seed); |
1006 break; | 1010 break; |
1007 } | 1011 } |
1008 | 1012 |
1009 md5_init(&ctx); | 1013 gaim_cipher_context_reset(context, NULL); |
1010 md5_append(&ctx, hash_string_p, strlen(hash_string_p)); | 1014 gaim_cipher_context_append(context, hash_string_p, strlen(hash_string_p)); |
1011 md5_finish(&ctx, result); | 1015 gaim_cipher_context_digest(context, NULL, digest); |
1012 to_y64(result6, result, 16); | 1016 to_y64(result6, digest, 16); |
1013 | 1017 |
1014 md5_init(&ctx); | 1018 gaim_cipher_context_reset(context, NULL); |
1015 md5_append(&ctx, hash_string_c, strlen(hash_string_c)); | 1019 gaim_cipher_context_append(context, hash_string_c, strlen(hash_string_c)); |
1016 md5_finish(&ctx, result); | 1020 gaim_cipher_context_digest(context, NULL, digest); |
1017 to_y64(result96, result, 16); | 1021 gaim_cipher_context_destroy(context); |
1022 to_y64(result96, digest, 16); | |
1018 | 1023 |
1019 pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, YAHOO_STATUS_AVAILABLE, 0); | 1024 pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, YAHOO_STATUS_AVAILABLE, 0); |
1020 yahoo_packet_hash(pack, "ssss", 0, name, 6, result6, 96, result96, 1, name); | 1025 yahoo_packet_hash(pack, "ssss", 0, name, 6, result6, 96, result96, 1, name); |
1021 yahoo_packet_send_and_free(pack, yd); | 1026 yahoo_packet_send_and_free(pack, yd); |
1022 | 1027 |
1033 GaimAccount *account = gaim_connection_get_account(gc); | 1038 GaimAccount *account = gaim_connection_get_account(gc); |
1034 const char *name = gaim_normalize(account, gaim_account_get_username(account)); | 1039 const char *name = gaim_normalize(account, gaim_account_get_username(account)); |
1035 const char *pass = gaim_account_get_password(account); | 1040 const char *pass = gaim_account_get_password(account); |
1036 struct yahoo_data *yd = gc->proto_data; | 1041 struct yahoo_data *yd = gc->proto_data; |
1037 | 1042 |
1038 md5_byte_t result[16]; | 1043 GaimCipher *md5_cipher; |
1039 md5_state_t ctx; | 1044 GaimCipherContext *md5_ctx; |
1040 | 1045 guint8 md5_digest[16]; |
1041 SHA_CTX ctx1; | 1046 |
1042 SHA_CTX ctx2; | 1047 GaimCipher *sha1_cipher; |
1048 GaimCipherContext *sha1_ctx1; | |
1049 GaimCipherContext *sha1_ctx2; | |
1043 | 1050 |
1044 char *alphabet1 = "FBZDWAGHrJTLMNOPpRSKUVEXYChImkwQ"; | 1051 char *alphabet1 = "FBZDWAGHrJTLMNOPpRSKUVEXYChImkwQ"; |
1045 char *alphabet2 = "F0E1D2C3B4A59687abcdefghijklmnop"; | 1052 char *alphabet2 = "F0E1D2C3B4A59687abcdefghijklmnop"; |
1046 | 1053 |
1047 char *challenge_lookup = "qzec2tb3um1olpar8whx4dfgijknsvy5"; | 1054 char *challenge_lookup = "qzec2tb3um1olpar8whx4dfgijknsvy5"; |
1086 memset(&magic, 0, 64); | 1093 memset(&magic, 0, 64); |
1087 memset(&resp_6, 0, 100); | 1094 memset(&resp_6, 0, 100); |
1088 memset(&resp_96, 0, 100); | 1095 memset(&resp_96, 0, 100); |
1089 memset(&magic_key_char, 0, 4); | 1096 memset(&magic_key_char, 0, 4); |
1090 memset(&comparison_src, 0, 20); | 1097 memset(&comparison_src, 0, 20); |
1098 | |
1099 md5_cipher = gaim_ciphers_find_cipher("md5"); | |
1100 md5_ctx = gaim_cipher_context_new(md5_cipher, NULL); | |
1101 | |
1102 sha1_cipher = gaim_ciphers_find_cipher("sha1"); | |
1103 sha1_ctx1 = gaim_cipher_context_new(sha1_cipher, NULL); | |
1104 sha1_ctx2 = gaim_cipher_context_new(sha1_cipher, NULL); | |
1091 | 1105 |
1092 /* | 1106 /* |
1093 * Magic: Phase 1. Generate what seems to be a 30 byte value (could change if base64 | 1107 * Magic: Phase 1. Generate what seems to be a 30 byte value (could change if base64 |
1094 * ends up differently? I don't remember and I'm tired, so use a 64 byte buffer. | 1108 * ends up differently? I don't remember and I'm tired, so use a 64 byte buffer. |
1095 */ | 1109 */ |
1206 | 1220 |
1207 comparison_src[x++] = (bl & 0xff00) >> 8; | 1221 comparison_src[x++] = (bl & 0xff00) >> 8; |
1208 comparison_src[x++] = bl & 0xff; | 1222 comparison_src[x++] = bl & 0xff; |
1209 } while (x < 20); | 1223 } while (x < 20); |
1210 | 1224 |
1211 /* First four bytes are magic key. | 1225 /* First four bytes are magic key. */ |
1212 */ | |
1213 | |
1214 memcpy(&magic_key_char[0], comparison_src, 4); | 1226 memcpy(&magic_key_char[0], comparison_src, 4); |
1215 magic_4 = magic_key_char[0] | (magic_key_char[1]<<8) | (magic_key_char[2]<<16) | (magic_key_char[3]<<24); | 1227 magic_4 = magic_key_char[0] | (magic_key_char[1]<<8) | (magic_key_char[2]<<16) | (magic_key_char[3]<<24); |
1216 | 1228 |
1217 /* | 1229 /* |
1218 * Magic: Phase 4. Determine what function to use later by getting outside/inside | 1230 * Magic: Phase 4. Determine what function to use later by getting outside/inside |
1219 * loop values until we match our previous buffer. | 1231 * loop values until we match our previous buffer. |
1220 */ | 1232 */ |
1221 | |
1222 for (x = 0; x < 65535; x++) { | 1233 for (x = 0; x < 65535; x++) { |
1223 int leave = 0; | 1234 int leave = 0; |
1224 | 1235 |
1225 for (y = 0; y < 5; y++) { | 1236 for (y = 0; y < 5; y++) { |
1226 md5_byte_t result[16]; | |
1227 md5_state_t ctx; | |
1228 | |
1229 unsigned char test[3]; | 1237 unsigned char test[3]; |
1230 | 1238 |
1231 memset(&result, 0, 16); | 1239 /* Calculate buffer. */ |
1232 memset(&test, 0, 3); | |
1233 | |
1234 /* Calculate buffer. | |
1235 */ | |
1236 | |
1237 test[0] = x; | 1240 test[0] = x; |
1238 test[1] = x >> 8; | 1241 test[1] = x >> 8; |
1239 test[2] = y; | 1242 test[2] = y; |
1240 | 1243 |
1241 md5_init(&ctx); | 1244 gaim_cipher_context_reset(md5_ctx, NULL); |
1242 md5_append(&ctx, magic_key_char, 4); | 1245 gaim_cipher_context_append(md5_ctx, magic_key_char, 4); |
1243 md5_append(&ctx, test, 3); | 1246 gaim_cipher_context_append(md5_ctx, test, 3); |
1244 md5_finish(&ctx, result); | 1247 gaim_cipher_context_digest(md5_ctx, NULL, md5_digest); |
1245 | 1248 |
1246 if (!memcmp(result, comparison_src+4, 16)) { | 1249 if (!memcmp(md5_digest, comparison_src+4, 16)) { |
1247 leave = 1; | 1250 leave = 1; |
1248 break; | 1251 break; |
1249 } | 1252 } |
1250 } | 1253 } |
1251 | 1254 |
1252 if (leave == 1) | 1255 if (leave == 1) |
1253 break; | 1256 break; |
1254 } | 1257 } |
1255 | 1258 |
1256 /* If y != 0, we need some help. | 1259 /* If y != 0, we need some help. */ |
1257 */ | |
1258 | |
1259 if (y != 0) { | 1260 if (y != 0) { |
1260 unsigned int updated_key; | 1261 unsigned int updated_key; |
1261 | 1262 |
1262 /* Update magic stuff. Call it twice because Yahoo's encryption is super bad ass. | 1263 /* Update magic stuff. |
1264 * Call it twice because Yahoo's encryption is super bad ass. | |
1263 */ | 1265 */ |
1264 | |
1265 updated_key = yahoo_auth_finalCountdown(magic_4, 0x60, y, x); | 1266 updated_key = yahoo_auth_finalCountdown(magic_4, 0x60, y, x); |
1266 updated_key = yahoo_auth_finalCountdown(updated_key, 0x60, y, x); | 1267 updated_key = yahoo_auth_finalCountdown(updated_key, 0x60, y, x); |
1267 | 1268 |
1268 magic_key_char[0] = updated_key & 0xff; | 1269 magic_key_char[0] = updated_key & 0xff; |
1269 magic_key_char[1] = (updated_key >> 8) & 0xff; | 1270 magic_key_char[1] = (updated_key >> 8) & 0xff; |
1270 magic_key_char[2] = (updated_key >> 16) & 0xff; | 1271 magic_key_char[2] = (updated_key >> 16) & 0xff; |
1271 magic_key_char[3] = (updated_key >> 24) & 0xff; | 1272 magic_key_char[3] = (updated_key >> 24) & 0xff; |
1272 } | 1273 } |
1273 | 1274 |
1274 /* Get password and crypt hashes as per usual. | 1275 /* Get password and crypt hashes as per usual. */ |
1275 */ | 1276 gaim_cipher_context_reset(md5_ctx, NULL); |
1276 | 1277 gaim_cipher_context_append(md5_ctx, pass, strlen(pass)); |
1277 md5_init(&ctx); | 1278 gaim_cipher_context_digest(md5_ctx, NULL, md5_digest); |
1278 md5_append(&ctx, pass, strlen(pass)); | 1279 to_y64(password_hash, md5_digest, 16); |
1279 md5_finish(&ctx, result); | 1280 |
1280 to_y64(password_hash, result, 16); | |
1281 | |
1282 md5_init(&ctx); | |
1283 crypt_result = yahoo_crypt(pass, "$1$_2S43d5f$"); | 1281 crypt_result = yahoo_crypt(pass, "$1$_2S43d5f$"); |
1284 md5_append(&ctx, crypt_result, strlen(crypt_result)); | 1282 gaim_cipher_context_reset(md5_ctx, NULL); |
1285 md5_finish(&ctx, result); | 1283 gaim_cipher_context_append(md5_ctx, crypt_result, strlen(crypt_result)); |
1286 to_y64(crypt_hash, result, 16); | 1284 gaim_cipher_context_digest(md5_ctx, NULL, md5_digest); |
1287 | 1285 to_y64(crypt_hash, md5_digest, 16); |
1288 /* Our first authentication response is based off of the password hash. | 1286 |
1289 */ | 1287 /* Our first authentication response is based off of the password hash. */ |
1290 | |
1291 for (x = 0; x < (int)strlen(password_hash); x++) | 1288 for (x = 0; x < (int)strlen(password_hash); x++) |
1292 pass_hash_xor1[cnt++] = password_hash[x] ^ 0x36; | 1289 pass_hash_xor1[cnt++] = password_hash[x] ^ 0x36; |
1293 | 1290 |
1294 if (cnt < 64) | 1291 if (cnt < 64) |
1295 memset(&(pass_hash_xor1[cnt]), 0x36, 64-cnt); | 1292 memset(&(pass_hash_xor1[cnt]), 0x36, 64-cnt); |
1300 pass_hash_xor2[cnt++] = password_hash[x] ^ 0x5c; | 1297 pass_hash_xor2[cnt++] = password_hash[x] ^ 0x5c; |
1301 | 1298 |
1302 if (cnt < 64) | 1299 if (cnt < 64) |
1303 memset(&(pass_hash_xor2[cnt]), 0x5c, 64-cnt); | 1300 memset(&(pass_hash_xor2[cnt]), 0x5c, 64-cnt); |
1304 | 1301 |
1305 shaInit(&ctx1); | |
1306 shaInit(&ctx2); | |
1307 | |
1308 /* | 1302 /* |
1309 * The first context gets the password hash XORed with 0x36 plus a magic value | 1303 * The first context gets the password hash XORed with 0x36 plus a magic value |
1310 * which we previously extrapolated from our challenge. | 1304 * which we previously extrapolated from our challenge. |
1311 */ | 1305 */ |
1312 | 1306 |
1313 shaUpdate(&ctx1, pass_hash_xor1, 64); | 1307 gaim_cipher_context_append(sha1_ctx1, pass_hash_xor1, 64); |
1314 if (y >= 3) | 1308 if (y >= 3) |
1315 ctx1.sizeLo = 0x1ff; | 1309 gaim_cipher_context_set_option(sha1_ctx1, "sizeLo", GINT_TO_POINTER(0x1ff)); |
1316 shaUpdate(&ctx1, magic_key_char, 4); | 1310 gaim_cipher_context_append(sha1_ctx1, magic_key_char, 4); |
1317 shaFinal(&ctx1, digest1); | 1311 gaim_cipher_context_digest(sha1_ctx1, NULL, digest1); |
1318 | 1312 |
1319 /* | 1313 /* |
1320 * The second context gets the password hash XORed with 0x5c plus the SHA-1 digest | 1314 * The second context gets the password hash XORed with 0x5c plus the SHA-1 digest |
1321 * of the first context. | 1315 * of the first context. |
1322 */ | 1316 */ |
1323 | 1317 |
1324 shaUpdate(&ctx2, pass_hash_xor2, 64); | 1318 gaim_cipher_context_append(sha1_ctx2, pass_hash_xor2, 64); |
1325 shaUpdate(&ctx2, digest1, 20); | 1319 gaim_cipher_context_append(sha1_ctx2, digest1, 20); |
1326 shaFinal(&ctx2, digest2); | 1320 gaim_cipher_context_digest(sha1_ctx2, NULL, digest2); |
1327 | 1321 |
1328 /* | 1322 /* |
1329 * Now that we have digest2, use it to fetch characters from an alphabet to construct | 1323 * Now that we have digest2, use it to fetch characters from an alphabet to construct |
1330 * our first authentication response. | 1324 * our first authentication response. |
1331 */ | 1325 */ |
1393 crypt_hash_xor2[cnt++] = crypt_hash[x] ^ 0x5c; | 1387 crypt_hash_xor2[cnt++] = crypt_hash[x] ^ 0x5c; |
1394 | 1388 |
1395 if (cnt < 64) | 1389 if (cnt < 64) |
1396 memset(&(crypt_hash_xor2[cnt]), 0x5c, 64-cnt); | 1390 memset(&(crypt_hash_xor2[cnt]), 0x5c, 64-cnt); |
1397 | 1391 |
1398 shaInit(&ctx1); | 1392 gaim_cipher_context_reset(sha1_ctx1, NULL); |
1399 shaInit(&ctx2); | 1393 gaim_cipher_context_reset(sha1_ctx2, NULL); |
1400 | 1394 |
1401 /* | 1395 /* |
1402 * The first context gets the password hash XORed with 0x36 plus a magic value | 1396 * The first context gets the password hash XORed with 0x36 plus a magic value |
1403 * which we previously extrapolated from our challenge. | 1397 * which we previously extrapolated from our challenge. |
1404 */ | 1398 */ |
1405 | 1399 |
1406 shaUpdate(&ctx1, crypt_hash_xor1, 64); | 1400 gaim_cipher_context_append(sha1_ctx1, crypt_hash_xor1, 64); |
1407 if (y >= 3) | 1401 if (y >= 3) |
1408 ctx1.sizeLo = 0x1ff; | 1402 gaim_cipher_context_set_option(sha1_ctx1, "sizeLo", GINT_TO_POINTER(0x1ff)); |
1409 shaUpdate(&ctx1, magic_key_char, 4); | 1403 gaim_cipher_context_append(sha1_ctx1, magic_key_char, 4); |
1410 shaFinal(&ctx1, digest1); | 1404 gaim_cipher_context_digest(sha1_ctx1, NULL, digest1); |
1411 | 1405 |
1412 /* | 1406 /* |
1413 * The second context gets the password hash XORed with 0x5c plus the SHA-1 digest | 1407 * The second context gets the password hash XORed with 0x5c plus the SHA-1 digest |
1414 * of the first context. | 1408 * of the first context. |
1415 */ | 1409 */ |
1416 | 1410 |
1417 shaUpdate(&ctx2, crypt_hash_xor2, 64); | 1411 gaim_cipher_context_append(sha1_ctx2, crypt_hash_xor2, 64); |
1418 shaUpdate(&ctx2, digest1, 20); | 1412 gaim_cipher_context_append(sha1_ctx2, digest1, 20); |
1419 shaFinal(&ctx2, digest2); | 1413 gaim_cipher_context_digest(sha1_ctx2, NULL, digest2); |
1420 | 1414 |
1421 /* | 1415 /* |
1422 * Now that we have digest2, use it to fetch characters from an alphabet to construct | 1416 * Now that we have digest2, use it to fetch characters from an alphabet to construct |
1423 * our first authentication response. | 1417 * our first authentication response. |
1424 */ | 1418 */ |
1473 if (yd->picture_checksum) | 1467 if (yd->picture_checksum) |
1474 yahoo_packet_hash_int(pack, 192, yd->picture_checksum); | 1468 yahoo_packet_hash_int(pack, 192, yd->picture_checksum); |
1475 | 1469 |
1476 yahoo_packet_send_and_free(pack, yd); | 1470 yahoo_packet_send_and_free(pack, yd); |
1477 | 1471 |
1472 gaim_cipher_context_destroy(md5_ctx); | |
1473 gaim_cipher_context_destroy(sha1_ctx1); | |
1474 gaim_cipher_context_destroy(sha1_ctx2); | |
1475 | |
1478 g_free(password_hash); | 1476 g_free(password_hash); |
1479 g_free(crypt_hash); | 1477 g_free(crypt_hash); |
1480 } | 1478 } |
1481 | 1479 |
1482 static void yahoo_process_auth(GaimConnection *gc, struct yahoo_packet *pkt) | 1480 static void yahoo_process_auth(GaimConnection *gc, struct yahoo_packet *pkt) |
2172 const char *pass = gaim_account_get_password(account); | 2170 const char *pass = gaim_account_get_password(account); |
2173 GHashTable *hash = yahoo_login_page_hash(buf, len); | 2171 GHashTable *hash = yahoo_login_page_hash(buf, len); |
2174 GString *url = g_string_new("GET http://login.yahoo.com/config/login?login="); | 2172 GString *url = g_string_new("GET http://login.yahoo.com/config/login?login="); |
2175 char md5[33], *hashp = md5, *chal; | 2173 char md5[33], *hashp = md5, *chal; |
2176 int i; | 2174 int i; |
2177 md5_byte_t result[16]; | 2175 GaimCipher *cipher; |
2178 md5_state_t ctx; | 2176 GaimCipherContext *context; |
2177 guint8 digest[16]; | |
2179 | 2178 |
2180 url = g_string_append(url, sn); | 2179 url = g_string_append(url, sn); |
2181 url = g_string_append(url, "&passwd="); | 2180 url = g_string_append(url, "&passwd="); |
2182 | 2181 |
2183 md5_init(&ctx); | 2182 cipher = gaim_ciphers_find_cipher("md5"); |
2184 md5_append(&ctx, pass, strlen(pass)); | 2183 context = gaim_cipher_context_new(cipher, NULL); |
2185 md5_finish(&ctx, result); | 2184 |
2185 gaim_cipher_context_append(context, pass, strlen(pass)); | |
2186 gaim_cipher_context_digest(context, NULL, digest); | |
2186 for (i = 0; i < 16; ++i) { | 2187 for (i = 0; i < 16; ++i) { |
2187 g_snprintf(hashp, 3, "%02x", result[i]); | 2188 g_snprintf(hashp, 3, "%02x", digest[i]); |
2188 hashp += 2; | 2189 hashp += 2; |
2189 } | 2190 } |
2191 | |
2190 chal = g_strconcat(md5, g_hash_table_lookup(hash, ".challenge"), NULL); | 2192 chal = g_strconcat(md5, g_hash_table_lookup(hash, ".challenge"), NULL); |
2191 md5_init(&ctx); | 2193 gaim_cipher_context_reset(context, NULL); |
2192 md5_append(&ctx, chal, strlen(chal)); | 2194 gaim_cipher_context_append(context, chal, strlen(chal)); |
2193 md5_finish(&ctx, result); | 2195 gaim_cipher_context_digest(context, NULL, digest); |
2194 hashp = md5; | 2196 hashp = md5; |
2195 for (i = 0; i < 16; ++i) { | 2197 for (i = 0; i < 16; ++i) { |
2196 g_snprintf(hashp, 3, "%02x", result[i]); | 2198 g_snprintf(hashp, 3, "%02x", digest[i]); |
2197 hashp += 2; | 2199 hashp += 2; |
2198 } | 2200 } |
2199 /* | 2201 /* |
2200 md5_init(&ctx); | 2202 * I dunno why this is here and commented out.. but in case it's needed |
2201 md5_append(&ctx, md5, strlen(md5)); | 2203 * I updated it.. |
2202 md5_finish(&ctx, result); | 2204 |
2205 gaim_cipher_context_reset(context, NULL); | |
2206 gaim_cipher_context_append(context, md5, strlen(md5)); | |
2207 gaim_cipher_context_digest(context, NULL, digest); | |
2203 hashp = md5; | 2208 hashp = md5; |
2204 for (i = 0; i < 16; ++i) { | 2209 for (i = 0; i < 16; ++i) { |
2205 g_snprintf(hashp, 3, "%02x", result[i]); | 2210 g_snprintf(hashp, 3, "%02x", digest[i]); |
2206 hashp += 2; | 2211 hashp += 2; |
2207 } | 2212 } |
2208 */ | 2213 */ |
2209 g_free(chal); | 2214 g_free(chal); |
2210 | 2215 |
2217 yd->auth = g_string_free(url, FALSE); | 2222 yd->auth = g_string_free(url, FALSE); |
2218 if (gaim_proxy_connect(account, "login.yahoo.com", 80, yahoo_got_cookies, gc) != 0) { | 2223 if (gaim_proxy_connect(account, "login.yahoo.com", 80, yahoo_got_cookies, gc) != 0) { |
2219 gaim_connection_error(gc, _("Connection problem")); | 2224 gaim_connection_error(gc, _("Connection problem")); |
2220 return; | 2225 return; |
2221 } | 2226 } |
2227 | |
2228 gaim_cipher_context_destroy(context); | |
2222 } | 2229 } |
2223 | 2230 |
2224 static void yahoo_server_check(GaimAccount *account) | 2231 static void yahoo_server_check(GaimAccount *account) |
2225 { | 2232 { |
2226 const char *server; | 2233 const char *server; |