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;