| 1330 aimbs_get8(&mbs); /* 01 */ |
1330 aimbs_get8(&mbs); /* 01 */ |
| 1331 aimbs_get8(&mbs); /* 01 */ |
1331 aimbs_get8(&mbs); /* 01 */ |
| 1332 |
1332 |
| 1333 /* Message string length, including character set info. */ |
1333 /* Message string length, including character set info. */ |
| 1334 msglen = aimbs_get16(&mbs); |
1334 msglen = aimbs_get16(&mbs); |
| |
1335 if (msglen > aim_bstream_empty(&mbs)) |
| |
1336 { |
| |
1337 faimdprintf(sess, 0, "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious."); |
| |
1338 break; |
| |
1339 } |
| 1335 |
1340 |
| 1336 /* Character set info */ |
1341 /* Character set info */ |
| 1337 flag1 = aimbs_get16(&mbs); |
1342 flag1 = aimbs_get16(&mbs); |
| 1338 flag2 = aimbs_get16(&mbs); |
1343 flag2 = aimbs_get16(&mbs); |
| 1339 |
1344 |
| 1409 { |
1414 { |
| 1410 fu16_t type, length; |
1415 fu16_t type, length; |
| 1411 aim_rxcallback_t userfunc; |
1416 aim_rxcallback_t userfunc; |
| 1412 int ret = 0; |
1417 int ret = 0; |
| 1413 struct aim_incomingim_ch1_args args; |
1418 struct aim_incomingim_ch1_args args; |
| 1414 int endpos; |
1419 unsigned int endpos; |
| 1415 |
1420 |
| 1416 memset(&args, 0, sizeof(args)); |
1421 memset(&args, 0, sizeof(args)); |
| 1417 |
1422 |
| 1418 aim_mpmsg_init(sess, &args.mpmsg); |
1423 aim_mpmsg_init(sess, &args.mpmsg); |
| 1419 |
1424 |
| 1420 /* |
1425 /* |
| 1421 * This used to be done using tlvchains. For performance reasons, |
1426 * This used to be done using tlvchains. For performance reasons, |
| 1422 * I've changed it to process the TLVs in-place. This avoids lots |
1427 * I've changed it to process the TLVs in-place. This avoids lots |
| 1423 * of per-IM memory allocations. |
1428 * of per-IM memory allocations. |
| 1424 */ |
1429 */ |
| 1425 while (aim_bstream_empty(bs)) { |
1430 while (aim_bstream_empty(bs)) |
| 1426 |
1431 { |
| 1427 type = aimbs_get16(bs); |
1432 type = aimbs_get16(bs); |
| 1428 length = aimbs_get16(bs); |
1433 length = aimbs_get16(bs); |
| |
1434 |
| |
1435 if (length > aim_bstream_empty(bs)) |
| |
1436 { |
| |
1437 faimdprintf(sess, 0, "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious.\n", userinfo->sn); |
| |
1438 break; |
| |
1439 } |
| 1429 |
1440 |
| 1430 endpos = aim_bstream_curpos(bs) + length; |
1441 endpos = aim_bstream_curpos(bs) + length; |
| 1431 |
1442 |
| 1432 if (type == 0x0002) { /* Message Block */ |
1443 if (type == 0x0002) { /* Message Block */ |
| 1433 |
1444 |
| 1442 |
1453 |
| 1443 aimbs_get8(bs); /* 05 */ |
1454 aimbs_get8(bs); /* 05 */ |
| 1444 aimbs_get8(bs); /* 01 */ |
1455 aimbs_get8(bs); /* 01 */ |
| 1445 |
1456 |
| 1446 args.featureslen = aimbs_get16(bs); |
1457 args.featureslen = aimbs_get16(bs); |
| 1447 /* XXX XXX this is all evil! */ |
1458 if (args.featureslen > aim_bstream_empty(bs)) |
| 1448 args.features = bs->data + bs->offset; |
1459 { |
| 1449 aim_bstream_advance(bs, args.featureslen); |
1460 faimdprintf(sess, 0, "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious.\n", userinfo->sn); |
| 1450 args.icbmflags |= AIM_IMFLAGS_CUSTOMFEATURES; |
1461 break; |
| |
1462 } |
| |
1463 if (args.featureslen == 0) |
| |
1464 { |
| |
1465 args.features = NULL; |
| |
1466 } |
| |
1467 else |
| |
1468 { |
| |
1469 args.features = aimbs_getraw(bs, args.featureslen); |
| |
1470 args.icbmflags |= AIM_IMFLAGS_CUSTOMFEATURES; |
| |
1471 } |
| 1451 |
1472 |
| 1452 /* |
1473 /* |
| 1453 * The rest of the TLV contains one or more message |
1474 * The rest of the TLV contains one or more message |
| 1454 * blocks... |
1475 * blocks... |
| 1455 */ |
1476 */ |
| 1496 |
1517 |
| 1497 args.icbmflags |= AIM_IMFLAGS_TYPINGNOT; |
1518 args.icbmflags |= AIM_IMFLAGS_TYPINGNOT; |
| 1498 |
1519 |
| 1499 } else if (type == 0x0017) { |
1520 } else if (type == 0x0017) { |
| 1500 |
1521 |
| |
1522 free(args.extdata); |
| 1501 args.extdatalen = length; |
1523 args.extdatalen = length; |
| 1502 args.extdata = aimbs_getraw(bs, args.extdatalen); |
1524 if (args.extdatalen > aim_bstream_empty(bs)) |
| |
1525 { |
| |
1526 faimdprintf(sess, 0, "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious.\n", userinfo->sn); |
| |
1527 break; |
| |
1528 } |
| |
1529 if (args.extdatalen == 0) |
| |
1530 args.extdata = NULL; |
| |
1531 else |
| |
1532 args.extdata = aimbs_getraw(bs, args.extdatalen); |
| 1503 |
1533 |
| 1504 } else { |
1534 } else { |
| 1505 faimdprintf(sess, 0, "incomingim_ch1: unknown TLV 0x%04x (len %d)\n", type, length); |
1535 faimdprintf(sess, 0, "incomingim_ch1: unknown TLV 0x%04x (len %d)\n", type, length); |
| 1506 } |
1536 } |
| 1507 |
1537 |
| 1519 |
1549 |
| 1520 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) |
1550 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) |
| 1521 ret = userfunc(sess, rx, channel, userinfo, &args); |
1551 ret = userfunc(sess, rx, channel, userinfo, &args); |
| 1522 |
1552 |
| 1523 aim_mpmsg_free(sess, &args.mpmsg); |
1553 aim_mpmsg_free(sess, &args.mpmsg); |
| |
1554 free(args.features); |
| 1524 free(args.extdata); |
1555 free(args.extdata); |
| 1525 |
1556 |
| 1526 return ret; |
1557 return ret; |
| 1527 } |
1558 } |
| 1528 |
1559 |