2 * Copyright (c) 2006-2009 Bjorn Andersson <flex@kryo.se>, Erik Ekman <yarrick@kryo.se>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 #include <sys/types.h>
24 #include <sys/param.h>
33 #include <arpa/nameser.h>
35 #include <arpa/nameser8_compat.h>
37 #include <sys/socket.h>
39 #include <arpa/inet.h>
40 #include <netinet/in.h>
56 WORD req_version = MAKEWORD(2, 2);
60 static void send_ping(int fd);
61 static void send_chunk(int fd);
62 static int build_hostname(char *buf, size_t buflen,
63 const char *data, const size_t datalen,
64 const char *topdomain, struct encoder *encoder);
66 static int running = 1;
67 static char password[33];
69 static struct sockaddr_in nameserv;
70 static char *topdomain;
72 static uint16_t rand_seed;
73 static int downstream_seqno;
74 static int downstream_fragment;
75 static int down_ack_seqno;
76 static int down_ack_fragment;
78 /* Current up/downstream IP packet */
79 static struct packet outpkt;
80 static struct packet inpkt;
82 /* My userid at the server */
85 /* DNS id for next packet */
86 static uint16_t chunkid;
88 /* Base32 encoder used for non-data packets */
89 static struct encoder *b32;
91 /* The encoder used for data packets
92 * Defaults to Base32, can be changed after handshake */
93 static struct encoder *dataenc;
95 /* result of case preservation check done after login */
96 static int case_preserved;
98 #if !defined(BSD) && !defined(__GLIBC__)
99 static char *__progname;
109 send_query(int fd, char *hostname)
118 len = dns_encode(packet, sizeof(packet), &q, QR_QUERY, hostname, strlen(hostname));
120 sendto(fd, packet, len, 0, (struct sockaddr*)&nameserv, sizeof(nameserv));
124 send_packet(int fd, char cmd, const char *data, const size_t datalen)
130 build_hostname(buf + 1, sizeof(buf) - 1, data, datalen, topdomain, b32);
135 build_hostname(char *buf, size_t buflen,
136 const char *data, const size_t datalen,
137 const char *topdomain, struct encoder *encoder)
143 space = MIN(0xFF, buflen) - strlen(topdomain) - 7;
144 if (!encoder->places_dots())
145 space -= (space / 57); /* space for dots */
147 memset(buf, 0, buflen);
149 encsize = encoder->encode(buf, &space, data, datalen);
151 if (!encoder->places_dots())
152 inline_dotify(buf, buflen);
160 strncpy(b, topdomain, strlen(topdomain)+1);
168 return (outpkt.len != 0);
172 read_dns(int fd, char *buf, int buflen)
174 struct sockaddr_in from;
181 addrlen = sizeof(struct sockaddr);
182 if ((r = recvfrom(fd, data, sizeof(data), 0,
183 (struct sockaddr*)&from, &addrlen)) == -1) {
188 rv = dns_decode(buf, buflen, &q, QR_ANSWER, data, r);
190 /* decode the data header, update seqno and frag before next request */
192 downstream_seqno = (buf[1] >> 5) & 7;
193 downstream_fragment = (buf[1] >> 1) & 15;
198 if (chunkid == q.id) {
199 /* Got ACK on sent packet */
200 outpkt.offset += outpkt.sentlen;
201 if (outpkt.offset == outpkt.len) {
202 /* Packet completed */
207 /* If the ack contains unacked frag number but no data,
208 * send a ping to ack the frag number and get more data*/
210 downstream_seqno != down_ack_seqno ||
211 downstream_fragment != down_ack_fragment
228 tunnel_tun(int tun_fd, int dns_fd)
230 unsigned long outlen;
236 if ((read = read_tun(tun_fd, in, sizeof(in))) <= 0)
239 outlen = sizeof(out);
241 compress2((uint8_t*)out, &outlen, (uint8_t*)in, inlen, 9);
243 memcpy(outpkt.data, out, MIN(outlen, sizeof(outpkt.data)));
256 tunnel_dns(int tun_fd, int dns_fd)
258 unsigned long datalen;
262 if ((read = read_dns(dns_fd, buf, sizeof(buf))) <= 2)
265 if (downstream_seqno != inpkt.seqno) {
267 inpkt.seqno = downstream_seqno;
268 inpkt.fragment = downstream_fragment;
270 } else if (downstream_fragment <= inpkt.fragment) {
271 /* Duplicate fragment */
274 inpkt.fragment = downstream_fragment;
276 datalen = MIN(read - 2, sizeof(inpkt.data) - inpkt.len);
278 /* Skip 2 byte data header and append to packet */
279 memcpy(&inpkt.data[inpkt.len], &buf[2], datalen);
280 inpkt.len += datalen;
282 if (buf[1] & 1) { /* If last fragment flag is set */
283 /* Uncompress packet and send to tun */
284 datalen = sizeof(buf);
285 if (uncompress((uint8_t*)buf, &datalen, (uint8_t*) inpkt.data, inpkt.len) == Z_OK) {
286 write_tun(tun_fd, buf, datalen);
291 /* If we have nothing to send, send a ping to get more data */
299 tunnel(int tun_fd, int dns_fd)
315 FD_SET(tun_fd, &fds);
317 FD_SET(dns_fd, &fds);
319 i = select(MAX(tun_fd, dns_fd) + 1, &fds, NULL, NULL, &tv);
327 if (i == 0) /* timeout */
330 if (FD_ISSET(tun_fd, &fds)) {
331 if (tunnel_tun(tun_fd, dns_fd) <= 0)
334 if (FD_ISSET(dns_fd, &fds)) {
335 if (tunnel_dns(tun_fd, dns_fd) <= 0)
347 char hex[] = "0123456789ABCDEF";
355 avail = outpkt.len - outpkt.offset;
357 outpkt.sentlen = build_hostname(buf + 4, sizeof(buf) - 4, p, avail, topdomain, dataenc);
359 /* Build upstream data header (see doc/proto_xxxxxxxx.txt) */
361 buf[0] = hex[userid & 15]; /* First byte is 4 bits userid */
363 code = ((outpkt.seqno & 7) << 2) | ((outpkt.fragment & 15) >> 2);
364 buf[1] = b32_5to8(code); /* Second byte is 3 bits seqno, 2 upper bits fragment count */
366 code = ((outpkt.fragment & 3) << 3) | (downstream_seqno & 7);
367 buf[2] = b32_5to8(code); /* Third byte is 2 bits lower fragment count, 3 bits downstream packet seqno */
369 code = ((downstream_fragment & 15) << 1) | (outpkt.sentlen == avail);
370 buf[3] = b32_5to8(code); /* Fourth byte is 4 bits downstream fragment count, 1 bit last frag flag */
372 down_ack_seqno = downstream_seqno;
373 down_ack_fragment = downstream_fragment;
380 send_login(int fd, char *login, int len)
384 memset(data, 0, sizeof(data));
386 memcpy(&data[1], login, MIN(len, 16));
388 data[17] = (rand_seed >> 8) & 0xff;
389 data[18] = (rand_seed >> 0) & 0xff;
393 send_packet(fd, 'L', data, sizeof(data));
408 data[1] = ((downstream_seqno & 7) << 4) | (downstream_fragment & 15);
409 data[2] = (rand_seed >> 8) & 0xff;
410 data[3] = (rand_seed >> 0) & 0xff;
412 down_ack_seqno = downstream_seqno;
413 down_ack_fragment = downstream_fragment;
417 send_packet(fd, 'P', data, sizeof(data));
421 send_fragsize_probe(int fd, int fragsize)
426 /* build a large query domain which is random and maximum size */
427 memset(probedata, MIN(1, rand_seed & 0xff), sizeof(probedata));
428 probedata[1] = MIN(1, (rand_seed >> 8) & 0xff);
430 build_hostname(buf + 4, sizeof(buf) - 4, probedata, sizeof(probedata), topdomain, dataenc);
434 buf[0] = 'r'; /* Probe downstream fragsize packet */
435 buf[1] = b32_5to8((userid << 1) | ((fragsize >> 10) & 1));
436 buf[2] = b32_5to8((fragsize >> 5) & 31);
437 buf[3] = b32_5to8(fragsize & 31);
443 send_set_downstream_fragsize(int fd, int fragsize)
448 data[1] = (fragsize & 0xff00) >> 8;
449 data[2] = (fragsize & 0x00ff);
450 data[3] = (rand_seed >> 8) & 0xff;
451 data[4] = (rand_seed >> 0) & 0xff;
455 send_packet(fd, 'N', data, sizeof(data));
459 send_version(int fd, uint32_t version)
463 data[0] = (version >> 24) & 0xff;
464 data[1] = (version >> 16) & 0xff;
465 data[2] = (version >> 8) & 0xff;
466 data[3] = (version >> 0) & 0xff;
468 data[4] = (rand_seed >> 8) & 0xff;
469 data[5] = (rand_seed >> 0) & 0xff;
473 send_packet(fd, 'V', data, sizeof(data));
477 send_case_check(int fd)
479 /* The '+' plus character is not allowed according to RFC.
480 * Expect to get SERVFAIL or similar if it is rejected.
482 char buf[512] = "zZ+-aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyY1234.";
484 strncat(buf, topdomain, 512 - strlen(buf));
489 send_codec_switch(int fd, int userid, int bits)
491 char buf[512] = "S__.";
492 buf[1] = b32_5to8(userid);
493 buf[2] = b32_5to8(bits);
495 strncat(buf, topdomain, 512 - strlen(buf));
500 handshake_version(int dns_fd, int *seed)
510 for (i = 0; running && i < 5; i++) {
514 send_version(dns_fd, VERSION);
517 FD_SET(dns_fd, &fds);
519 r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
522 read = read_dns(dns_fd, in, sizeof(in));
526 warn("handshake read");
528 /* if read < 0 then warning has been printed already */
533 payload = (((in[4] & 0xff) << 24) |
534 ((in[5] & 0xff) << 16) |
535 ((in[6] & 0xff) << 8) |
538 if (strncmp("VACK", in, 4) == 0) {
542 fprintf(stderr, "Version ok, both using protocol v 0x%08x. You are user #%d\n", VERSION, userid);
544 } else if (strncmp("VNAK", in, 4) == 0) {
545 warnx("You use protocol v 0x%08x, server uses v 0x%08x. Giving up",
548 } else if (strncmp("VFUL", in, 4) == 0) {
549 warnx("Server full, all %d slots are taken. Try again later", payload);
553 warnx("did not receive proper login challenge");
556 fprintf(stderr, "Retrying version check...\n");
558 warnx("couldn't connect to server");
563 handshake_login(int dns_fd, int seed)
576 login_calculate(login, 16, password, seed);
578 for (i=0; running && i<5 ;i++) {
582 send_login(dns_fd, login, 16);
585 FD_SET(dns_fd, &fds);
587 r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
590 read = read_dns(dns_fd, in, sizeof(in));
599 if (strncmp("LNAK", in, 4) == 0) {
600 fprintf(stderr, "Bad password\n");
602 } else if (sscanf(in, "%64[^-]-%64[^-]-%d-%d",
603 server, client, &mtu, &netmask) == 4) {
607 if (tun_setip(client, netmask) == 0 &&
608 tun_setmtu(mtu) == 0) {
611 warnx("Received handshake with bad data");
614 fprintf(stderr, "Received bad handshake\n");
619 fprintf(stderr, "Retrying login...\n");
621 warnx("couldn't login to server");
626 handshake_case_check(int dns_fd)
636 for (i=0; running && i<5 ;i++) {
640 send_case_check(dns_fd);
643 FD_SET(dns_fd, &fds);
645 r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
648 read = read_dns(dns_fd, in, sizeof(in));
651 if (in[0] == 'z' || in[0] == 'Z') {
652 if (read < (27 * 2)) {
653 fprintf(stderr, "Received short case check reply. Will use base32 encoder\n");
658 /* TODO enhance this, base128 is probably also possible */
660 for (k = 0; k < 27 && case_preserved; k += 2) {
661 if (in[k] == in[k+1]) {
662 /* test string: zZ+-aAbBcCdDeE... */
669 fprintf(stderr, "Received bad case check reply\n");
672 fprintf(stderr, "Got error on case check, will use base32\n");
677 fprintf(stderr, "Retrying case check...\n");
680 fprintf(stderr, "No reply on case check, continuing\n");
684 handshake_switch_codec(int dns_fd)
693 dataenc = get_base64_encoder();
694 fprintf(stderr, "Switching to %s codec\n", dataenc->name);
695 /* Send to server that this user will use base64 from now on */
696 for (i=0; running && i<5 ;i++) {
701 bits = 6; /* base64 = 6 bits per byte */
703 send_codec_switch(dns_fd, userid, bits);
706 FD_SET(dns_fd, &fds);
708 r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
711 read = read_dns(dns_fd, in, sizeof(in));
714 if (strncmp("BADLEN", in, 6) == 0) {
715 fprintf(stderr, "Server got bad message length. ");
717 } else if (strncmp("BADIP", in, 5) == 0) {
718 fprintf(stderr, "Server rejected sender IP address. ");
720 } else if (strncmp("BADCODEC", in, 8) == 0) {
721 fprintf(stderr, "Server rejected the selected codec. ");
724 in[read] = 0; /* zero terminate */
725 fprintf(stderr, "Server switched to codec %s\n", in);
729 fprintf(stderr, "Retrying codec switch...\n");
731 fprintf(stderr, "No reply from server on codec switch. ");
734 fprintf(stderr, "Falling back to base32\n");
735 dataenc = get_base32_encoder();
739 handshake_autoprobe_fragsize(int dns_fd)
747 int proposed_fragsize = 768;
749 int max_fragsize = 0;
752 fprintf(stderr, "Autoprobing max downstream fragment size... (skip with -m fragsize)\n");
753 while (running && range > 0 && (range >= 8 || !max_fragsize)) {
754 for (i=0; running && i<3 ;i++) {
757 send_fragsize_probe(dns_fd, proposed_fragsize);
760 FD_SET(dns_fd, &fds);
762 r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
765 read = read_dns(dns_fd, in, sizeof(in));
769 int acked_fragsize = ((in[0] & 0xff) << 8) | (in[1] & 0xff);
770 if (acked_fragsize == proposed_fragsize) {
771 if (read == proposed_fragsize) {
772 fprintf(stderr, "%d ok.. ", acked_fragsize);
774 max_fragsize = acked_fragsize;
777 if (strncmp("BADIP", in, 5) == 0) {
778 fprintf(stderr, "got BADIP.. ");
784 fprintf(stderr, ".");
788 if (max_fragsize == proposed_fragsize) {
790 proposed_fragsize += range;
793 fprintf(stderr, "%d not ok.. ", proposed_fragsize);
795 proposed_fragsize -= range;
799 fprintf(stderr, "\n");
800 warnx("stopped while autodetecting fragment size (Try probing manually with -m)");
804 /* Tried all the way down to 2 and found no good size */
805 fprintf(stderr, "\n");
806 warnx("found no accepted fragment size. (Try probing manually with -m)");
809 fprintf(stderr, "will use %d\n", max_fragsize);
814 handshake_set_fragsize(int dns_fd, int fragsize)
823 fprintf(stderr, "Setting downstream fragment size to max %d...\n", fragsize);
824 for (i=0; running && i<5 ;i++) {
828 send_set_downstream_fragsize(dns_fd, fragsize);
831 FD_SET(dns_fd, &fds);
833 r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
836 read = read_dns(dns_fd, in, sizeof(in));
839 int accepted_fragsize;
841 if (strncmp("BADFRAG", in, 7) == 0) {
842 fprintf(stderr, "Server rejected fragsize. Keeping default.");
844 } else if (strncmp("BADIP", in, 5) == 0) {
845 fprintf(stderr, "Server rejected sender IP address.\n");
849 accepted_fragsize = ((in[0] & 0xff) << 8) | (in[1] & 0xff);
853 fprintf(stderr, "Retrying set fragsize...\n");
855 fprintf(stderr, "No reply from server when setting fragsize. Keeping default.\n");
859 handshake(int dns_fd, int autodetect_frag_size, int fragsize)
864 r = handshake_version(dns_fd, &seed);
869 r = handshake_login(dns_fd, seed);
874 handshake_case_check(dns_fd);
876 if (case_preserved) {
877 handshake_switch_codec(dns_fd);
880 if (autodetect_frag_size) {
881 fragsize = handshake_autoprobe_fragsize(dns_fd);
887 handshake_set_fragsize(dns_fd, fragsize);
893 get_resolvconf_addr()
895 static char addr[16];
903 if ((fp = fopen("/etc/resolv.conf", "r")) == NULL)
904 err(1, "/etc/resolve.conf");
906 while (feof(fp) == 0) {
907 fgets(buf, sizeof(buf), fp);
909 if (sscanf(buf, "nameserver %15s", addr) == 1) {
916 #else /* !WINDOWS32 */
917 FIXED_INFO *fixed_info;
922 fixed_info = malloc(sizeof(FIXED_INFO));
923 buflen = sizeof(FIXED_INFO);
925 if (GetNetworkParams(fixed_info, &buflen) == ERROR_BUFFER_OVERFLOW) {
926 /* official ugly api workaround */
928 fixed_info = malloc(buflen);
931 ret = GetNetworkParams(fixed_info, &buflen);
932 if (ret == NO_ERROR) {
933 strncpy(addr, fixed_info->DnsServerList.IpAddress.String, sizeof(addr));
943 set_nameserver(const char *cp)
947 if (inet_aton(cp, &addr) != 1)
948 errx(1, "error parsing nameserver address: '%s'", cp);
950 memset(&nameserv, 0, sizeof(nameserv));
951 nameserv.sin_family = AF_INET;
952 nameserv.sin_port = htons(53);
953 nameserv.sin_addr = addr;
958 extern char *__progname;
960 fprintf(stderr, "Usage: %s [-v] [-h] [-f] [-u user] [-t chrootdir] [-d device] "
961 "[-P password] [-m maxfragsize] [nameserver] topdomain\n", __progname);
967 extern char *__progname;
969 fprintf(stderr, "iodine IP over DNS tunneling client\n");
970 fprintf(stderr, "Usage: %s [-v] [-h] [-f] [-u user] [-t chrootdir] [-d device] "
971 "[-P password] [-m maxfragsize] [nameserver] topdomain\n", __progname);
972 fprintf(stderr, " -v to print version info and exit\n");
973 fprintf(stderr, " -h to print this help and exit\n");
974 fprintf(stderr, " -f to keep running in foreground\n");
975 fprintf(stderr, " -u name to drop privileges and run as user 'name'\n");
976 fprintf(stderr, " -t dir to chroot to directory dir\n");
977 fprintf(stderr, " -d device to set tunnel device name\n");
978 fprintf(stderr, " -P password used for authentication (max 32 chars will be used)\n");
979 fprintf(stderr, " -m maxfragsize, to limit size of downstream packets\n");
980 fprintf(stderr, "nameserver is the IP number of the relaying nameserver, if absent /etc/resolv.conf is used\n");
981 fprintf(stderr, "topdomain is the FQDN that is delegated to the tunnel endpoint.\n");
988 printf("iodine IP over DNS tunneling client\n");
989 printf("version: 0.5.1 from 2009-03-21\n");
995 main(int argc, char **argv)
1008 int max_downstream_frag_size;
1009 int autodetect_frag_size;
1011 memset(password, 0, 33);
1021 autodetect_frag_size = 1;
1022 max_downstream_frag_size = 3072;
1024 b32 = get_base32_encoder();
1025 dataenc = get_base32_encoder();
1028 WSAStartup(req_version, &wsa_data);
1031 #if !defined(BSD) && !defined(__GLIBC__)
1032 __progname = strrchr(argv[0], '/');
1033 if (__progname == NULL)
1034 __progname = argv[0];
1039 while ((choice = getopt(argc, argv, "vfhu:t:d:P:m:")) != -1) {
1062 strncpy(password, optarg, sizeof(password));
1063 password[sizeof(password)-1] = 0;
1065 /* XXX: find better way of cleaning up ps(1) */
1066 memset(optarg, 0, strlen(optarg));
1069 autodetect_frag_size = 0;
1070 max_downstream_frag_size = atoi(optarg);
1078 check_superuser(usage);
1085 nameserv_addr = get_resolvconf_addr();
1086 topdomain = strdup(argv[0]);
1089 nameserv_addr = argv[0];
1090 topdomain = strdup(argv[1]);
1097 if (max_downstream_frag_size < 1 || max_downstream_frag_size > 0xffff) {
1098 warnx("Use a max frag size between 1 and 65535 bytes.\n");
1103 set_nameserver(nameserv_addr);
1105 if(strlen(topdomain) <= 128) {
1106 if(check_topdomain(topdomain)) {
1107 warnx("Topdomain contains invalid characters.\n");
1112 warnx("Use a topdomain max 128 chars long.\n");
1117 if (username != NULL) {
1119 if ((pw = getpwnam(username)) == NULL) {
1120 warnx("User %s does not exist!\n", username);
1127 if (strlen(password) == 0)
1128 read_password(password, sizeof(password));
1130 if ((tun_fd = open_tun(device)) == -1)
1132 if ((dns_fd = open_dns(0, INADDR_ANY)) == -1)
1135 signal(SIGINT, sighandler);
1136 signal(SIGTERM, sighandler);
1138 if(handshake(dns_fd, autodetect_frag_size, max_downstream_frag_size))
1141 fprintf(stderr, "Sending queries for %s to %s\n", topdomain, nameserv_addr);
1143 if (foreground == 0)
1146 if (newroot != NULL)
1149 if (username != NULL) {
1152 gids[0] = pw->pw_gid;
1153 if (setgroups(1, gids) < 0 || setgid(pw->pw_gid) < 0 || setuid(pw->pw_uid) < 0) {
1154 warnx("Could not switch to user %s!\n", username);
1161 downstream_seqno = 0;
1162 downstream_fragment = 0;
1164 down_ack_fragment = 0;
1166 tunnel(tun_fd, dns_fd);