/* PROTO */ IMCOMM_RET snac_send_cli_update(void *handle) { IMCOMM_RET ret; pkt_t *pkt; /* * This makes the server send us extended status information */ #if 0 pkt = pkt_init(12); pkt_add16(pkt, 0x001d); pkt_add16(pkt, 0x0008); pkt_add32(pkt, 0x00020404); pkt_add32(pkt, 0x00000000); #endif pkt = pkt_init(8); pkt_add16(pkt, 0x0006); pkt_add16(pkt, 0x0004); if (((IMCOMM *) handle)->isinvisible) pkt_add32(pkt, 0x00000100); else pkt_add32(pkt, 0x00000000); ret = snac_sendpkt(handle, 0x01, 0x1e, pkt, 0); pkt_free(pkt); return ret; }
/* PROTO */ void imcomm_request_awayprofile(void *handle, char *sn) { pkt_t *packet; struct MultiPacket *mpkt; mpkt = MultiPktInit(); packet = pkt_init(3 + (uint8_t) strlen(sn)); pkt_add16(packet, 0x0003); pkt_add8(packet, (uint8_t) strlen(sn)); pkt_addraw(packet, (uint8_t *) sn, strlen(sn)); snac_addToMulti(handle, mpkt, 0x02, 0x05, packet->data, packet->len, 0); pkt_free(packet); packet = pkt_init(3 + (uint8_t) strlen(sn)); pkt_add16(packet, 0x0001); pkt_add8(packet, (uint8_t) strlen(sn)); pkt_addraw(packet, (uint8_t *) sn, strlen(sn)); snac_addToMulti(handle, mpkt, 0x02, 0x05, packet->data, packet->len, 0); pkt_free(packet); flap_sendMulti(handle, mpkt); MultiPktFree(mpkt); }
/* PROTO */ void imcomm_im_add_buddy(void *handle, char *sn) { IMCOMM_BUDDYLIST *temp, *trav; struct MultiPacket *mpkt; pkt_t *packet; char *sname; uint16_t nextid; sname = imcomm_simplify_sn(sn); for (trav = ((IMCOMM *) handle)->buddylist; trav != NULL; trav = trav->next) { if (strcmp(sname, trav->sn) == 0) { free(sname); return; } } nextid = imcomm_get_next_id(handle); temp = malloc(sizeof(IMCOMM_BUDDYLIST)); temp->sn = sname; temp->formattedsn = strdup(sname); temp->ssi_id = nextid; temp->next = NULL; if (((IMCOMM *) handle)->buddylist == NULL) ((IMCOMM *) handle)->buddylist = temp; else { for (trav = ((IMCOMM *) handle)->buddylist; trav->next != NULL; trav = trav->next); trav->next = temp; } mpkt = MultiPktInit(); snac_addToMulti(handle, mpkt, 0x13, 0x11, NULL, 0, 0); packet = pkt_init(10 + strlen(sname)); pkt_add16(packet, (uint16_t) strlen(sname)); pkt_addraw(packet, (unsigned char *) sname, strlen(sname)); pkt_add16(packet, 0x0001); pkt_add16(packet, nextid); pkt_add16(packet, 0x0000); pkt_add16(packet, 0x0000); snac_addToMulti(handle, mpkt, 0x13, 0x08, packet->data, packet->len, 0); pkt_free(packet); snac_addToMulti(handle, mpkt, 0x13, 0x012, NULL, 0, 0); flap_sendMulti(handle, mpkt); MultiPktFree(mpkt); }
/* PROTO */ IMCOMM_RET snac_ack_srv_pause(void *handle, uint8_t * data, size_t len) { pkt_t *ackpkt; struct IMComm_Families *tr; int count; for (count = 0, tr = ((IMCOMM *) handle)->families; tr; tr = tr->next) count++; ackpkt = pkt_init(count * 2); /* each family is 16 bits */ for (tr = ((IMCOMM *) handle)->families; tr; tr = tr->next) { pkt_add16(ackpkt, tr->family); printf("adding family %d (total %d).\n", tr->family, count); } ((IMCOMM *) handle)->srv_pause = 1; /* return snac_send(handle, 0x01, 0x0c, data, len, 0); */ snac_sendpkt(handle, 0x01, 0x0c, ackpkt, 0); pkt_free(ackpkt); return IMCOMM_RET_OK; }
/* PROTO */ IMCOMM_RET snac_ack_limits(void *handle, unsigned char *data, size_t len) { pkt_t *pkt; uint16_t x, y, num_classes, *ids; num_classes = two_to_16(data); ids = malloc(num_classes * 2); /* it's a 16 bit type, so we need * twice the bytes. Thanks to djgpp * for catching this bug! UNIX/win32 * let it go. */ for (x = 2, y = 0; y < num_classes; y++) { ids[y] = two_to_16(data + x); x += 35; } pkt = pkt_init(num_classes * 2); for (y = 0; y < num_classes; y++) pkt_add16(pkt, ids[y]); if (snac_sendpkt(handle, 0x01, 0x08, pkt, 0) != IMCOMM_RET_OK) { pkt_free(pkt); free(ids); return IMCOMM_RET_ERROR; } pkt_free(pkt); free(ids); return snac_multireq(handle); }
/* PROTO */ void snac_addToMulti(void *handle, struct MultiPacket * mpkt, uint16_t family, uint16_t subtype, unsigned char *data, uint16_t len, int updateidle) { pkt_t *snac_packet; snac_packet = pkt_init(len + 10); pkt_add16(snac_packet, family); pkt_add16(snac_packet, subtype); pkt_add16(snac_packet, 0); pkt_add32(snac_packet, ((IMCOMM *) handle)->snacreq); pkt_addraw(snac_packet, (uint8_t *) data, len); ((IMCOMM *) handle)->snacreq++; flap_addToMulti(mpkt, 0x02, snac_packet->data, snac_packet->len, updateidle); pkt_free(snac_packet); }
/* PROTO */ void imcomm_im_send_message(void *handle, const char *whom, const char *msg, int automsg) { pkt_t *packet; packet = pkt_init(28 + strlen(whom) + strlen(msg) + (4 * automsg)); /* * Message cookie? * * Putting something random seems to work. */ pkt_add32(packet, 0x01020304); pkt_add32(packet, 0x05060708); pkt_add16(packet, 0x0001); pkt_add8(packet, (uint8_t) strlen(whom)); pkt_addraw(packet, (uint8_t *) whom, strlen(whom)); pkt_add16(packet, 0x0002); pkt_add16(packet, (uint16_t) (uint16_t) (strlen(msg) + 13)); pkt_add32(packet, 0x05010001); pkt_add8(packet, 0x01); pkt_add16(packet, 0x0101); pkt_add16(packet, (uint16_t) (uint16_t) (strlen(msg) + 4)); pkt_add32(packet, 0x00000000); pkt_addraw(packet, (uint8_t *) msg, strlen(msg)); if (automsg) { pkt_add16(packet, 0x0004); pkt_add16(packet, 0x0000); } snac_sendpkt(handle, 0x04, 0x06, packet, (automsg ? 0 : 1)); pkt_free(packet); }
/* PROTO */ IMCOMM_RET snac_send_icbm_params(void *handle, uint16_t channel, uint16_t max_msg_size) { IMCOMM_RET ret; pkt_t *packet; packet = pkt_init(16); pkt_add32(packet, 0x00000000); pkt_add16(packet, 0x000b); pkt_add16(packet, 0x1f40); pkt_add16(packet, ((IMCOMM *) handle)->max_sender_warning); pkt_add16(packet, ((IMCOMM *) handle)->max_receiver_warning); pkt_add32(packet, 0x00000000); ret = snac_sendpkt(handle, 0x04, 0x02, packet, 0); pkt_free(packet); return ret; }
/* PROTO */ void snac_request_new_service(void *handle, uint16_t service) { pkt_t *pkt; pkt = pkt_init(2); pkt_add16(pkt, service); snac_sendpkt(handle, 0x01, 0x04, pkt, 0); pkt_free(pkt); }
/* PROTO */ void snac_finish_buddy_icon(void *handle) { /* * The icon data is contained in the parent's node */ pkt_t *newpkt; void *pptr = ((IMCOMM *) handle)->parent; newpkt = pkt_init(4 + ((IMCOMM *) pptr)->iconlen); pkt_add16(newpkt, 0x0001); pkt_add16(newpkt, ((IMCOMM *) pptr)->iconlen); pkt_addraw(newpkt, ((IMCOMM *) pptr)->icondata, ((IMCOMM *) pptr)->iconlen); snac_sendpkt(handle, 0x10, 0x02, newpkt, 0); pkt_free(newpkt); }
/**************************************************************************** * ow_write_header(struct owctx *ow) * * Write OLE header block. */ void ow_write_header(struct owctx *ow) { int root_start; int num_lists; struct pkt *pkt; int i; if (ow->biff_only) return; ow_calculate_sizes(ow); root_start = ow->root_start; num_lists = ow->list_blocks; pkt = pkt_init(0, VARIABLE_PACKET); pkt_add32(pkt, 0xD0CF11E0); /* OLE document file id part 1 */ pkt_add32(pkt, 0xA1B11AE1); /* OLE document file id part 2 */ pkt_add32_le(pkt, 0x00); /* UID of this file (can be all 0's) 1/4 */ pkt_add32_le(pkt, 0x00); /* UID of this file (can be all 0's) 2/4 */ pkt_add32_le(pkt, 0x00); /* UID of this file (can be all 0's) 3/4 */ pkt_add32_le(pkt, 0x00); /* UID of this file (can be all 0's) 4/4 */ pkt_add16_le(pkt, 0x3E); /* Revision number (almost always 0x003E) */ pkt_add16_le(pkt, 0x03); /* Version number (almost always 0x0003) */ pkt_add16(pkt, 0xFEFF); /* Byte order identifier: * (0xFEFF = Little Endian) * (0xFFFE = Big Endian) */ pkt_add16_le(pkt, 0x09); /* 2^x (9 = 512 bytes) */ pkt_add32_le(pkt, 0x06); /* Unknown 5 */ pkt_add32_le(pkt, 0x00); /* Unknown 5 */ pkt_add32_le(pkt, 0x00); /* Unknown 5 */ pkt_add32_le(pkt, num_lists); /* num_bbd_blocks */ pkt_add32_le(pkt, root_start); /* root_startblock */ pkt_add32_le(pkt, 0x00); /* Unknown 6 */ pkt_add32_le(pkt, 0x1000); /* Unknown 6 */ pkt_add32_le(pkt, -2); /* sbd_startblock */ pkt_add32_le(pkt, 0x00); /* Unknown 7 */ pkt_add32_le(pkt, -2); /* Unknown 7 */ pkt_add32_le(pkt, 0x00); /* Unknown 7 */ for (i = 1; i <= num_lists; i++) { root_start++; pkt_add32_le(pkt, root_start); } for (i = num_lists; i <= 108; i++) { pkt_add32_le(pkt, -1); /* Unused */ } ow->io_handler.write(ow->io_handle,pkt->data, pkt->len); pkt_free(pkt); }
/* PROTO */ IMCOMM_RET snac_send(void *handle, uint16_t family, uint16_t subtype, unsigned char *data, uint16_t len, int updateidle) { pkt_t *snac_packet; IMCOMM_RET ret; if (((IMCOMM *) handle)->srv_pause) return IMCOMM_RET_OK; snac_packet = pkt_init(len + 10); pkt_add16(snac_packet, family); pkt_add16(snac_packet, subtype); pkt_add16(snac_packet, 0); pkt_add32(snac_packet, ((IMCOMM *) handle)->snacreq); pkt_addraw(snac_packet, (uint8_t *) data, len); ((IMCOMM *) handle)->snacreq++; ret = flap_sendpkt(handle, 0x02, snac_packet, updateidle); pkt_free(snac_packet); return ret; }
/* PROTO */ IMCOMM_RET multi_ssiact_cliready(void *handle) { struct MultiPacket *multipkt; pkt_t *cliupdpkt; unsigned char cli_ready_packet[] = {0x00, 0x13, 0x00, 0x03, 0x01, 0x10, 0x08, 0xE5, 0x00, 0x0b, 0x00, 0x01, 0x01, 0x10, 0x08, 0xe5, 0x00, 0x0a, 0x00, 0x01, 0x01, 0x10, 0x08, 0xe5, 0x00, 0x09, 0x00, 0x01, 0x01, 0x10, 0x08, 0xe5, 0x00, 0x08, 0x00, 0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x01, 0x10, 0x08, 0xe5, 0x00, 0x04, 0x00, 0x01, 0x01, 0x10, 0x08, 0xe5, 0x00, 0x03, 0x00, 0x01, 0x01, 0x10, 0x08, 0xe5, 0x00, 0x02, 0x00, 0x01, 0x01, 0x10, 0x08, 0xe5, 0x00, 0x01, 0x00, 0x04, 0x01, 0x10, 0x08, 0xe5 }; multipkt = MultiPktInit(); cliupdpkt = pkt_init(12); pkt_add16(cliupdpkt, 0x001d); pkt_add16(cliupdpkt, 0x0008); pkt_add32(cliupdpkt, 0x00020404); pkt_add32(cliupdpkt, 0x00000000); snac_addToMulti(handle, multipkt, 0x01, 0x1e, cliupdpkt->data, cliupdpkt->len, 0); snac_addToMulti(handle, multipkt, 0x01, 0x02, cli_ready_packet, sizeof(cli_ready_packet), 0); snac_addToMulti(handle, multipkt, 0x13, 0x07, NULL, 0, 0); flap_sendMulti(handle, multipkt); MultiPktFree(multipkt); pkt_free(cliupdpkt); if (((IMCOMM *) handle)->callbacks[IMCOMM_ERROR]) ((IMCOMM *) handle)->callbacks[IMCOMM_ERROR] (handle, IMCOMM_STATUS_CONNECTED); return IMCOMM_RET_OK; }
/* PROTO */ void imcomm_request_awaymsg(void *handle, char *sn) { pkt_t *packet; packet = pkt_init(3 + (uint8_t) strlen(sn)); pkt_add16(packet, 0x0003); pkt_add8(packet, (uint8_t) strlen(sn)); pkt_addraw(packet, (uint8_t *) sn, strlen(sn)); snac_sendpkt(handle, 0x02, 0x05, packet, 0); pkt_free(packet); }
/* PROTO */ void imcomm_request_massawaymsg(void *handle, char **sns, int num) { pkt_t *packet; int x; struct MultiPacket *multipkt; multipkt = MultiPktInit(); for (x = 0; x < num; x++) { packet = pkt_init(3 + (uint8_t) strlen(sns[x])); pkt_add16(packet, 0x0003); pkt_add8(packet, (uint8_t) strlen(sns[x])); pkt_addraw(packet, (uint8_t *) sns[x], strlen(sns[x])); snac_addToMulti(handle, multipkt, 0x02, 0x05, packet->data, (uint16_t) packet->len, 0); pkt_free(packet); } flap_sendMulti(handle, multipkt); MultiPktFree(multipkt); }
/* PROTO */ IMCOMM_RET snac_set_location_info(void *handle) { pkt_t *packet; char *idstr = "text/aolrtf; charset=\"iso-8859-1\""; int pktlen = 0; uint8_t capabilities[] = {0x09, 0x46, 0x13, 0x46, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00, 0x09, 0x46, 0x13, 0x4d, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00, 0x09, 0x46, 0x00, 0x00, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 }; snac_send_cli_update(handle); if (((IMCOMM *) handle)->profile_str != NULL) pktlen += 8 + strlen(idstr) + strlen((char *) ((IMCOMM *) handle)->profile_str); if (((IMCOMM *) handle)->away_msg != NULL) pktlen += strlen((char *) ((IMCOMM *) handle)->away_msg); packet = pkt_init(pktlen + 10 + 8 + 4 + strlen(idstr) + sizeof(capabilities)); pkt_add16(packet, 0x0001); pkt_add16(packet, (uint16_t) strlen(idstr)); pkt_addraw(packet, (uint8_t *) idstr, strlen(idstr)); if (((IMCOMM *) handle)->profile_str != NULL) { pkt_add16(packet, 0x0002); pkt_add16(packet, (uint16_t) strlen((char *) ((IMCOMM *) handle)-> profile_str)); pkt_addraw(packet, ((IMCOMM *) handle)->profile_str, strlen((char *) ((IMCOMM *) handle)->profile_str)); } pkt_add16(packet, 0x0003); pkt_add16(packet, (uint16_t) strlen(idstr)); pkt_addraw(packet, (uint8_t *) idstr, strlen(idstr)); pkt_add16(packet, 0x0004); if (((IMCOMM *) handle)->away_msg != NULL) { pkt_add16(packet, (uint16_t) strlen((char *) ((IMCOMM *) handle)-> away_msg)); pkt_addraw(packet, ((IMCOMM *) handle)->away_msg, (uint16_t) strlen((char *) ((IMCOMM *) handle)-> away_msg)); } else { pkt_add16(packet, 0x0000); } pkt_add16(packet, 0x0005); pkt_add16(packet, (uint16_t) sizeof(capabilities)); pkt_addraw(packet, capabilities, sizeof(capabilities)); pkt_add16(packet, 0x0006); pkt_add16(packet, 0x0006); pkt_add16(packet, 0x0004); pkt_add32(packet, 0x00020002); snac_sendpkt(handle, 0x02, 0x04, packet, 0); pkt_free(packet); return IMCOMM_RET_OK; }
/* PROTO */ void imcomm_im_remove_buddy(void *handle, const char *sn) { char *sname, *snsend = NULL; pkt_t *packet; IMCOMM_BUDDYLIST *temp, *trav; struct MultiPacket *mpkt; uint16_t buddy_id = 0x00, buddy_group_id = 0x00; sname = imcomm_simplify_sn(sn); if (((IMCOMM *) handle)->buddylist != NULL) { if (strcmp(((IMCOMM *) handle)->buddylist->sn, sname) == 0) { temp = ((IMCOMM *) handle)->buddylist; ((IMCOMM *) handle)->buddylist = ((IMCOMM *) handle)->buddylist->next; buddy_id = temp->ssi_id; buddy_group_id = temp->group_id; snsend = temp->formattedsn; free(temp->sn); free(temp); } else { for (trav = ((IMCOMM *) handle)->buddylist; trav->next != NULL; trav = trav->next) { if (strcmp(trav->next->sn, sname) == 0) { temp = trav->next; trav->next = trav->next->next; buddy_id = temp->ssi_id; buddy_group_id = temp->group_id; snsend = temp->formattedsn; free(temp->sn); free(temp); break; } } } } imcomm_internal_delete_buddy(handle, sn); if (snsend == NULL) { free(sname); return; } /* * packet = malloc(strlen(sname) + 1); packet[0] = strlen(sname); * memcpy(packet + 1, sname, strlen(sname)); * * snac_send(handle, 0x03, 0x05, packet, (uint16_t) (strlen(sname) + 1), * 0); free(packet); */ mpkt = MultiPktInit(); snac_addToMulti(handle, mpkt, 0x13, 0x11, NULL, 0, 0); packet = pkt_init(10 + strlen(snsend)); pkt_add16(packet, (uint16_t) strlen(snsend)); pkt_addraw(packet, (unsigned char *) snsend, strlen(snsend)); pkt_add16(packet, buddy_group_id); pkt_add16(packet, buddy_id); pkt_add16(packet, 0x0000); pkt_add16(packet, 0x0000); snac_addToMulti(handle, mpkt, 0x13, 0x0a, packet->data, packet->len, 0); pkt_free(packet); snac_addToMulti(handle, mpkt, 0x13, 0x012, NULL, 0, 0); flap_sendMulti(handle, mpkt); MultiPktFree(mpkt); free(sname); free(snsend); }
/* PROTO */ int connect_socks5(void *handle, char *host, uint16_t port) { IMCOMM *h = (IMCOMM *) handle; struct sockaddr_in sin; struct hostent *he = NULL; long addy; struct in_addr ina = {0}; pkt_t *sockspkt; uint8_t len; unsigned char sockbuf[512]; #ifdef DEBUG printf("Connecting via SOCKS5 to %s/%u\n", host, port); printf("SOCKS5 proxy server: %s/%u\n", h->proxyserver, h->proxyport); #endif if ((he = gethostbyname(h->proxyserver)) == NULL) { addy = inet_addr(h->proxyserver); ina.s_addr = addy; } if ((h->socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) { if (h->callbacks[IMCOMM_ERROR]) h->callbacks[IMCOMM_ERROR] (handle, IMCOMM_ERROR_PROXY, PROXY_ERROR_CONNECT); return IMCOMM_RET_ERROR; } sin.sin_family = AF_INET; sin.sin_port = htons(h->proxyport); if (he == NULL) sin.sin_addr = ina; else sin.sin_addr = *((struct in_addr *) he->h_addr); memset(&(sin.sin_zero), 0, 8); if (connect (h->socket, (struct sockaddr *) & sin, sizeof(struct sockaddr)) == -1) { if (h->callbacks[IMCOMM_ERROR]) h->callbacks[IMCOMM_ERROR] (handle, IMCOMM_ERROR_PROXY, PROXY_ERROR_CONNECT); return IMCOMM_RET_ERROR; } sockspkt = pkt_init(3); pkt_add8(sockspkt, 0x05); pkt_add8(sockspkt, 0x01); pkt_add8(sockspkt, 0x00); if (send(h->socket, sockspkt->data, sockspkt->len, 0) < 0) { pkt_free(sockspkt); if (h->callbacks[IMCOMM_ERROR]) h->callbacks[IMCOMM_ERROR] (handle, IMCOMM_ERROR_DISCONNECTED, 0); shutdown(h->socket, 0x02); h->socket = -1; return IMCOMM_RET_ERROR; } pkt_free(sockspkt); recv(h->socket, sockbuf, 2, 0); if (sockbuf[1] != 0x00) { if (h->callbacks[IMCOMM_ERROR]) h->callbacks[IMCOMM_ERROR] (handle, IMCOMM_ERROR_PROXY, PROXY_ERROR_AUTH); return IMCOMM_RET_ERROR; } sockspkt = pkt_init(7 + strlen(host)); pkt_add8(sockspkt, 0x05); pkt_add8(sockspkt, 0x01); pkt_add8(sockspkt, 0x00); pkt_add8(sockspkt, 0x03); pkt_add8(sockspkt, (uint8_t) strlen(host)); pkt_addraw(sockspkt, (unsigned char *) host, strlen(host)); pkt_add16(sockspkt, port); if (send(h->socket, sockspkt->data, sockspkt->len, 0) < 0) { pkt_free(sockspkt); if (h->callbacks[IMCOMM_ERROR]) h->callbacks[IMCOMM_ERROR] (handle, IMCOMM_ERROR_DISCONNECTED, 0); shutdown(h->socket, 0x02); h->socket = -1; return IMCOMM_RET_ERROR; } pkt_free(sockspkt); recv(h->socket, sockbuf, 4, 0); if (sockbuf[1] != 0x00) { if (h->callbacks[IMCOMM_ERROR]) h->callbacks[IMCOMM_ERROR] (handle, IMCOMM_ERROR_PROXY, PROXY_ERROR_PROXYCONNECT); shutdown(h->socket, 0x02); h->socket = -1; return IMCOMM_RET_ERROR; } if (sockbuf[3] == 0x03) { recv(h->socket, &len, 1, 0); recv(h->socket, sockbuf, len + 2, 0); } else if (sockbuf[3] == 0x01) { recv(h->socket, sockbuf, 6, 0); } else { if (h->callbacks[IMCOMM_ERROR]) h->callbacks[IMCOMM_ERROR] (handle, IMCOMM_ERROR_PROXY, PROXY_ERROR_UNKNOWN); shutdown(h->socket, 0x02); h->socket = -1; return IMCOMM_RET_ERROR; } /* now we should be set to read the connection */ return IMCOMM_RET_OK; }