uint32_t ventrilo3_handshake(uint32_t ip, uint16_t port, uint8_t *handshake, uint32_t *handshake_num, uint8_t *handshake_key) { struct linger ling = {1,1}; uint32_t sd, i, len; uint8_t sbuff[V3HBUFFSZ], rbuff[V3HBUFFSZ]; sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if(sd < 0) return(-1); setsockopt(sd, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling)); memset(rbuff, 0, 200); ventrilo3_hdr_udp(4, sbuff, rbuff); putbe(sbuff + 0xc, 2, 8); putbe(sbuff + 0x10, 1, 16); // useless putbe(sbuff + 0x12, time(NULL),16); // rand useless number ventrilo3_send_udp(sd, -1, ip, port, sbuff, 200); len = ventrilo3_recv_udp(sd, NULL, rbuff, V3HBUFFSZ, handshake_num); if(len < 0) goto quit; for(i = 0; ventrilo3_auth[i].host; i++) { len = ventrilo3_hdr_udp(5, sbuff, rbuff); ventrilo3_send_udp(sd, ventrilo3_auth[i].vnum, inet_addr(ventrilo3_auth[i].host), ventrilo3_auth[i].port, sbuff, len); } for(;;) { len = ventrilo3_recv_udp(sd, (void *)&ventrilo3_auth, rbuff, V3HBUFFSZ, handshake_num); if(len < 0) break; if(!len) continue; if(len < (0x5c + 16)) continue; #ifdef V3HPROXY memcpy(ventrilo3_auth[*handshake_num].handshake_key, rbuff + 0x1c, 64); memcpy(ventrilo3_auth[*handshake_num].handshake, rbuff + 0x5c, 16); ventrilo3_auth[*handshake_num].ok = 1; #else memcpy(handshake_key, rbuff + 0x1c, 64); memcpy(handshake, rbuff + 0x5c, 16); close(sd); return(0); #endif } quit: close(sd); #ifdef V3HPROXY return(0); #else return(-1); #endif }
static int mkhdr(Hdr *hp, Dir *dir, char *file) { int r; /* * some of these fields run together, so we format them left-to-right * and don't use snprint. */ sprint(hp->mode, "%6lo ", dir->mode & 0777); sprint(hp->uid, "%6o ", aruid); sprint(hp->gid, "%6o ", argid); if (dir->length >= (Off)1<<32) { static int printed; if (!printed) { printed = 1; fprint(2, "%s: storing large sizes in \"base 256\"\n", argv0); } hp->size[0] = Binsize; /* emit so-called `base 256' representation of size */ putbe((unsigned char *)hp->size+1, dir->length, sizeof hp->size - 2); hp->size[sizeof hp->size - 1] = ' '; } else sprint(hp->size, "%11lluo ", dir->length); sprint(hp->mtime, "%11luo ", dir->mtime); hp->linkflag = (dir->mode&DMDIR? LF_DIR: LF_PLAIN1); r = putfullname(hp, file); if (posix) { strncpy(hp->magic, "ustar", sizeof hp->magic); strncpy(hp->version, "00", sizeof hp->version); strncpy(hp->uname, dir->uid, sizeof hp->uname); strncpy(hp->gname, dir->gid, sizeof hp->gname); } sprint(hp->chksum, "%6luo", chksum(hp)); return r; }
uint32_t ventrilo3_hdr_udp(uint32_t type, uint8_t *buff, uint8_t *pck) { uint8_t c; memset(buff, 0, 0x200); // no, I'm not mad, this is EXACTLY what Ventrilo does switch(type - 1) { case 0: c = 0xb4; break; case 1: c = 0x70; break; case 2: c = 0x24; break; case 3: c = 0xb8; break; case 4: c = 0x74; break; case 5: c = 0x5c; break; case 6: c = 0xd0; break; case 7: c = 0x08; break; case 8: c = 0x50; break; default: c = 0; break; } c += 0x10; putbe(buff + 8, type, 16); putbe(buff + 10, c, 16); buff[4] = 'U'; buff[5] = 'D'; buff[6] = 'C'; buff[7] = 'L'; buff[0xc] = 1; putbe(buff + 0x10, 0xb401, 32); // x[seq], recheck putbe(buff + 0x14, getbe(pck + 0x14, NULL, 32), 32); putbe(buff + 0x18, getbe(pck + 0x18, NULL, 32), 32); putbe(buff + 0x1c, getbe(pck + 0x1c, NULL, 32), 32); putbe(buff + 0x20, getbe(pck + 0x20, NULL, 32), 32); putbe(buff + 0x24, getbe(pck + 0x28, NULL, 32), 32); buff[0x28] = pck[0x30]; buff[0x29] = 0; buff[0x2a] = 0; buff[0x2b] = 0; putbe(buff + 0x2c, getbe(pck + 0x24, NULL, 16), 16); putbe(buff + 0x2e, 0, 16); putbe(buff + 0x30, getbe(pck + 0x14, NULL, 16), 16); memcpy(buff + 0x34, pck + 0x38, 16); // hash memcpy(buff + 0x44, pck + 0x88, 32); // WIN32 buff[0x63] = 0; memcpy(buff + 0x64, pck + 0xa8, 32); // version buff[0x83] = 0; return(132); }