Changeset 5ebff60 for protocols/oscar/service.c
- Timestamp:
- 2015-02-20T22:50:54Z (10 years ago)
- Branches:
- master
- Children:
- 0b9daac, 3d45471, 7733b8c
- Parents:
- af359b4
- git-author:
- Indent <please@…> (19-02-15 05:47:20)
- git-committer:
- dequis <dx@…> (20-02-15 22:50:54)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/oscar/service.c
raf359b4 r5ebff60 11 11 int aim_clientready(aim_session_t *sess, aim_conn_t *conn) 12 12 { 13 aim_conn_inside_t *ins = (aim_conn_inside_t *) conn->inside;13 aim_conn_inside_t *ins = (aim_conn_inside_t *) conn->inside; 14 14 struct snacgroup *sg; 15 15 aim_frame_t *fr; 16 16 aim_snacid_t snacid; 17 17 18 if (!ins) 18 if (!ins) { 19 19 return -EINVAL; 20 21 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152))) 20 } 21 22 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152))) { 22 23 return -ENOMEM; 24 } 23 25 24 26 snacid = aim_cachesnac(sess, 0x0001, 0x0002, 0x0000, NULL, 0); … … 27 29 /* 28 30 * Send only the tool versions that the server cares about (that it 29 * marked as supporting in the server ready SNAC). 31 * marked as supporting in the server ready SNAC). 30 32 */ 31 33 for (sg = ins->groups; sg; sg = sg->next) { … … 37 39 aimbs_put16(&fr->data, mod->toolid); 38 40 aimbs_put16(&fr->data, mod->toolversion); 39 } 41 } 40 42 } 41 43 … … 47 49 /* 48 50 * Host Online (group 1, type 3) 49 * 51 * 50 52 * See comments in conn.c about how the group associations are supposed 51 53 * to work, and how they really work. … … 55 57 * We don't actually call the client here. This starts off the connection 56 58 * initialization routine required by all AIM connections. The next time 57 * the client is called is the CONNINITDONE callback, which should be 59 * the client is called is the CONNINITDONE callback, which should be 58 60 * shortly after the rate information is acknowledged. 59 * 61 * 60 62 */ 61 63 static int hostonline(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) … … 65 67 66 68 67 if (!(families = g_malloc(aim_bstream_empty(bs)))) 69 if (!(families = g_malloc(aim_bstream_empty(bs)))) { 68 70 return 0; 71 } 69 72 70 73 for (famcount = 0; aim_bstream_empty(bs); famcount++) { … … 86 89 aim_setversions(sess, rx->conn); 87 90 88 return 1; 91 return 1; 89 92 } 90 93 … … 109 112 110 113 if (!aim_gettlv(tlvlist, 0x000d, 1) || 111 112 114 !aim_gettlv(tlvlist, 0x0005, 1) || 115 !aim_gettlv(tlvlist, 0x0006, 1)) { 113 116 aim_freetlvchain(&tlvlist); 114 117 return 0; … … 117 120 redir.group = aim_gettlv16(tlvlist, 0x000d, 1); 118 121 redir.ip = aim_gettlv_str(tlvlist, 0x0005, 1); 119 redir.cookie = (guint8 *) aim_gettlv_str(tlvlist, 0x0006, 1);122 redir.cookie = (guint8 *) aim_gettlv_str(tlvlist, 0x0006, 1); 120 123 121 124 /* Fetch original SNAC so we can get csi if needed */ … … 123 126 124 127 if ((redir.group == AIM_CONN_TYPE_CHAT) && origsnac) { 125 struct chatsnacinfo *csi = (struct chatsnacinfo *) origsnac->data;128 struct chatsnacinfo *csi = (struct chatsnacinfo *) origsnac->data; 126 129 127 130 redir.chat.exchange = csi->exchange; … … 130 133 } 131 134 132 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 135 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 133 136 ret = userfunc(sess, rx, &redir); 134 135 g_free((void *)redir.ip); 136 g_free((void *)redir.cookie); 137 138 if (origsnac) 137 } 138 139 g_free((void *) redir.ip); 140 g_free((void *) redir.cookie); 141 142 if (origsnac) { 139 143 g_free(origsnac->data); 144 } 140 145 g_free(origsnac); 141 146 … … 157 162 * it. The rate classes, their limiting properties, and the definitions 158 163 * of which SNACs are belong to which class, are defined in the 159 * Rate Response packet at login to each host. 164 * Rate Response packet at login to each host. 160 165 * 161 166 * Logically, all rate offenses within one class count against further … … 171 176 * 172 177 * Rate class 0x0001: 173 * 178 * - Everything thats not in any of the other classes 174 179 * 175 180 * Rate class 0x0002: 176 * 181 * - Buddy list add/remove 177 182 * - Permit list add/remove 178 183 * - Deny list add/remove … … 190 195 * 191 196 * The only other thing of note is that class 5 (chat) has slightly looser 192 * limiting properties than class 3 (normal messages). But thats just a 197 * limiting properties than class 3 (normal messages). But thats just a 193 198 * small bit of trivia for you. 194 199 * … … 196 201 * system is how the actual numbers relate to the passing of time. This 197 202 * seems to be a big mystery. 198 * 203 * 199 204 */ 200 205 … … 203 208 struct rateclass *rc, *rc2; 204 209 205 if (!(rc = g_malloc(sizeof(struct rateclass)))) 210 if (!(rc = g_malloc(sizeof(struct rateclass)))) { 206 211 return; 212 } 207 213 208 214 memcpy(rc, inrc, sizeof(struct rateclass)); 209 215 rc->next = NULL; 210 216 211 for (rc2 = *head; rc2 && rc2->next; rc2 = rc2->next) 217 for (rc2 = *head; rc2 && rc2->next; rc2 = rc2->next) { 212 218 ; 213 214 if (!rc2) 219 } 220 221 if (!rc2) { 215 222 *head = rc; 216 else223 } else { 217 224 rc2->next = rc; 225 } 218 226 219 227 return; … … 225 233 226 234 for (rc = *head; rc; rc = rc->next) { 227 if (rc->classid == id) 235 if (rc->classid == id) { 228 236 return rc; 237 } 229 238 } 230 239 … … 236 245 struct snacpair *sp, *sp2; 237 246 238 if (!(sp = g_new0(struct snacpair, 1))) 247 if (!(sp = g_new0(struct snacpair, 1))) { 239 248 return; 249 } 240 250 241 251 sp->group = group; … … 243 253 sp->next = NULL; 244 254 245 for (sp2 = rc->members; sp2 && sp2->next; sp2 = sp2->next) 255 for (sp2 = rc->members; sp2 && sp2->next; sp2 = sp2->next) { 246 256 ; 247 248 if (!sp2) 257 } 258 259 if (!sp2) { 249 260 rc->members = sp; 250 else261 } else { 251 262 sp2->next = sp; 263 } 252 264 253 265 return; … … 257 269 static int rateresp(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 258 270 { 259 aim_conn_inside_t *ins = (aim_conn_inside_t *) rx->conn->inside;271 aim_conn_inside_t *ins = (aim_conn_inside_t *) rx->conn->inside; 260 272 guint16 numclasses, i; 261 273 aim_rxcallback_t userfunc; … … 284 296 * depending on the version we advertised in 1/17. If we 285 297 * didn't send 1/17 (evil!), then this will crash and you 286 * die, as it will default to the old version but we have 287 * the new version hardcoded here. 298 * die, as it will default to the old version but we have 299 * the new version hardcoded here. 288 300 */ 289 if (mod->version >= 3) 301 if (mod->version >= 3) { 290 302 aimbs_getrawbuf(bs, rc.unknown, sizeof(rc.unknown)); 303 } 291 304 292 305 rc_addclass(&ins->rates, &rc); … … 312 325 subtype = aimbs_get16(bs); 313 326 314 if (rc) 327 if (rc) { 315 328 rc_addpair(rc, group, subtype); 329 } 316 330 } 317 331 } … … 332 346 * Finally, tell the client it's ready to go... 333 347 */ 334 if ((userfunc = aim_callhandler(sess, rx->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE))) 348 if ((userfunc = aim_callhandler(sess, rx->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE))) { 335 349 userfunc(sess, rx); 350 } 336 351 337 352 … … 342 357 int aim_rates_addparam(aim_session_t *sess, aim_conn_t *conn) 343 358 { 344 aim_conn_inside_t *ins = (aim_conn_inside_t *) conn->inside;345 aim_frame_t *fr; 359 aim_conn_inside_t *ins = (aim_conn_inside_t *) conn->inside; 360 aim_frame_t *fr; 346 361 aim_snacid_t snacid; 347 362 struct rateclass *rc; 348 363 349 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 512))) 350 return -ENOMEM; 364 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 512))) { 365 return -ENOMEM; 366 } 351 367 352 368 snacid = aim_cachesnac(sess, 0x0001, 0x0008, 0x0000, NULL, 0); 353 369 aim_putsnac(&fr->data, 0x0001, 0x0008, 0x0000, snacid); 354 370 355 for (rc = ins->rates; rc; rc = rc->next) 371 for (rc = ins->rates; rc; rc = rc->next) { 356 372 aimbs_put16(&fr->data, rc->classid); 373 } 357 374 358 375 aim_tx_enqueue(sess, fr); … … 370 387 code = aimbs_get16(bs); 371 388 rateclass = aimbs_get16(bs); 372 389 373 390 windowsize = aimbs_get32(bs); 374 391 clear = aimbs_get32(bs); … … 379 396 maxavg = aimbs_get32(bs); 380 397 381 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 382 return userfunc(sess, rx, code, rateclass, windowsize, clear, alert, limit, disconnect, currentavg, maxavg); 398 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 399 return userfunc(sess, rx, code, rateclass, windowsize, clear, alert, limit, disconnect, currentavg, 400 maxavg); 401 } 383 402 384 403 return 0; … … 386 405 387 406 /* 388 * How Migrations work. 389 * 390 * The server sends a Server Pause message, which the client should respond to 391 * with a Server Pause Ack, which contains the families it needs on this 392 * connection. The server will send a Migration Notice with an IP address, and 393 * then disconnect. Next the client should open the connection and send the 407 * How Migrations work. 408 * 409 * The server sends a Server Pause message, which the client should respond to 410 * with a Server Pause Ack, which contains the families it needs on this 411 * connection. The server will send a Migration Notice with an IP address, and 412 * then disconnect. Next the client should open the connection and send the 394 413 * cookie. Repeat the normal login process and pretend this never happened. 395 414 * … … 403 422 aim_rxcallback_t userfunc; 404 423 405 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 424 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 406 425 return userfunc(sess, rx); 426 } 407 427 408 428 return 0; … … 414 434 aim_rxcallback_t userfunc; 415 435 416 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 436 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 417 437 return userfunc(sess, rx); 438 } 418 439 419 440 return 0; … … 434 455 aim_extractuserinfo(sess, bs, &userinfo); 435 456 436 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 457 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 437 458 return userfunc(sess, rx, &userinfo); 459 } 438 460 439 461 return 0; … … 448 470 449 471 memset(&userinfo, 0, sizeof(aim_userinfo_t)); 450 472 451 473 newevil = aimbs_get16(bs); 452 474 453 if (aim_bstream_empty(bs)) 475 if (aim_bstream_empty(bs)) { 454 476 aim_extractuserinfo(sess, bs, &userinfo); 455 456 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 477 } 478 479 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 457 480 return userfunc(sess, rx, newevil, &userinfo); 481 } 458 482 459 483 return 0; … … 464 488 * 465 489 * This is the final SNAC sent on the original connection during a migration. 466 * It contains the IP and cookie used to connect to the new server, and 490 * It contains the IP and cookie used to connect to the new server, and 467 491 * optionally a list of the SNAC groups being migrated. 468 492 * … … 482 506 * moves to the new server. When not all the groups for a connection 483 507 * are migrated, or they are all migrated but some groups are moved 484 * to a different server than others, it is called a bifurcated 508 * to a different server than others, it is called a bifurcated 485 509 * migration. 486 510 * … … 497 521 tl = aim_readtlvchain(bs); 498 522 499 if (aim_gettlv(tl, 0x0005, 1)) 523 if (aim_gettlv(tl, 0x0005, 1)) { 500 524 ip = aim_gettlv_str(tl, 0x0005, 1); 525 } 501 526 502 527 cktlv = aim_gettlv(tl, 0x0006, 1); 503 528 504 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 529 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 505 530 ret = userfunc(sess, rx, ip, cktlv ? cktlv->value : NULL); 531 } 506 532 507 533 aim_freetlvchain(&tl); … … 528 554 * 3 System bulletin 529 555 * 4 Nothing's wrong ("top o the world" -- normal) 530 * 5 Lets-break-something. 556 * 5 Lets-break-something. 531 557 * 532 558 */ 533 559 id = aimbs_get16(bs); 534 560 535 /* 536 * TLVs follow 561 /* 562 * TLVs follow 537 563 */ 538 564 tlvlist = aim_readtlvchain(bs); … … 540 566 msg = aim_gettlv_str(tlvlist, 0x000b, 1); 541 567 542 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 568 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 543 569 ret = userfunc(sess, rx, id, msg); 570 } 544 571 545 572 g_free(msg); … … 550 577 } 551 578 552 /* 579 /* 553 580 * Set privacy flags (group 1, type 0x14) 554 581 * … … 565 592 566 593 567 /* 568 * Set client versions (group 1, subtype 0x17) 569 * 570 * If you've seen the clientonline/clientready SNAC you're probably 594 /* 595 * Set client versions (group 1, subtype 0x17) 596 * 597 * If you've seen the clientonline/clientready SNAC you're probably 571 598 * wondering what the point of this one is. And that point seems to be 572 599 * that the versions in the client online SNAC are sent too late for the 573 600 * server to be able to use them to change the protocol for the earlier 574 * login packets (client versions are sent right after Host Online is 601 * login packets (client versions are sent right after Host Online is 575 602 * received, but client online versions aren't sent until quite a bit later). 576 603 * We can see them already making use of this by changing the format of … … 580 607 int aim_setversions(aim_session_t *sess, aim_conn_t *conn) 581 608 { 582 aim_conn_inside_t *ins = (aim_conn_inside_t *) conn->inside;609 aim_conn_inside_t *ins = (aim_conn_inside_t *) conn->inside; 583 610 struct snacgroup *sg; 584 611 aim_frame_t *fr; 585 612 aim_snacid_t snacid; 586 613 587 if (!ins) 614 if (!ins) { 588 615 return -EINVAL; 589 590 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152))) 616 } 617 618 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152))) { 591 619 return -ENOMEM; 620 } 592 621 593 622 snacid = aim_cachesnac(sess, 0x0001, 0x0017, 0x0000, NULL, 0); … … 596 625 /* 597 626 * Send only the versions that the server cares about (that it 598 * marked as supporting in the server ready SNAC). 627 * marked as supporting in the server ready SNAC). 599 628 */ 600 629 for (sg = ins->groups; sg; sg = sg->next) { … … 630 659 } 631 660 632 /* 661 /* 633 662 * Subtype 0x001e - Extended Status 634 663 * 635 664 * Sets your ICQ status (available, away, do not disturb, etc.) 636 665 * 637 * These are the same TLVs seen in user info. You can 666 * These are the same TLVs seen in user info. You can 638 667 * also set 0x0008 and 0x000c. 639 668 */ … … 647 676 648 677 data = AIM_ICQ_STATE_HIDEIP | status; /* yay for error checking ;^) */ 649 650 if (ic && set_getbool(&ic->acc->set, "web_aware")) 678 679 if (ic && set_getbool(&ic->acc->set, "web_aware")) { 651 680 data |= AIM_ICQ_STATE_WEBAWARE; 681 } 652 682 653 683 aim_addtlvtochain32(&tl, 0x0006, data); /* tlvlen */ 654 684 655 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 8))) 685 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 8))) { 656 686 return -ENOMEM; 687 } 657 688 658 689 snacid = aim_cachesnac(sess, 0x0001, 0x001e, 0x0000, NULL, 0); 659 690 aim_putsnac(&fr->data, 0x0001, 0x001e, 0x0000, snacid); 660 691 661 692 aim_writetlvchain(&fr->data, &tl); 662 693 aim_freetlvchain(&tl); 663 694 664 695 aim_tx_enqueue(sess, fr); 665 696 … … 688 719 * the data that the specific client should have, the client will get the 689 720 * following message from "AOL Instant Messenger": 690 * "You have been disconnected from the AOL Instant Message Service (SM) 721 * "You have been disconnected from the AOL Instant Message Service (SM) 691 722 * for accessing the AOL network using unauthorized software. You can 692 * download a FREE, fully featured, and authorized client, here 723 * download a FREE, fully featured, and authorized client, here 693 724 * http://www.aol.com/aim/download2.html" 694 725 * The connection is then closed, recieving disconnect code 1, URL 695 * http://www.aim.aol.com/errors/USER_LOGGED_OFF_NEW_LOGIN.html. 696 * 697 * Note, however, that numerous inconsistencies can cause the above error, 726 * http://www.aim.aol.com/errors/USER_LOGGED_OFF_NEW_LOGIN.html. 727 * 728 * Note, however, that numerous inconsistencies can cause the above error, 698 729 * not just sending back a bad hash. Do not immediatly suspect this code 699 730 * if you get disconnected. AOL and the open/free software community have … … 718 749 modname = aim_gettlv_str(list, 0x0001, 1); 719 750 720 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 751 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 721 752 return userfunc(sess, rx, offset, len, modname); 753 } 722 754 723 755 g_free(modname); … … 730 762 { 731 763 732 if (snac->subtype == 0x0003) 764 if (snac->subtype == 0x0003) { 733 765 return hostonline(sess, mod, rx, snac, bs); 734 else if (snac->subtype == 0x0005)766 } else if (snac->subtype == 0x0005) { 735 767 return redirect(sess, mod, rx, snac, bs); 736 else if (snac->subtype == 0x0007)768 } else if (snac->subtype == 0x0007) { 737 769 return rateresp(sess, mod, rx, snac, bs); 738 else if (snac->subtype == 0x000a)770 } else if (snac->subtype == 0x000a) { 739 771 return ratechange(sess, mod, rx, snac, bs); 740 else if (snac->subtype == 0x000b)772 } else if (snac->subtype == 0x000b) { 741 773 return serverpause(sess, mod, rx, snac, bs); 742 else if (snac->subtype == 0x000d)774 } else if (snac->subtype == 0x000d) { 743 775 return serverresume(sess, mod, rx, snac, bs); 744 else if (snac->subtype == 0x000f)776 } else if (snac->subtype == 0x000f) { 745 777 return selfinfo(sess, mod, rx, snac, bs); 746 else if (snac->subtype == 0x0010)778 } else if (snac->subtype == 0x0010) { 747 779 return evilnotify(sess, mod, rx, snac, bs); 748 else if (snac->subtype == 0x0012)780 } else if (snac->subtype == 0x0012) { 749 781 return migrate(sess, mod, rx, snac, bs); 750 else if (snac->subtype == 0x0013)782 } else if (snac->subtype == 0x0013) { 751 783 return motd(sess, mod, rx, snac, bs); 752 else if (snac->subtype == 0x0018)784 } else if (snac->subtype == 0x0018) { 753 785 return hostversions(sess, mod, rx, snac, bs); 754 else if (snac->subtype == 0x001f)786 } else if (snac->subtype == 0x001f) { 755 787 return memrequest(sess, mod, rx, snac, bs); 788 } 756 789 757 790 return 0;
Note: See TracChangeset
for help on using the changeset viewer.