From 07e98f181c3819835ac4ae9655d6556c372b7307 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sat, 12 Jul 2008 11:36:39 +0000 Subject: [PATCH] reverting the code after 0.4.1, except for some patches --- src/Makefile | 2 +- src/common.c | 17 -------- src/common.h | 10 ++++- src/encoding.c | 2 +- src/iodine.c | 106 +++++++++++++++++++++-------------------------- src/iodined.c | 71 ++++++++++++------------------- src/user.c | 5 ++- src/user.h | 2 - src/version.h | 2 +- tests/Makefile | 4 +- tests/encoding.c | 8 ++-- 11 files changed, 94 insertions(+), 135 deletions(-) diff --git a/src/Makefile b/src/Makefile index 9ca5753..eca134f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,5 @@ CC = gcc -COMMONOBJS = tun.o dns.o read.o encoding.o login.o base32.o base64.o md5.o common.o packet.o +COMMONOBJS = tun.o dns.o read.o encoding.o login.o base32.o base64.o md5.o common.o CLIENTOBJS = iodine.o CLIENT = ../bin/iodine SERVEROBJS = iodined.o user.o diff --git a/src/common.c b/src/common.c index 52f917f..73cf24d 100644 --- a/src/common.c +++ b/src/common.c @@ -111,20 +111,3 @@ read_password(char *buf, size_t len) strncpy(buf, pwd, len); buf[len-1] = '\0'; } - -int -check_topdomain(char *str) -{ - int i; - - if(str[0] == '.') /* special case */ - return 1; - - for( i = 0; i < strlen(str); i++) { - if( isalpha(str[i]) || isdigit(str[i]) || str[i] == '-' || str[i] == '.' ) - continue; - else - return 1; - } - return 0; -} diff --git a/src/common.h b/src/common.h index eb6f719..811aa40 100644 --- a/src/common.h +++ b/src/common.h @@ -30,6 +30,14 @@ #define QUERY_NAME_SIZE 256 +struct packet +{ + int len; /* Total packet length */ + int sentlen; /* Length of chunk currently transmitted */ + int offset; /* Current offset */ + char data[64*1024]; /* The data */ +}; + struct query { char name[QUERY_NAME_SIZE]; short type; @@ -46,6 +54,4 @@ void do_detach(); void read_password(char*, size_t); -int check_topdomain(char *); - #endif diff --git a/src/encoding.c b/src/encoding.c index bfdaa7a..127e871 100644 --- a/src/encoding.c +++ b/src/encoding.c @@ -49,7 +49,7 @@ inline_dotify(char *buf, size_t buflen) } reader = writer - dots; - pos = (unsigned) (reader - buf); + pos = (unsigned) (reader - buf) + 1; while (dots) { if (pos % 62 == 0) { diff --git a/src/iodine.c b/src/iodine.c index 5b23c83..dbf760c 100644 --- a/src/iodine.c +++ b/src/iodine.c @@ -36,7 +36,6 @@ #endif #include "common.h" -#include "packet.h" #include "encoding.h" #include "base32.h" #include "dns.h" @@ -46,7 +45,7 @@ static void send_ping(int fd); static void send_chunk(int fd); -static int build_hostname(char *buf, size_t buflen, size_t offset, +static int build_hostname(char *buf, size_t buflen, const char *data, const size_t datalen, const char *topdomain, struct encoder *encoder); @@ -67,9 +66,6 @@ static char userid; /* DNS id for next packet */ static uint16_t chunkid; -/* DNS id for last packet with payload from server */ -static uint16_t server_id; - /* Base32 encoder used for non-data packets */ static struct encoder *b32; @@ -79,9 +75,6 @@ static struct encoder *dataenc; /* result of case preservation check done after login */ static int case_preserved; - -/* For easy conversion 0-F to ascii digit */ -static char hex[] = "0123456789ABCDEF"; static void sighandler(int sig) @@ -92,16 +85,16 @@ sighandler(int sig) static void send_query(int fd, char *hostname) { - char pkt[4096]; + char packet[4096]; struct query q; size_t len; q.id = ++chunkid; q.type = T_NULL; - len = dns_encode(pkt, sizeof(pkt), &q, QR_QUERY, hostname, strlen(hostname)); + len = dns_encode(packet, sizeof(packet), &q, QR_QUERY, hostname, strlen(hostname)); - sendto(fd, pkt, len, 0, (struct sockaddr*)&nameserv, sizeof(nameserv)); + sendto(fd, packet, len, 0, (struct sockaddr*)&nameserv, sizeof(nameserv)); } static void @@ -109,15 +102,14 @@ send_packet(int fd, char cmd, const char *data, const size_t datalen) { char buf[4096]; - build_hostname(buf, sizeof(buf), 1, data, datalen, topdomain, b32); - /* build_hostname clears buf, write command afterwards */ buf[0] = cmd; - + + build_hostname(buf + 1, sizeof(buf) - 1, data, datalen, topdomain, b32); send_query(fd, buf); } static int -build_hostname(char *buf, size_t buflen, size_t offset, +build_hostname(char *buf, size_t buflen, const char *data, const size_t datalen, const char *topdomain, struct encoder *encoder) { @@ -125,15 +117,14 @@ build_hostname(char *buf, size_t buflen, size_t offset, size_t space; char *b; + space = MIN(0xFF, buflen) - strlen(topdomain) - 2; if (!encoder->places_dots()) space -= (space / 62); /* space for dots */ memset(buf, 0, buflen); - memset(buf, 'A', offset); - b = buf + offset; - encsize = encoder->encode(b, &space, data, datalen); + encsize = encoder->encode(buf, &space, data, datalen); if (!encoder->places_dots()) inline_dotify(buf, buflen); @@ -149,6 +140,12 @@ build_hostname(char *buf, size_t buflen, size_t offset, return space; } +int +is_sending() +{ + return (packet.len != 0); +} + int read_dns(int fd, char *buf, int buflen) { @@ -167,15 +164,16 @@ read_dns(int fd, char *buf, int buflen) } rv = dns_decode(buf, buflen, &q, QR_ANSWER, data, r); - - if (rv > 0) { - server_id = q.id; - } - if (packet_empty(&packet) == 0 && chunkid == q.id) { + if (is_sending() && chunkid == q.id) { /* Got ACK on sent packet */ - packet_advance(&packet); - if (!packet_empty(&packet)) { + packet.offset += packet.sentlen; + if (packet.offset == packet.len) { + /* Packet completed */ + packet.offset = 0; + packet.len = 0; + packet.sentlen = 0; + } else { /* More to send */ send_chunk(fd); } @@ -200,8 +198,11 @@ tunnel_tun(int tun_fd, int dns_fd) inlen = read; compress2((uint8_t*)out, &outlen, (uint8_t*)in, inlen, 9); - packet_fill(&packet, out, outlen); - + memcpy(packet.data, out, MIN(outlen, sizeof(packet.data))); + packet.sentlen = 0; + packet.offset = 0; + packet.len = outlen; + send_chunk(dns_fd); return read; @@ -218,14 +219,14 @@ tunnel_dns(int tun_fd, int dns_fd) if ((read = read_dns(dns_fd, in, sizeof(in))) <= 0) return -1; - + outlen = sizeof(out); inlen = read; if (uncompress((uint8_t*)out, &outlen, (uint8_t*)in, inlen) != Z_OK) return -1; write_tun(tun_fd, out, outlen); - if (packet_empty(&packet)) + if (!is_sending()) send_ping(dns_fd); return read; @@ -246,7 +247,7 @@ tunnel(int tun_fd, int dns_fd) tv.tv_usec = 0; FD_ZERO(&fds); - if (packet_empty(&packet)) + if (!is_sending()) FD_SET(tun_fd, &fds); FD_SET(dns_fd, &fds); @@ -278,21 +279,19 @@ tunnel(int tun_fd, int dns_fd) static void send_chunk(int fd) { + char hex[] = "0123456789ABCDEF"; char buf[4096]; int avail; int code; - int sentlen; char *p; p = packet.data; p += packet.offset; - avail = packet_len_to_send(&packet); + avail = packet.len - packet.offset; - sentlen = build_hostname(buf, sizeof(buf), 3, p, avail, topdomain, dataenc); + packet.sentlen = build_hostname(buf + 1, sizeof(buf) - 1, p, avail, topdomain, dataenc); - packet_send_len(&packet, sentlen); - - if (sentlen == avail) + if (packet.sentlen == avail) code = 1; else code = 0; @@ -300,9 +299,6 @@ send_chunk(int fd) code |= (userid << 1); buf[0] = hex[code]; - /* tell server we received reply */ - buf[1] = hex[(server_id >> 4) & 0xf]; - buf[2] = hex[(server_id >> 0) & 0xf]; send_query(fd, buf); } @@ -326,17 +322,17 @@ send_login(int fd, char *login, int len) static void send_ping(int fd) { - char data[5]; + char data[3]; - /* clear any packet not sent */ - packet_init(&packet); + if (is_sending()) { + packet.sentlen = 0; + packet.offset = 0; + packet.len = 0; + } data[0] = userid; - /* tell server we received reply */ - data[1] = hex[(server_id >> 4) & 0xf]; - data[2] = hex[(server_id >> 0) & 0xf]; - data[3] = (rand_seed >> 8) & 0xff; - data[4] = (rand_seed >> 0) & 0xff; + data[1] = (rand_seed >> 8) & 0xff; + data[2] = (rand_seed >> 0) & 0xff; rand_seed++; @@ -451,7 +447,7 @@ perform_login: if(r > 0) { read = read_dns(dns_fd, in, sizeof(in)); - if(read < 0) { + if(read <= 0) { warn("read"); continue; } @@ -605,7 +601,7 @@ help() { static void version() { char *svnver; - + svnver = "$Rev$ from $Date$"; printf("iodine IP over DNS tunneling client\n"); @@ -633,7 +629,6 @@ main(int argc, char **argv) newroot = NULL; device = NULL; chunkid = 0; - server_id = 0; b32 = get_base32_encoder(); dataenc = get_base32_encoder(); @@ -642,14 +637,12 @@ main(int argc, char **argv) switch(choice) { case 'v': version(); - /* NOTREACHED */ break; case 'f': foreground = 1; break; case 'h': help(); - /* NOTREACHED */ break; case 'u': username = optarg; @@ -697,13 +690,8 @@ main(int argc, char **argv) set_nameserver(nameserv_addr); - if(strlen(topdomain) <= 128) { - if(check_topdomain(topdomain)) { - warnx("Topdomain contains invalid characters.\n"); - usage(); - } - } else { - warnx("Use a topdomain max 128 chars long.\n"); + if (strlen(topdomain) > 128 || topdomain[0] == '.') { + warnx("Use a topdomain max 128 chars long. Do not start it with a dot.\n"); usage(); } diff --git a/src/iodined.c b/src/iodined.c index 3b4652c..4adc82e 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -82,8 +82,10 @@ tunnel_tun(int tun_fd, int dns_fd) compress2((uint8_t*)out, &outlen, (uint8_t*)in, read, 9); /* if another packet is queued, throw away this one. TODO build queue */ - if (packet_empty(&(users[userid].outpacket))) { - return packet_fill(&(users[userid].outpacket), out, outlen); + if (users[userid].outpacket.len == 0) { + memcpy(users[userid].outpacket.data, out, outlen); + users[userid].outpacket.len = outlen; + return outlen; } else { return 0; } @@ -122,16 +124,6 @@ send_version_response(int fd, version_ack_t ack, uint32_t payload, struct user * write_dns(fd, &u->q, out, sizeof(out)); } -static void -send_chunk(int dns_fd, struct query *q, int userid) -{ - /* XXX: check MTU and only send part of packet if needed */ - write_dns(dns_fd, q, users[userid].outpacket.data, users[userid].outpacket.len); - /* move this reset to after receiving ack */ - users[userid].outpacket.len = 0; - users[userid].q.id = 0; -} - static int tunnel_dns(int tun_fd, int dns_fd) { @@ -255,7 +247,7 @@ tunnel_dns(int tun_fd, int dns_fd) write_dns(dns_fd, &(dummy.q), "BADIP", 5); } else { /* decode with this users encoding */ - read = unpack_data(unpacked, sizeof(unpacked), &(in[3]), read - 3, + read = unpack_data(unpacked, sizeof(unpacked), &(in[1]), read - 1, users[userid].encoder); users[userid].last_pkt = time(NULL); @@ -267,8 +259,8 @@ tunnel_dns(int tun_fd, int dns_fd) if (code & 1) { outlen = sizeof(out); - uncompress((uint8_t*)out, &outlen, (uint8_t*)users[userid].inpacket.data, - users[userid].inpacket.len); + uncompress((uint8_t*)out, &outlen, + (uint8_t*)users[userid].inpacket.data, users[userid].inpacket.len); hdr = (struct ip*) (out + 4); touser = find_user_by_ip(hdr->ip_dst.s_addr); @@ -279,21 +271,23 @@ tunnel_dns(int tun_fd, int dns_fd) } else { /* send the compressed packet to other client * if another packet is queued, throw away this one. TODO build queue */ - if (packet_empty(&(users[touser].outpacket))) { - packet_fill(&(users[touser].outpacket), users[userid].inpacket.data, - users[userid].inpacket.len); + if (users[touser].outpacket.len == 0) { + memcpy(users[touser].outpacket.data, users[userid].inpacket.data, users[userid].inpacket.len); + users[touser].outpacket.len = users[userid].inpacket.len; } } - packet_init(&(users[userid].inpacket)); /* clear inpacket */ + users[userid].inpacket.len = users[userid].inpacket.offset = 0; } } } /* userid must be set for a reply to be sent */ if (userid >= 0 && userid < USERS && dummy.q.fromlen == users[userid].addrlen && memcmp(&(users[userid].host), &(dummy.q.from), dummy.q.fromlen) == 0 && - packet_empty(&(users[userid].outpacket)) == 0) { + users[userid].outpacket.len > 0) { - send_chunk(dns_fd, &(dummy.q), userid); + write_dns(dns_fd, &(dummy.q), users[userid].outpacket.data, users[userid].outpacket.len); + users[userid].outpacket.len = 0; + users[userid].q.id = 0; } return 0; @@ -334,7 +328,9 @@ tunnel(int tun_fd, int dns_fd) if (i==0) { for (j = 0; j < USERS; j++) { if (users[j].q.id != 0) { - send_chunk(dns_fd, &(users[j].q), j); + write_dns(dns_fd, &(users[j].q), users[j].outpacket.data, users[j].outpacket.len); + users[j].outpacket.len = 0; + users[j].q.id = 0; } } } else { @@ -431,7 +427,8 @@ help() { static void version() { - char *svnver = "$Rev$ from $Date$"; + char *svnver; + svnver = "$Rev$ from $Date$"; printf("iodine IP over DNS tunneling server\n"); printf("SVN version: %s\n", svnver); exit(0); @@ -469,14 +466,12 @@ main(int argc, char **argv) switch(choice) { case 'v': version(); - /* NOTREACHED */ break; case 'f': foreground = 1; break; case 'h': help(); - /* NOTREACHED */ break; case 'u': username = optarg; @@ -495,6 +490,10 @@ main(int argc, char **argv) break; case 'p': port = atoi(optarg); + if (port) { + printf("ALERT! Other dns servers expect you to run on port 53.\n"); + printf("You must manually forward port 53 to port %d for things to work.\n", port); + } break; case 'P': strncpy(password, optarg, sizeof(password)); @@ -505,7 +504,6 @@ main(int argc, char **argv) break; default: usage(); - /* NOTREACHED */ break; } } @@ -522,13 +520,8 @@ main(int argc, char **argv) usage(); topdomain = strdup(argv[1]); - if(strlen(topdomain) <= 128) { - if(check_topdomain(topdomain)) { - warnx("Topdomain contains invalid characters.\n"); - usage(); - } - } else { - warnx("Use a topdomain max 128 chars long.\n"); + if (strlen(topdomain) > 128 || topdomain[0] == '.') { + warnx("Use a topdomain max 128 chars long. Do not start it with a dot.\n"); usage(); } @@ -539,20 +532,10 @@ main(int argc, char **argv) } } - if (mtu <= 0) { + if (mtu == 0) { warnx("Bad MTU given.\n"); usage(); } - - if(port < 1 || port > 65535) { - warnx("Bad port number given.\n"); - usage(); - } - - if (port != 53) { - printf("ALERT! Other dns servers expect you to run on port 53.\n"); - printf("You must manually forward port 53 to port %d for things to work.\n", port); - } if (listen_ip == INADDR_NONE) { warnx("Bad IP address to listen on.\n"); diff --git a/src/user.c b/src/user.c index 2bfccca..6cbddfb 100644 --- a/src/user.c +++ b/src/user.c @@ -46,8 +46,9 @@ init_users(in_addr_t my_ip) users[i].id = i; snprintf(newip, sizeof(newip), "0.0.0.%d", i + 1); users[i].tun_ip = my_ip + inet_addr(newip);; - packet_init(&(users[i].inpacket)); - packet_init(&(users[i].outpacket)); + users[i].inpacket.len = 0; + users[i].inpacket.offset = 0; + users[i].outpacket.len = 0; users[i].q.id = 0; } } diff --git a/src/user.h b/src/user.h index f2dfd44..2d0d2ad 100644 --- a/src/user.h +++ b/src/user.h @@ -17,8 +17,6 @@ #ifndef __USER_H__ #define __USER_H__ -#include "packet.h" - #define USERS 8 struct user { diff --git a/src/version.h b/src/version.h index 7db28a5..d12c2f9 100644 --- a/src/version.h +++ b/src/version.h @@ -19,7 +19,7 @@ /* This is the version of the network protocol It is usually equal to the latest iodine version number */ -#define VERSION 0x00000403 +#define VERSION 0x00000402 #endif /* _VERSION_H_ */ diff --git a/tests/Makefile b/tests/Makefile index a6ed2ea..ef45783 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,7 +1,7 @@ CC = gcc TEST = test OBJS = test.o base32.o base64.o read.o dns.o encoding.o login.o user.o -SRCOBJS = ../src/base32.o ../src/base64.o ../src/read.o ../src/dns.o ../src/encoding.o ../src/login.o ../src/md5.o ../src/user.o ../src/packet.o +SRCOBJS = ../src/base32.o ../src/base64.o ../src/read.o ../src/dns.o ../src/encoding.o ../src/login.o ../src/md5.o ../src/user.o OS = `uname | tr "a-z" "A-Z"` @@ -21,6 +21,6 @@ $(TEST): $(OBJS) $(SRCOBJS) clean: - @echo "Cleaning..." + @echo "Cleaning tests/" @rm -f *~ *.core $(TEST) $(OBJS) diff --git a/tests/encoding.c b/tests/encoding.c index 3c41f96..fcfae49 100644 --- a/tests/encoding.c +++ b/tests/encoding.c @@ -27,10 +27,10 @@ struct tuple char *a; char *b; } dottests[] = { - { "aaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaba", - "aaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab.a"}, - { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."}, + { "aaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "aaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.a"}, + { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."}, { "abc123", "abc123" }, { NULL, NULL } };