Changeset 85d7b85 for protocols/yahoo/libyahoo2.c
- Timestamp:
- 2008-04-02T14:22:57Z (16 years ago)
- Branches:
- master
- Children:
- f9dbc99
- Parents:
- 875ad42 (diff), dd34575 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/yahoo/libyahoo2.c
r875ad42 r85d7b85 74 74 #include <ctype.h> 75 75 76 #include "sha .h"76 #include "sha1.h" 77 77 #include "md5.h" 78 78 #include "yahoo2.h" … … 88 88 #endif 89 89 90 #include "base64.h" 91 90 92 #ifdef USE_STRUCT_CALLBACKS 91 93 struct yahoo_callbacks *yc=NULL; … … 100 102 #define YAHOO_CALLBACK(x) x 101 103 #endif 104 105 static int yahoo_send_data(int fd, void *data, int len); 102 106 103 107 int yahoo_log_message(char * fmt, ...) … … 200 204 YAHOO_SERVICE_CHATLOGOUT = 0xa0, 201 205 YAHOO_SERVICE_CHATPING, 202 YAHOO_SERVICE_COMMENT = 0xa8 206 YAHOO_SERVICE_COMMENT = 0xa8, 207 YAHOO_SERVICE_STEALTH = 0xb9, 208 YAHOO_SERVICE_PICTURE_CHECKSUM = 0xbd, 209 YAHOO_SERVICE_PICTURE = 0xbe, 210 YAHOO_SERVICE_PICTURE_UPDATE = 0xc1, 211 YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2 203 212 }; 204 213 … … 693 702 } 694 703 695 static char base64digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 696 "abcdefghijklmnopqrstuvwxyz" 697 "0123456789._"; 704 /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */ 698 705 static void to_y64(unsigned char *out, const unsigned char *in, int inlen) 699 /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */ 700 { 701 for (; inlen >= 3; inlen -= 3) 702 { 703 *out++ = base64digits[in[0] >> 2]; 704 *out++ = base64digits[((in[0]<<4) & 0x30) | (in[1]>>4)]; 705 *out++ = base64digits[((in[1]<<2) & 0x3c) | (in[2]>>6)]; 706 *out++ = base64digits[in[2] & 0x3f]; 707 in += 3; 708 } 709 if (inlen > 0) 710 { 711 unsigned char fragment; 712 713 *out++ = base64digits[in[0] >> 2]; 714 fragment = (in[0] << 4) & 0x30; 715 if (inlen > 1) 716 fragment |= in[1] >> 4; 717 *out++ = base64digits[fragment]; 718 *out++ = (inlen < 2) ? '-' 719 : base64digits[(in[1] << 2) & 0x3c]; 720 *out++ = '-'; 721 } 722 *out = '\0'; 706 { 707 base64_encode_real(in, inlen, out, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-"); 723 708 } 724 709 … … 750 735 751 736 memcpy(data + pos, "YMSG", 4); pos += 4; 752 pos += yahoo_put16(data + pos, 0x0 a00);737 pos += yahoo_put16(data + pos, 0x000c); 753 738 pos += yahoo_put16(data + pos, 0x0000); 754 739 pos += yahoo_put16(data + pos, pktlen + extra_pad); … … 761 746 yahoo_packet_dump(data, len); 762 747 748 if( yid->type == YAHOO_CONNECTION_FT ) 749 yahoo_send_data(yid->fd, data, len); 750 else 763 751 yahoo_add_to_send_queue(yid, data, len); 764 752 FREE(data); … … 946 934 char *msg = NULL; 947 935 char *from = NULL; 936 char *to = NULL; 948 937 int stat = 0; 949 938 int accept = 0; … … 954 943 if (pair->key == 4) 955 944 from = pair->value; 945 if (pair->key == 5) 946 to = pair->value; 956 947 if (pair->key == 49) 957 948 msg = pair->value; … … 971 962 972 963 if (!strncasecmp(msg, "TYPING", strlen("TYPING"))) 973 YAHOO_CALLBACK(ext_yahoo_typing_notify)(yd->client_id, from, stat);964 YAHOO_CALLBACK(ext_yahoo_typing_notify)(yd->client_id, to, from, stat); 974 965 else if (!strncasecmp(msg, "GAME", strlen("GAME"))) 975 YAHOO_CALLBACK(ext_yahoo_game_notify)(yd->client_id, from, stat);966 YAHOO_CALLBACK(ext_yahoo_game_notify)(yd->client_id, to, from, stat); 976 967 else if (!strncasecmp(msg, "WEBCAMINVITE", strlen("WEBCAMINVITE"))) 977 968 { 978 969 if (!strcmp(ind, " ")) { 979 YAHOO_CALLBACK(ext_yahoo_webcam_invite)(yd->client_id, from);970 YAHOO_CALLBACK(ext_yahoo_webcam_invite)(yd->client_id, to, from); 980 971 } else { 981 972 accept = atoi(ind); … … 983 974 if (accept < 0) 984 975 accept = 0; 985 YAHOO_CALLBACK(ext_yahoo_webcam_invite_reply)(yd->client_id, from, accept);976 YAHOO_CALLBACK(ext_yahoo_webcam_invite_reply)(yd->client_id, to, from, accept); 986 977 } 987 978 } … … 1042 1033 } 1043 1034 if(url && from) 1044 YAHOO_CALLBACK(ext_yahoo_got_file)(yd->client_id, from, url, expires, msg, filename, filesize);1035 YAHOO_CALLBACK(ext_yahoo_got_file)(yd->client_id, to, from, url, expires, msg, filename, filesize); 1045 1036 1046 1037 } … … 1116 1107 ; 1117 1108 else if(members) 1118 YAHOO_CALLBACK(ext_yahoo_got_conf_invite)(yd->client_id, host, room, msg, members);1109 YAHOO_CALLBACK(ext_yahoo_got_conf_invite)(yd->client_id, id, host, room, msg, members); 1119 1110 else if(msg) 1120 YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, msg, 0 );1111 YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, msg, 0, E_CONFNOTAVAIL); 1121 1112 break; 1122 1113 case YAHOO_SERVICE_CONFADDINVITE: … … 1124 1115 ; 1125 1116 else 1126 YAHOO_CALLBACK(ext_yahoo_got_conf_invite)(yd->client_id, host, room, msg, members);1117 YAHOO_CALLBACK(ext_yahoo_got_conf_invite)(yd->client_id, id, host, room, msg, members); 1127 1118 break; 1128 1119 case YAHOO_SERVICE_CONFDECLINE: 1129 1120 if(who) 1130 YAHOO_CALLBACK(ext_yahoo_conf_userdecline)(yd->client_id, who, room, msg);1121 YAHOO_CALLBACK(ext_yahoo_conf_userdecline)(yd->client_id, id, who, room, msg); 1131 1122 break; 1132 1123 case YAHOO_SERVICE_CONFLOGON: 1133 1124 if(who) 1134 YAHOO_CALLBACK(ext_yahoo_conf_userjoin)(yd->client_id, who, room);1125 YAHOO_CALLBACK(ext_yahoo_conf_userjoin)(yd->client_id, id, who, room); 1135 1126 break; 1136 1127 case YAHOO_SERVICE_CONFLOGOFF: 1137 1128 if(who) 1138 YAHOO_CALLBACK(ext_yahoo_conf_userleave)(yd->client_id, who, room);1129 YAHOO_CALLBACK(ext_yahoo_conf_userleave)(yd->client_id, id, who, room); 1139 1130 break; 1140 1131 case YAHOO_SERVICE_CONFMSG: 1141 1132 if(who) 1142 YAHOO_CALLBACK(ext_yahoo_conf_message)(yd->client_id, who, room, msg, utf8);1133 YAHOO_CALLBACK(ext_yahoo_conf_message)(yd->client_id, id, who, room, msg, utf8); 1143 1134 break; 1144 1135 } … … 1148 1139 { 1149 1140 char *msg = NULL; 1141 char *id = NULL; 1150 1142 char *who = NULL; 1151 1143 char *room = NULL; … … 1164 1156 struct yahoo_pair *pair = l->data; 1165 1157 1158 if (pair->key == 1) { 1159 /* My identity */ 1160 id = pair->value; 1161 } 1162 1166 1163 if (pair->key == 104) { 1167 1164 /* Room name */ … … 1238 1235 if(!room) { 1239 1236 if (pkt->service == YAHOO_SERVICE_CHATLOGOUT) { /* yahoo originated chat logout */ 1240 YAHOO_CALLBACK(ext_yahoo_chat_yahoologout)(yid->yd->client_id );1237 YAHOO_CALLBACK(ext_yahoo_chat_yahoologout)(yid->yd->client_id, id); 1241 1238 return ; 1242 1239 } 1243 1240 if (pkt->service == YAHOO_SERVICE_COMMENT && chaterr) { 1244 YAHOO_CALLBACK(ext_yahoo_chat_yahooerror)(yid->yd->client_id );1245 return 1241 YAHOO_CALLBACK(ext_yahoo_chat_yahooerror)(yid->yd->client_id, id); 1242 return; 1246 1243 } 1247 1244 … … 1256 1253 } 1257 1254 if(firstjoin && members) { 1258 YAHOO_CALLBACK(ext_yahoo_chat_join)(yid->yd->client_id, room, topic, members, yid->fd);1255 YAHOO_CALLBACK(ext_yahoo_chat_join)(yid->yd->client_id, id, room, topic, members, yid->fd); 1259 1256 } else if(who) { 1260 1257 if(y_list_length(members) != 1) { … … 1265 1262 YList *n = members->next; 1266 1263 currentmember = members->data; 1267 YAHOO_CALLBACK(ext_yahoo_chat_userjoin)(yid->yd->client_id, room, currentmember);1264 YAHOO_CALLBACK(ext_yahoo_chat_userjoin)(yid->yd->client_id, id, room, currentmember); 1268 1265 y_list_free_1(members); 1269 1266 members=n; … … 1273 1270 case YAHOO_SERVICE_CHATEXIT: 1274 1271 if(who) { 1275 YAHOO_CALLBACK(ext_yahoo_chat_userleave)(yid->yd->client_id, room, who);1272 YAHOO_CALLBACK(ext_yahoo_chat_userleave)(yid->yd->client_id, id, room, who); 1276 1273 } 1277 1274 break; 1278 1275 case YAHOO_SERVICE_COMMENT: 1279 1276 if(who) { 1280 YAHOO_CALLBACK(ext_yahoo_chat_message)(yid->yd->client_id, who, room, msg, msgtype, utf8);1277 YAHOO_CALLBACK(ext_yahoo_chat_message)(yid->yd->client_id, id, who, room, msg, msgtype, utf8); 1281 1278 } 1282 1279 break; … … 1337 1334 YAHOO_CALLBACK(ext_yahoo_system_message)(yd->client_id, message->msg); 1338 1335 } else if (pkt->status <= 2 || pkt->status == 5) { 1339 YAHOO_CALLBACK(ext_yahoo_got_im)(yd->client_id, message-> from, message->msg, message->tm, pkt->status, message->utf8);1336 YAHOO_CALLBACK(ext_yahoo_got_im)(yd->client_id, message->to, message->from, message->msg, message->tm, pkt->status, message->utf8); 1340 1337 } else if (pkt->status == 0xffffffff) { 1341 YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, message->msg, 0 );1338 YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, message->msg, 0, E_SYSTEM); 1342 1339 } 1343 1340 free(message); … … 1352 1349 YList *l; 1353 1350 struct yahoo_data *yd = yid->yd; 1354 char *name = NULL; 1355 int state = 0; 1356 int away = 0; 1357 int idle = 0; 1358 char *msg = NULL; 1351 1352 struct user 1353 { 1354 char *name; /* 7 name */ 1355 int state; /* 10 state */ 1356 int flags; /* 13 flags, bit 0 = pager, bit 1 = chat, bit 2 = game */ 1357 int mobile; /* 60 mobile */ 1358 char *msg; /* 19 custom status message */ 1359 int away; /* 47 away (or invisible)*/ 1360 int buddy_session; /* 11 state */ 1361 int f17; /* 17 in chat? then what about flags? */ 1362 int idle; /* 137 seconds idle */ 1363 int f138; /* 138 state */ 1364 char *f184; /* 184 state */ 1365 int f192; /* 192 state */ 1366 int f10001; /* 10001 state */ 1367 int f10002; /* 10002 state */ 1368 int f198; /* 198 state */ 1369 char *f197; /* 197 state */ 1370 char *f205; /* 205 state */ 1371 int f213; /* 213 state */ 1372 } *u; 1373 1374 YList *users = 0; 1359 1375 1360 if (pkt->service == YAHOO_SERVICE_LOGOFF && pkt->status == -1) {1376 if (pkt->service == YAHOO_SERVICE_LOGOFF && pkt->status == -1) { 1361 1377 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_DUPL, NULL); 1362 1378 return; … … 1382 1398 break; 1383 1399 case 7: /* the current buddy */ 1384 name = pair->value; 1400 u = y_new0(struct user, 1); 1401 u->name = pair->value; 1402 users = y_list_prepend(users, u); 1385 1403 break; 1386 1404 case 10: /* state */ 1387 state = strtol(pair->value, NULL, 10);1405 ((struct user*)users->data)->state = strtol(pair->value, NULL, 10); 1388 1406 break; 1389 1407 case 19: /* custom status message */ 1390 msg = pair->value;1408 ((struct user*)users->data)->msg = pair->value; 1391 1409 break; 1392 1410 case 47: /* is it an away message or not */ 1393 away = atoi(pair->value);1411 ((struct user*)users->data)->away = atoi(pair->value); 1394 1412 break; 1395 1413 case 137: /* seconds idle */ 1396 idle = atoi(pair->value);1397 break; 1398 case 11: /* what is this?*/1399 NOTICE(("key %d:%s", pair->key, pair->value));1414 ((struct user*)users->data)->idle = atoi(pair->value); 1415 break; 1416 case 11: /* this is the buddy's session id */ 1417 ((struct user*)users->data)->buddy_session = atoi(pair->value); 1400 1418 break; 1401 1419 case 17: /* in chat? */ 1402 break; 1403 case 13: /* in pager? */ 1404 if (pkt->service == YAHOO_SERVICE_LOGOFF || strtol(pair->value, NULL, 10) == 0) { 1405 YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, name, YAHOO_STATUS_OFFLINE, NULL, 1); 1406 break; 1407 } 1408 if (state == YAHOO_STATUS_AVAILABLE) { 1409 YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, name, state, NULL, 0); 1410 } else if (state == YAHOO_STATUS_CUSTOM) { 1411 YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, name, state, msg, away); 1412 } else { 1413 YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, name, state, NULL, idle); 1414 } 1415 1416 break; 1417 case 60: 1420 ((struct user*)users->data)->f17 = atoi(pair->value); 1421 break; 1422 case 13: /* bitmask, bit 0 = pager, bit 1 = chat, bit 2 = game */ 1423 ((struct user*)users->data)->flags = atoi(pair->value); 1424 break; 1425 case 60: /* SMS -> 1 MOBILE USER */ 1418 1426 /* sometimes going offline makes this 2, but invisible never sends it */ 1419 NOTICE(("key %d:%s", pair->key, pair->value)); 1420 break; 1427 ((struct user*)users->data)->mobile = atoi(pair->value); 1428 break; 1429 case 138: 1430 ((struct user*)users->data)->f138 = atoi(pair->value); 1431 break; 1432 case 184: 1433 ((struct user*)users->data)->f184 = pair->value; 1434 break; 1435 case 192: 1436 ((struct user*)users->data)->f192 = atoi(pair->value); 1437 break; 1438 case 10001: 1439 ((struct user*)users->data)->f10001 = atoi(pair->value); 1440 break; 1441 case 10002: 1442 ((struct user*)users->data)->f10002 = atoi(pair->value); 1443 break; 1444 case 198: 1445 ((struct user*)users->data)->f198 = atoi(pair->value); 1446 break; 1447 case 197: 1448 ((struct user*)users->data)->f197 = pair->value; 1449 break; 1450 case 205: 1451 ((struct user*)users->data)->f205 = pair->value; 1452 break; 1453 case 213: 1454 ((struct user*)users->data)->f213 = atoi(pair->value); 1455 break; 1421 1456 case 16: /* Custom error message */ 1422 YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, pair->value, 0 );1457 YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, pair->value, 0, E_CUSTOM); 1423 1458 break; 1424 1459 default: … … 1426 1461 break; 1427 1462 } 1463 } 1464 1465 while (users) { 1466 YList *t = users; 1467 struct user *u = users->data; 1468 1469 if (u->name != NULL) { 1470 if (pkt->service == YAHOO_SERVICE_LOGOFF || u->flags == 0) { 1471 YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, u->name, YAHOO_STATUS_OFFLINE, NULL, 1, 0, 0); 1472 } else { 1473 YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, u->name, u->state, u->msg, u->away, u->idle, u->mobile); 1474 } 1475 } 1476 1477 users = y_list_remove_link(users, users); 1478 y_list_free_1(t); 1479 FREE(u); 1428 1480 } 1429 1481 } … … 1530 1582 yahoo_packet_free(pkt); 1531 1583 1584 } 1585 1586 static void yahoo_process_picture_checksum( struct yahoo_input_data *yid, struct yahoo_packet *pkt) 1587 { 1588 struct yahoo_data *yd = yid->yd; 1589 char *from = NULL; 1590 char *to = NULL; 1591 int checksum = 0; 1592 YList *l; 1593 1594 for(l = pkt->hash; l; l = l->next) 1595 { 1596 struct yahoo_pair *pair = l->data; 1597 1598 switch(pair->key) 1599 { 1600 case 1: 1601 case 4: 1602 from = pair->value; 1603 case 5: 1604 to = pair->value; 1605 break; 1606 case 212: 1607 break; 1608 case 192: 1609 checksum = atoi( pair->value ); 1610 break; 1611 } 1612 } 1613 1614 YAHOO_CALLBACK(ext_yahoo_got_buddyicon_checksum)(yd->client_id,to,from,checksum); 1615 } 1616 1617 static void yahoo_process_picture(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 1618 { 1619 struct yahoo_data *yd = yid->yd; 1620 char *url = NULL; 1621 char *from = NULL; 1622 char *to = NULL; 1623 int status = 0; 1624 int checksum = 0; 1625 YList *l; 1626 1627 for(l = pkt->hash; l; l = l->next) 1628 { 1629 struct yahoo_pair *pair = l->data; 1630 1631 switch(pair->key) 1632 { 1633 case 1: 1634 case 4: /* sender */ 1635 from = pair->value; 1636 break; 1637 case 5: /* we */ 1638 to = pair->value; 1639 break; 1640 case 13: /* request / sending */ 1641 status = atoi( pair->value ); 1642 break; 1643 case 20: /* url */ 1644 url = pair->value; 1645 break; 1646 case 192: /*checksum */ 1647 checksum = atoi( pair->value ); 1648 break; 1649 } 1650 } 1651 1652 switch( status ) 1653 { 1654 case 1: /* this is a request, ignore for now */ 1655 YAHOO_CALLBACK(ext_yahoo_got_buddyicon_request)(yd->client_id, to, from); 1656 break; 1657 case 2: /* this is cool - we get a picture :) */ 1658 YAHOO_CALLBACK(ext_yahoo_got_buddyicon)(yd->client_id,to, from, url, checksum); 1659 break; 1660 } 1661 } 1662 1663 static void yahoo_process_picture_upload(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 1664 { 1665 struct yahoo_data *yd = yid->yd; 1666 YList *l; 1667 char *url = NULL; 1668 1669 if ( pkt->status != 1 ) 1670 return; /* something went wrong */ 1671 1672 for(l = pkt->hash; l; l = l->next) 1673 { 1674 struct yahoo_pair *pair = l->data; 1675 1676 switch(pair->key) 1677 { 1678 case 5: /* we */ 1679 break; 1680 case 20: /* url */ 1681 url = pair->value; 1682 break; 1683 case 27: /* local filename */ 1684 break; 1685 case 38: /* time */ 1686 break; 1687 } 1688 } 1689 1690 YAHOO_CALLBACK(ext_yahoo_buddyicon_uploaded)(yd->client_id, url); 1532 1691 } 1533 1692 … … 1659 1818 md5_state_t ctx; 1660 1819 1661 SHA_CTXctx1;1662 SHA_CTXctx2;1820 sha1_state_t ctx1; 1821 sha1_state_t ctx2; 1663 1822 1664 1823 char *alphabet1 = "FBZDWAGHrJTLMNOPpRSKUVEXYChImkwQ"; … … 1716 1875 magic_ptr = (unsigned char *)seed; 1717 1876 1718 while (*magic_ptr != (int)NULL) {1877 while (*magic_ptr != 0) { 1719 1878 char *loc; 1720 1879 … … 1895 2054 memset(&(pass_hash_xor2[cnt]), 0x5c, 64-cnt); 1896 2055 1897 sha Init(&ctx1);1898 sha Init(&ctx2);2056 sha1_init(&ctx1); 2057 sha1_init(&ctx2); 1899 2058 1900 2059 /* The first context gets the password hash XORed … … 1903 2062 * challenge. */ 1904 2063 1905 sha Update(&ctx1, pass_hash_xor1, 64);2064 sha1_append(&ctx1, pass_hash_xor1, 64); 1906 2065 if (j >= 3 ) 1907 ctx1. sizeLo= 0x1ff;1908 sha Update(&ctx1, magic_key_char, 4);1909 sha Final(&ctx1, digest1);2066 ctx1.Length_Low = 0x1ff; 2067 sha1_append(&ctx1, magic_key_char, 4); 2068 sha1_finish(&ctx1, digest1); 1910 2069 1911 2070 /* The second context gets the password hash XORed … … 1913 2072 * of the first context. */ 1914 2073 1915 sha Update(&ctx2, pass_hash_xor2, 64);1916 sha Update(&ctx2, digest1, 20);1917 sha Final(&ctx2, digest2);2074 sha1_append(&ctx2, pass_hash_xor2, 64); 2075 sha1_append(&ctx2, digest1, 20); 2076 sha1_finish(&ctx2, digest2); 1918 2077 1919 2078 /* Now that we have digest2, use it to fetch … … 1986 2145 memset(&(crypt_hash_xor2[cnt]), 0x5c, 64-cnt); 1987 2146 1988 sha Init(&ctx1);1989 sha Init(&ctx2);2147 sha1_init(&ctx1); 2148 sha1_init(&ctx2); 1990 2149 1991 2150 /* The first context gets the password hash XORed … … 1994 2153 * challenge. */ 1995 2154 1996 sha Update(&ctx1, crypt_hash_xor1, 64);2155 sha1_append(&ctx1, crypt_hash_xor1, 64); 1997 2156 if (j >= 3 ) 1998 ctx1. sizeLo= 0x1ff;1999 sha Update(&ctx1, magic_key_char, 4);2000 sha Final(&ctx1, digest1);2157 ctx1.Length_Low = 0x1ff; 2158 sha1_append(&ctx1, magic_key_char, 4); 2159 sha1_finish(&ctx1, digest1); 2001 2160 2002 2161 /* The second context gets the password hash XORed … … 2004 2163 * of the first context. */ 2005 2164 2006 sha Update(&ctx2, crypt_hash_xor2, 64);2007 sha Update(&ctx2, digest1, 20);2008 sha Final(&ctx2, digest2);2165 sha1_append(&ctx2, crypt_hash_xor2, 64); 2166 sha1_append(&ctx2, digest1, 20); 2167 sha1_finish(&ctx2, digest2); 2009 2168 2010 2169 /* Now that we have digest2, use it to fetch … … 2174 2333 int online = FALSE; 2175 2334 int away = 0; 2335 int idle = 0; 2336 int mobile = 0; 2176 2337 2177 2338 YList *l; … … 2195 2356 else if (pair->key == 47) 2196 2357 away = strtol(pair->value, NULL, 10); 2358 else if (pair->key == 137) 2359 idle = strtol(pair->value, NULL, 10); 2360 else if (pair->key == 60) 2361 mobile = strtol(pair->value, NULL, 10); 2362 2197 2363 } 2198 2364 … … 2200 2366 YAHOO_CALLBACK(ext_yahoo_contact_added)(yd->client_id, id, who, msg); 2201 2367 else if (name) 2202 YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, name, state, msg, away );2368 YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, name, state, msg, away, idle, mobile); 2203 2369 else if(pkt->status == 0x07) 2204 2370 YAHOO_CALLBACK(ext_yahoo_rejected)(yd->client_id, who, msg); … … 2235 2401 where = "Unknown"; 2236 2402 2237 bud = y_new0(struct yahoo_buddy, 1); 2238 bud->id = strdup(who); 2239 bud->group = strdup(where); 2240 bud->real_name = NULL; 2241 2242 yd->buddies = y_list_append(yd->buddies, bud); 2403 /* status: 0 == Successful, 1 == Error (does not exist), 2 == Already in list */ 2404 if( status == 0 ) { 2405 bud = y_new0(struct yahoo_buddy, 1); 2406 bud->id = strdup(who); 2407 bud->group = strdup(where); 2408 bud->real_name = NULL; 2409 2410 yd->buddies = y_list_append(yd->buddies, bud); 2411 2412 /* Possibly called already, but at least the call above doesn't 2413 seem to happen every time (not anytime I tried). */ 2414 YAHOO_CALLBACK(ext_yahoo_contact_added)(yd->client_id, me, who, NULL); 2415 } 2243 2416 2244 2417 /* YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, who, status, NULL, (status==YAHOO_STATUS_AVAILABLE?0:1)); */ … … 2328 2501 2329 2502 /* if(status) 2330 YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, status, who, 0);2503 YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, who, 0, status); 2331 2504 */ 2332 2505 } … … 2352 2525 } 2353 2526 2354 NOTICE(("got voice chat invite from %s in %s ", who, room));2527 NOTICE(("got voice chat invite from %s in %s to identity %s", who, room, me)); 2355 2528 /* 2356 2529 * send: s:0 1:me 5:who 57:room 13:1 … … 2362 2535 * rejr: s:4 5:who 10:99 19:-1617114599 2363 2536 */ 2537 } 2538 2539 static void yahoo_process_ping(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 2540 { 2541 char *errormsg = NULL; 2542 2543 YList *l; 2544 for (l = pkt->hash; l; l = l->next) { 2545 struct yahoo_pair *pair = l->data; 2546 if (pair->key == 16) 2547 errormsg = pair->value; 2548 } 2549 2550 NOTICE(("got ping packet")); 2551 YAHOO_CALLBACK(ext_yahoo_got_ping)(yid->yd->client_id, errormsg); 2364 2552 } 2365 2553 … … 2539 2727 yahoo_process_webcam_key(yid, pkt); 2540 2728 break; 2729 case YAHOO_SERVICE_PING: 2730 yahoo_process_ping(yid, pkt); 2731 break; 2541 2732 case YAHOO_SERVICE_IDLE: 2542 2733 case YAHOO_SERVICE_MAILSTAT: … … 2546 2737 case YAHOO_SERVICE_ADDIDENT: 2547 2738 case YAHOO_SERVICE_ADDIGNORE: 2548 case YAHOO_SERVICE_PING:2549 2739 case YAHOO_SERVICE_GOTGROUPRENAME: 2550 2740 case YAHOO_SERVICE_GROUPRENAME: … … 2558 2748 yahoo_dump_unhandled(pkt); 2559 2749 break; 2750 case YAHOO_SERVICE_PICTURE: 2751 yahoo_process_picture(yid, pkt); 2752 break; 2753 case YAHOO_SERVICE_PICTURE_CHECKSUM: 2754 yahoo_process_picture_checksum(yid, pkt); 2755 break; 2756 case YAHOO_SERVICE_PICTURE_UPLOAD: 2757 yahoo_process_picture_upload(yid, pkt); 2758 break; 2560 2759 default: 2561 2760 WARNING(("unknown service 0x%02x", pkt->service)); … … 3150 3349 break; 3151 3350 case 5: 3152 if( cp != "\005")3351 if(strcmp(cp, "5") != 0) 3153 3352 yct->location = cp; 3154 3353 k = 0; … … 3367 3566 3368 3567 if(yid->type == YAHOO_CONNECTION_PAGER) { 3369 YAHOO_CALLBACK(ext_yahoo_ login_response)(yid->yd->client_id, YAHOO_LOGIN_SOCK, NULL);3568 YAHOO_CALLBACK(ext_yahoo_error)(yid->yd->client_id, "Connection closed by server", 1, E_CONNECTION); 3370 3569 } 3371 3570 … … 3515 3714 } 3516 3715 3517 void yahoo_send_im(int id, const char *from, const char *who, const char *what, int utf8 )3716 void yahoo_send_im(int id, const char *from, const char *who, const char *what, int utf8, int picture) 3518 3717 { 3519 3718 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 3520 3719 struct yahoo_packet *pkt = NULL; 3521 3720 struct yahoo_data *yd; 3721 char pic_str[10]; 3522 3722 3523 3723 if(!yid) … … 3528 3728 pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, yd->session_id); 3529 3729 3730 snprintf(pic_str, sizeof(pic_str), "%d", picture); 3731 3530 3732 if(from && strcmp(from, yd->user)) 3531 3733 yahoo_packet_hash(pkt, 0, yd->user); … … 3539 3741 yahoo_packet_hash(pkt, 63, ";0"); /* imvironment name; or ;0 */ 3540 3742 yahoo_packet_hash(pkt, 64, "0"); 3743 yahoo_packet_hash(pkt, 206, pic_str); 3541 3744 3542 3745 … … 3591 3794 else 3592 3795 service = YAHOO_SERVICE_ISAWAY; 3593 pkt = yahoo_packet_new(service, yd->current_status, yd->session_id); 3594 snprintf(s, sizeof(s), "%d", yd->current_status); 3595 yahoo_packet_hash(pkt, 10, s); 3596 if (yd->current_status == YAHOO_STATUS_CUSTOM) { 3597 yahoo_packet_hash(pkt, 19, msg); 3598 yahoo_packet_hash(pkt, 47, away?"1":"0"); 3796 3797 if ((away == 2) && (yd->current_status == YAHOO_STATUS_AVAILABLE)) { 3798 pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_BRB, yd->session_id); 3799 yahoo_packet_hash(pkt, 10, "999"); 3800 yahoo_packet_hash(pkt, 47, "2"); 3801 }else { 3802 pkt = yahoo_packet_new(service, YAHOO_STATUS_AVAILABLE, yd->session_id); 3803 snprintf(s, sizeof(s), "%d", yd->current_status); 3804 yahoo_packet_hash(pkt, 10, s); 3805 if (yd->current_status == YAHOO_STATUS_CUSTOM) { 3806 yahoo_packet_hash(pkt, 19, msg); 3807 yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0"); 3808 } else { 3809 yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0"); 3810 } 3811 3812 3813 3599 3814 } 3600 3815 … … 3837 4052 } 3838 4053 3839 void yahoo_add_buddy(int id, const char *who, const char *group )4054 void yahoo_add_buddy(int id, const char *who, const char *group, const char *msg) 3840 4055 { 3841 4056 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); … … 3854 4069 yahoo_packet_hash(pkt, 7, who); 3855 4070 yahoo_packet_hash(pkt, 65, group); 4071 if (msg != NULL) /* add message/request "it's me add me" */ 4072 yahoo_packet_hash(pkt, 14, msg); 3856 4073 yahoo_send_packet(yid, pkt, 0); 3857 4074 yahoo_packet_free(pkt); … … 3915 4132 yahoo_packet_hash(pkt, 7, who); 3916 4133 yahoo_packet_hash(pkt, 13, unignore?"2":"1"); 4134 yahoo_send_packet(yid, pkt, 0); 4135 yahoo_packet_free(pkt); 4136 } 4137 4138 void yahoo_stealth_buddy(int id, const char *who, int unstealth) 4139 { 4140 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4141 struct yahoo_data *yd; 4142 struct yahoo_packet *pkt; 4143 4144 if(!yid) 4145 return; 4146 yd = yid->yd; 4147 4148 if (!yd->logged_in) 4149 return; 4150 4151 pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH, YAHOO_STATUS_AVAILABLE, yd->session_id); 4152 yahoo_packet_hash(pkt, 1, yd->user); 4153 yahoo_packet_hash(pkt, 7, who); 4154 yahoo_packet_hash(pkt, 31, unstealth?"2":"1"); 4155 yahoo_packet_hash(pkt, 13, "2"); 3917 4156 yahoo_send_packet(yid, pkt, 0); 3918 4157 yahoo_packet_free(pkt); … … 4222 4461 yahoo_packet_hash(pkt, 1, (from?from:yd->user)); 4223 4462 4463 yahoo_send_packet(yid, pkt, 0); 4464 4465 yahoo_packet_free(pkt); 4466 } 4467 4468 void yahoo_buddyicon_request(int id, const char *who) 4469 { 4470 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4471 struct yahoo_data *yd; 4472 struct yahoo_packet *pkt; 4473 4474 if( !yid ) 4475 return; 4476 4477 yd = yid->yd; 4478 4479 pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YAHOO_STATUS_AVAILABLE, 0); 4480 yahoo_packet_hash(pkt, 4, yd->user); 4481 yahoo_packet_hash(pkt, 5, who); 4482 yahoo_packet_hash(pkt, 13, "1"); 4483 yahoo_send_packet(yid, pkt, 0); 4484 4485 yahoo_packet_free(pkt); 4486 } 4487 4488 void yahoo_send_picture_info(int id, const char *who, const char *url, int checksum) 4489 { 4490 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4491 struct yahoo_data *yd; 4492 struct yahoo_packet *pkt; 4493 char checksum_str[10]; 4494 4495 if( !yid ) 4496 return; 4497 4498 yd = yid->yd; 4499 4500 snprintf(checksum_str, sizeof(checksum_str), "%d", checksum); 4501 4502 pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YAHOO_STATUS_AVAILABLE, 0); 4503 yahoo_packet_hash(pkt, 1, yd->user); 4504 yahoo_packet_hash(pkt, 4, yd->user); 4505 yahoo_packet_hash(pkt, 5, who); 4506 yahoo_packet_hash(pkt, 13, "2"); 4507 yahoo_packet_hash(pkt, 20, url); 4508 yahoo_packet_hash(pkt, 192, checksum_str); 4509 yahoo_send_packet(yid, pkt, 0); 4510 4511 yahoo_packet_free(pkt); 4512 } 4513 4514 void yahoo_send_picture_update(int id, const char *who, int type) 4515 { 4516 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4517 struct yahoo_data *yd; 4518 struct yahoo_packet *pkt; 4519 char type_str[10]; 4520 4521 if( !yid ) 4522 return; 4523 4524 yd = yid->yd; 4525 4526 snprintf(type_str, sizeof(type_str), "%d", type); 4527 4528 pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPDATE, YAHOO_STATUS_AVAILABLE, 0); 4529 yahoo_packet_hash(pkt, 1, yd->user); 4530 yahoo_packet_hash(pkt, 5, who); 4531 yahoo_packet_hash(pkt, 206, type_str); 4532 yahoo_send_packet(yid, pkt, 0); 4533 4534 yahoo_packet_free(pkt); 4535 } 4536 4537 void yahoo_send_picture_checksum(int id, const char *who, int checksum) 4538 { 4539 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4540 struct yahoo_data *yd; 4541 struct yahoo_packet *pkt; 4542 char checksum_str[10]; 4543 4544 if( !yid ) 4545 return; 4546 4547 yd = yid->yd; 4548 4549 snprintf(checksum_str, sizeof(checksum_str), "%d", checksum); 4550 4551 pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_CHECKSUM, YAHOO_STATUS_AVAILABLE, 0); 4552 yahoo_packet_hash(pkt, 1, yd->user); 4553 if( who != 0 ) 4554 yahoo_packet_hash(pkt, 5, who); 4555 yahoo_packet_hash(pkt, 192, checksum_str); 4556 yahoo_packet_hash(pkt, 212, "1"); 4224 4557 yahoo_send_packet(yid, pkt, 0); 4225 4558 … … 4430 4763 }; 4431 4764 4765 static void _yahoo_send_picture_connected(int id, int fd, int error, void *data) 4766 { 4767 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_FT); 4768 struct send_file_data *sfd = data; 4769 struct yahoo_packet *pkt = sfd->pkt; 4770 unsigned char buff[1024]; 4771 4772 if(fd <= 0) { 4773 sfd->callback(id, fd, error, sfd->user_data); 4774 FREE(sfd); 4775 yahoo_packet_free(pkt); 4776 inputs = y_list_remove(inputs, yid); 4777 FREE(yid); 4778 return; 4779 } 4780 4781 yid->fd = fd; 4782 yahoo_send_packet(yid, pkt, 8); 4783 yahoo_packet_free(pkt); 4784 4785 snprintf((char *)buff, sizeof(buff), "29"); 4786 buff[2] = 0xc0; 4787 buff[3] = 0x80; 4788 4789 write(yid->fd, buff, 4); 4790 4791 /* YAHOO_CALLBACK(ext_yahoo_add_handler)(nyd->fd, YAHOO_INPUT_READ); */ 4792 4793 sfd->callback(id, fd, error, sfd->user_data); 4794 FREE(sfd); 4795 inputs = y_list_remove(inputs, yid); 4796 /* 4797 while(yahoo_tcp_readline(buff, sizeof(buff), nyd->fd) > 0) { 4798 if(!strcmp(buff, "")) 4799 break; 4800 } 4801 4802 */ 4803 yahoo_input_close(yid); 4804 } 4805 4806 void yahoo_send_picture(int id, const char *name, unsigned long size, 4807 yahoo_get_fd_callback callback, void *data) 4808 { 4809 struct yahoo_data *yd = find_conn_by_id(id); 4810 struct yahoo_input_data *yid; 4811 struct yahoo_server_settings *yss; 4812 struct yahoo_packet *pkt = NULL; 4813 char size_str[10]; 4814 char expire_str[10]; 4815 long content_length=0; 4816 unsigned char buff[1024]; 4817 char url[255]; 4818 struct send_file_data *sfd; 4819 4820 if(!yd) 4821 return; 4822 4823 yss = yd->server_settings; 4824 4825 yid = y_new0(struct yahoo_input_data, 1); 4826 yid->yd = yd; 4827 yid->type = YAHOO_CONNECTION_FT; 4828 4829 pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPLOAD, YAHOO_STATUS_AVAILABLE, yd->session_id); 4830 4831 snprintf(size_str, sizeof(size_str), "%ld", size); 4832 snprintf(expire_str, sizeof(expire_str), "%ld", (long)604800); 4833 4834 yahoo_packet_hash(pkt, 0, yd->user); 4835 yahoo_packet_hash(pkt, 1, yd->user); 4836 yahoo_packet_hash(pkt, 14, ""); 4837 yahoo_packet_hash(pkt, 27, name); 4838 yahoo_packet_hash(pkt, 28, size_str); 4839 yahoo_packet_hash(pkt, 38, expire_str); 4840 4841 4842 content_length = YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt); 4843 4844 snprintf(url, sizeof(url), "http://%s:%d/notifyft", 4845 yss->filetransfer_host, yss->filetransfer_port); 4846 snprintf((char *)buff, sizeof(buff), "Y=%s; T=%s", 4847 yd->cookie_y, yd->cookie_t); 4848 inputs = y_list_prepend(inputs, yid); 4849 4850 sfd = y_new0(struct send_file_data, 1); 4851 sfd->pkt = pkt; 4852 sfd->callback = callback; 4853 sfd->user_data = data; 4854 yahoo_http_post(yid->yd->client_id, url, (char *)buff, content_length+4+size, 4855 _yahoo_send_picture_connected, sfd); 4856 } 4857 4432 4858 static void _yahoo_send_file_connected(int id, int fd, int error, void *data) 4433 4859 {
Note: See TracChangeset
for help on using the changeset viewer.