/** * aim_puttlv_raw - Write a raw TLV. * @buf: Destination buffer * @t: TLV type * @l: Length of string * @v: String to write * * Writes a TLV with a raw value portion. (Only the first @l * bytes of the passed buffer will be written, which should not * include a terminating NULL.) * */ faim_export int aim_puttlv_raw(fu8_t *buf, const fu16_t t, const fu16_t l, const fu8_t *v) { int i; i = aimutil_put16(buf, t); i += aimutil_put16(buf+i, l); if (l) memcpy(buf+i, v, l); i += l; return i; }
/** * aim_puttlv_16 - Write a two-byte TLV. * @buf: Destination buffer * @t: TLV type * @v: Value * * Writes a TLV with a two-byte integer value portion. * */ faim_export int aim_puttlv_16(fu8_t *buf, const fu16_t t, const fu16_t v) { fu8_t v16[2]; aimutil_put16(v16, v); return aim_puttlv_raw(buf, t, 2, v16); }
/** * aim_addtlvtochain16 - Add a 16bit integer to a TLV chain * @list: Destination chain * @type: TLV type to add * @val: Value to add * * Adds a two-byte unsigned integer to a TLV chain. * */ faim_internal int aim_addtlvtochain16(aim_tlvlist_t **list, const fu16_t t, const fu16_t v) { fu8_t v16[2]; aimutil_put16(v16, v); return aim_addtlvtochain_raw(list, t, 2, v16); }
int byte_stream_put16(ByteStream *bs, guint16 v) { if (byte_stream_empty(bs) < 2) return 0; /* XXX throw an exception */ bs->offset += aimutil_put16(bs->data + bs->offset, v); return 2; }
faim_internal int aimbs_put16(aim_bstream_t *bs, fu16_t v) { if (aim_bstream_empty(bs) < 2) return 0; /* XXX throw an exception */ bs->offset += aimutil_put16(bs->data + bs->offset, v); return 2; }
int aimbs_put16(aim_bstream_t *bs, guint16 v) { if (aim_bstream_empty(bs) < 2) { return 0; /* XXX throw an exception */ } bs->offset += aimutil_put16(bs->data + bs->offset, v); return 2; }
/** * aim_proxyconnect - An extrememly quick and dirty SOCKS5 interface. * @sess: Session to connect * @host: Host to connect to * @port: Port to connect to * @statusret: Return value of the connection * * Attempts to connect to the specified host via the configured * proxy settings, if present. If no proxy is configured for * this session, the connection is done directly. * * XXX this is really awful. * */ static int aim_proxyconnect(aim_session_t *sess, const char *host, fu16_t port, fu32_t *statusret) { int fd = -1; if (strlen(sess->socksproxy.server)) { /* connecting via proxy */ int i; unsigned char buf[512]; struct sockaddr_in sa; struct hostent *hp; char *proxy; unsigned short proxyport = 1080; for(i=0;i<(int)strlen(sess->socksproxy.server);i++) { if (sess->socksproxy.server[i] == ':') { proxyport = atoi(&(sess->socksproxy.server[i+1])); break; } } proxy = (char *)malloc(i+1); strncpy(proxy, sess->socksproxy.server, i); proxy[i] = '\0'; if (!(hp = gethostbyname(proxy))) { faimdprintf(sess, 0, "proxyconnect: unable to resolve proxy name\n"); *statusret = (h_errno | AIM_CONN_STATUS_RESOLVERR); return -1; } free(proxy); memset(&sa.sin_zero, 0, 8); sa.sin_port = htons(proxyport); memcpy(&sa.sin_addr, hp->h_addr, hp->h_length); sa.sin_family = hp->h_addrtype; fd = socket(hp->h_addrtype, SOCK_STREAM, 0); if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) { faimdprintf(sess, 0, "proxyconnect: unable to connect to proxy\n"); close(fd); return -1; } i = 0; buf[0] = 0x05; /* SOCKS version 5 */ if (strlen(sess->socksproxy.username)) { buf[1] = 0x02; /* two methods */ buf[2] = 0x00; /* no authentication */ buf[3] = 0x02; /* username/password authentication */ i = 4; } else { buf[1] = 0x01; buf[2] = 0x00; i = 3; } if (write(fd, buf, i) < i) { *statusret = errno; close(fd); return -1; } if (read(fd, buf, 2) < 2) { *statusret = errno; close(fd); return -1; } if ((buf[0] != 0x05) || (buf[1] == 0xff)) { *statusret = EINVAL; close(fd); return -1; } /* check if we're doing username authentication */ if (buf[1] == 0x02) { i = aimutil_put8(buf, 0x01); /* version 1 */ i += aimutil_put8(buf+i, strlen(sess->socksproxy.username)); i += aimutil_putstr(buf+i, sess->socksproxy.username, strlen(sess->socksproxy.username)); i += aimutil_put8(buf+i, strlen(sess->socksproxy.password)); i += aimutil_putstr(buf+i, sess->socksproxy.password, strlen(sess->socksproxy.password)); if (write(fd, buf, i) < i) { *statusret = errno; close(fd); return -1; } if (read(fd, buf, 2) < 2) { *statusret = errno; close(fd); return -1; } if ((buf[0] != 0x01) || (buf[1] != 0x00)) { *statusret = EINVAL; close(fd); return -1; } } i = aimutil_put8(buf, 0x05); i += aimutil_put8(buf+i, 0x01); /* CONNECT */ i += aimutil_put8(buf+i, 0x00); /* reserved */ i += aimutil_put8(buf+i, 0x03); /* address type: host name */ i += aimutil_put8(buf+i, strlen(host)); i += aimutil_putstr(buf+i, host, strlen(host)); i += aimutil_put16(buf+i, port); if (write(fd, buf, i) < i) { *statusret = errno; close(fd); return -1; } if (read(fd, buf, 10) < 10) { *statusret = errno; close(fd); return -1; } if ((buf[0] != 0x05) || (buf[1] != 0x00)) { *statusret = EINVAL; close(fd); return -1; } } else { /* connecting directly */ struct sockaddr_in sa; struct hostent *hp; if (!(hp = gethostbyname(host))) { *statusret = (h_errno | AIM_CONN_STATUS_RESOLVERR); return -1; } memset(&sa, 0, sizeof(struct sockaddr_in)); sa.sin_port = htons(port); memcpy(&sa.sin_addr, hp->h_addr, hp->h_length); sa.sin_family = hp->h_addrtype; fd = socket(hp->h_addrtype, SOCK_STREAM, 0); if (sess->flags & AIM_SESS_FLAGS_NONBLOCKCONNECT) fcntl(fd, F_SETFL, O_NONBLOCK); /* XXX save flags */ if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) { if (sess->flags & AIM_SESS_FLAGS_NONBLOCKCONNECT) { if ((errno == EINPROGRESS) || (errno == EINTR)) { if (statusret) *statusret |= AIM_CONN_STATUS_INPROGRESS; return fd; } } close(fd); fd = -1; } } return fd; }