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.
24 #include <netinet/in.h>
25 #include <sys/types.h>
26 #include <sys/param.h>
28 #include <sys/socket.h>
33 #include <arpa/inet.h>
35 #include <arpa/nameser.h>
37 #include <arpa/nameser8_compat.h>
49 static void send_ping(int fd);
50 static void send_chunk(int fd);
51 static int build_hostname(char *buf, size_t buflen,
52 const char *data, const size_t datalen,
53 const char *topdomain, struct encoder *encoder);
55 static int running = 1;
56 static char password[33];
58 static struct sockaddr_in nameserv;
59 static char *topdomain;
61 static uint16_t rand_seed;
62 static int downstream_seqno;
63 static int downstream_fragment;
64 static int down_ack_seqno;
65 static int down_ack_fragment;
67 static int max_downstream_frag_size;
68 static int autodetect_frag_size;
70 /* Current up/downstream IP packet */
71 static struct packet outpkt;
72 static struct packet inpkt;
74 /* My userid at the server */
77 /* DNS id for next packet */
78 static uint16_t chunkid;
80 /* Base32 encoder used for non-data packets */
81 static struct encoder *b32;
83 /* The encoder used for data packets
84 * Defaults to Base32, can be changed after handshake */
85 static struct encoder *dataenc;
87 /* result of case preservation check done after login */
88 static int case_preserved;
90 #if !defined(BSD) && !defined(__GLIBC__)
91 static char *__progname;
101 send_query(int fd, char *hostname)
110 len = dns_encode(packet, sizeof(packet), &q, QR_QUERY, hostname, strlen(hostname));
112 sendto(fd, packet, len, 0, (struct sockaddr*)&nameserv, sizeof(nameserv));
116 send_packet(int fd, char cmd, const char *data, const size_t datalen)
122 build_hostname(buf + 1, sizeof(buf) - 1, data, datalen, topdomain, b32);
127 build_hostname(char *buf, size_t buflen,
128 const char *data, const size_t datalen,
129 const char *topdomain, struct encoder *encoder)
135 space = MIN(0xFF, buflen) - strlen(topdomain) - 5;
136 if (!encoder->places_dots())
137 space -= (space / 57); /* space for dots */
139 memset(buf, 0, buflen);
141 encsize = encoder->encode(buf, &space, data, datalen);
143 if (!encoder->places_dots())
144 inline_dotify(buf, buflen);
152 strncpy(b, topdomain, strlen(topdomain)+1);
160 return (outpkt.len != 0);
164 read_dns(int fd, char *buf, int buflen)
166 struct sockaddr_in from;
173 addrlen = sizeof(struct sockaddr);
174 if ((r = recvfrom(fd, data, sizeof(data), 0,
175 (struct sockaddr*)&from, &addrlen)) == -1) {
180 rv = dns_decode(buf, buflen, &q, QR_ANSWER, data, r);
182 /* decode the data header, update seqno and frag before next request */
184 downstream_seqno = (buf[1] >> 5) & 7;
185 downstream_fragment = (buf[1] >> 1) & 15;
190 if (chunkid == q.id) {
191 /* Got ACK on sent packet */
192 outpkt.offset += outpkt.sentlen;
193 if (outpkt.offset == outpkt.len) {
194 /* Packet completed */
199 /* If the ack contains unacked frag number but no data,
200 * send a ping to ack the frag number and get more data*/
202 downstream_seqno != down_ack_seqno ||
203 downstream_fragment != down_ack_fragment
220 tunnel_tun(int tun_fd, int dns_fd)
222 unsigned long outlen;
228 if ((read = read_tun(tun_fd, in, sizeof(in))) <= 0)
231 outlen = sizeof(out);
233 compress2((uint8_t*)out, &outlen, (uint8_t*)in, inlen, 9);
235 memcpy(outpkt.data, out, MIN(outlen, sizeof(outpkt.data)));
248 tunnel_dns(int tun_fd, int dns_fd)
250 unsigned long datalen;
254 if ((read = read_dns(dns_fd, buf, sizeof(buf))) <= 2)
257 if (downstream_seqno != inpkt.seqno) {
259 inpkt.seqno = downstream_seqno;
260 inpkt.fragment = downstream_fragment;
262 } else if (downstream_fragment <= inpkt.fragment) {
263 /* Duplicate fragment */
266 inpkt.fragment = downstream_fragment;
268 datalen = MIN(read - 2, sizeof(inpkt.data) - inpkt.len);
270 /* Skip 2 byte data header and append to packet */
271 memcpy(&inpkt.data[inpkt.len], &buf[2], datalen);
272 inpkt.len += datalen;
274 if (buf[1] & 1) { /* If last fragment flag is set */
275 /* Uncompress packet and send to tun */
276 datalen = sizeof(buf);
277 if (uncompress((uint8_t*)buf, &datalen, (uint8_t*) inpkt.data, inpkt.len) == Z_OK) {
278 write_tun(tun_fd, buf, datalen);
283 /* If we have nothing to send, send a ping to get more data */
291 tunnel(int tun_fd, int dns_fd)
307 FD_SET(tun_fd, &fds);
309 FD_SET(dns_fd, &fds);
311 i = select(MAX(tun_fd, dns_fd) + 1, &fds, NULL, NULL, &tv);
319 if (i == 0) /* timeout */
322 if (FD_ISSET(tun_fd, &fds)) {
323 if (tunnel_tun(tun_fd, dns_fd) <= 0)
326 if (FD_ISSET(dns_fd, &fds)) {
327 if (tunnel_dns(tun_fd, dns_fd) <= 0)
339 char hex[] = "0123456789ABCDEF";
347 avail = outpkt.len - outpkt.offset;
349 outpkt.sentlen = build_hostname(buf + 4, sizeof(buf) - 4, p, avail, topdomain, dataenc);
351 /* Build upstream data header (see doc/proto_xxxxxxxx.txt) */
353 buf[0] = hex[userid & 15]; /* First byte is 4 bits userid */
355 code = ((outpkt.seqno & 7) << 2) | ((outpkt.fragment & 15) >> 2);
356 buf[1] = b32_5to8(code); /* Second byte is 3 bits seqno, 2 upper bits fragment count */
358 code = ((outpkt.fragment & 3) << 3) | (downstream_seqno & 7);
359 buf[2] = b32_5to8(code); /* Third byte is 2 bits lower fragment count, 3 bits downstream packet seqno */
361 code = ((downstream_fragment & 15) << 1) | (outpkt.sentlen == avail);
362 buf[3] = b32_5to8(code); /* Fourth byte is 4 bits downstream fragment count, 1 bit last frag flag */
364 down_ack_seqno = downstream_seqno;
365 down_ack_fragment = downstream_fragment;
372 send_login(int fd, char *login, int len)
376 memset(data, 0, sizeof(data));
378 memcpy(&data[1], login, MIN(len, 16));
380 data[17] = (rand_seed >> 8) & 0xff;
381 data[18] = (rand_seed >> 0) & 0xff;
385 send_packet(fd, 'L', data, sizeof(data));
400 data[1] = ((downstream_seqno & 7) << 4) | (downstream_fragment & 15);
401 data[2] = (rand_seed >> 8) & 0xff;
402 data[3] = (rand_seed >> 0) & 0xff;
404 down_ack_seqno = downstream_seqno;
405 down_ack_fragment = downstream_fragment;
409 send_packet(fd, 'P', data, sizeof(data));
413 send_fragsize_probe(int fd, int fragsize)
418 /* build a large query domain which is random and maximum size */
419 memset(probedata, MIN(1, rand_seed & 0xff), sizeof(probedata));
420 probedata[1] = MIN(1, (rand_seed >> 8) & 0xff);
422 build_hostname(buf + 4, sizeof(buf) - 4, probedata, sizeof(probedata), topdomain, dataenc);
426 buf[0] = 'r'; /* Probe downstream fragsize packet */
427 buf[1] = b32_5to8((userid << 1) | (fragsize & 1024));
428 buf[2] = b32_5to8((fragsize >> 5) & 31);
429 buf[3] = b32_5to8(fragsize & 31);
435 send_set_downstream_fragsize(int fd, int fragsize)
440 data[1] = (fragsize & 0xff00) >> 8;
441 data[2] = (fragsize & 0x00ff);
442 data[3] = (rand_seed >> 8) & 0xff;
443 data[4] = (rand_seed >> 0) & 0xff;
447 send_packet(fd, 'N', data, sizeof(data));
451 send_version(int fd, uint32_t version)
455 data[0] = (version >> 24) & 0xff;
456 data[1] = (version >> 16) & 0xff;
457 data[2] = (version >> 8) & 0xff;
458 data[3] = (version >> 0) & 0xff;
460 data[4] = (rand_seed >> 8) & 0xff;
461 data[5] = (rand_seed >> 0) & 0xff;
465 send_packet(fd, 'V', data, sizeof(data));
469 send_case_check(int fd)
471 /* The '+' plus character is not allowed according to RFC.
472 * Expect to get SERVFAIL or similar if it is rejected.
474 char buf[512] = "zZ+-aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyY1234.";
476 strncat(buf, topdomain, 512 - strlen(buf));
481 send_codec_switch(int fd, int userid, int bits)
483 char buf[512] = "S__.";
484 buf[1] = b32_5to8(userid);
485 buf[2] = b32_5to8(bits);
487 strncat(buf, topdomain, 512 - strlen(buf));
492 handshake(int dns_fd)
507 for (i = 0; running && i < 5; i++) {
511 send_version(dns_fd, VERSION);
514 FD_SET(dns_fd, &fds);
516 r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
519 read = read_dns(dns_fd, in, sizeof(in));
523 warn("handshake read");
525 /* if read < 0 then warning has been printed already */
530 payload = (((in[4] & 0xff) << 24) |
531 ((in[5] & 0xff) << 16) |
532 ((in[6] & 0xff) << 8) |
535 if (strncmp("VACK", in, 4) == 0) {
539 printf("Version ok, both using protocol v 0x%08x. You are user #%d\n", VERSION, userid);
541 } else if (strncmp("VNAK", in, 4) == 0) {
542 warnx("You use protocol v 0x%08x, server uses v 0x%08x. Giving up",
545 } else if (strncmp("VFUL", in, 4) == 0) {
546 warnx("Server full, all %d slots are taken. Try again later", payload);
550 warnx("did not receive proper login challenge");
553 printf("Retrying version check...\n");
555 errx(1, "couldn't connect to server");
559 login_calculate(login, 16, password, seed);
561 for (i=0; running && i<5 ;i++) {
565 send_login(dns_fd, login, 16);
568 FD_SET(dns_fd, &fds);
570 r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
573 read = read_dns(dns_fd, in, sizeof(in));
582 if (strncmp("LNAK", in, 4) == 0) {
583 printf("Bad password\n");
585 } else if (sscanf(in, "%64[^-]-%64[^-]-%d-%d",
586 server, client, &mtu, &netmask) == 4) {
590 if (tun_setip(client, netmask) == 0 &&
591 tun_setmtu(mtu) == 0) {
592 goto perform_case_check;
594 warnx("Received handshake with bad data");
597 printf("Received bad handshake\n");
602 printf("Retrying login...\n");
604 warnx("couldn't login to server");
609 for (i=0; running && i<5 ;i++) {
613 send_case_check(dns_fd);
616 FD_SET(dns_fd, &fds);
618 r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
621 read = read_dns(dns_fd, in, sizeof(in));
624 if (in[0] == 'z' || in[0] == 'Z') {
625 if (read < (27 * 2)) {
626 printf("Received short case check reply. Will use base32 encoder\n");
631 /* TODO enhance this, base128 is probably also possible */
633 for (k = 0; k < 27 && case_preserved; k += 2) {
634 if (in[k] == in[k+1]) {
635 /* test string: zZ+-aAbBcCdDeE... */
642 printf("Received bad case check reply\n");
645 printf("Got error on case check, will use base32\n");
650 printf("Retrying case check...\n");
653 printf("No reply on case check, continuing\n");
656 goto autodetect_max_fragsize;
658 dataenc = get_base64_encoder();
659 printf("Switching to %s codec\n", dataenc->name);
660 /* Send to server that this user will use base64 from now on */
661 for (i=0; running && i<5 ;i++) {
666 bits = 6; /* base64 = 6 bits per byte */
668 send_codec_switch(dns_fd, userid, bits);
671 FD_SET(dns_fd, &fds);
673 r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
676 read = read_dns(dns_fd, in, sizeof(in));
679 if (strncmp("BADLEN", in, 6) == 0) {
680 printf("Server got bad message length. ");
682 } else if (strncmp("BADIP", in, 5) == 0) {
683 printf("Server rejected sender IP address. ");
685 } else if (strncmp("BADCODEC", in, 8) == 0) {
686 printf("Server rejected the selected codec. ");
689 in[read] = 0; /* zero terminate */
690 printf("Server switched to codec %s\n", in);
691 goto autodetect_max_fragsize;
694 printf("Retrying codec switch...\n");
696 printf("No reply from server on codec switch. ");
698 printf("Falling back to base32\n");
699 dataenc = get_base32_encoder();
700 autodetect_max_fragsize:
701 if (autodetect_frag_size) {
702 int proposed_fragsize = 768;
704 max_downstream_frag_size = 0;
705 printf("Autoprobing max downstream fragment size... (skip with -m fragsize)\n");
706 while (running && range > 0 && (range >= 8 || !max_downstream_frag_size)) {
707 for (i=0; running && i<3 ;i++) {
710 send_fragsize_probe(dns_fd, proposed_fragsize);
713 FD_SET(dns_fd, &fds);
715 r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
718 read = read_dns(dns_fd, in, sizeof(in));
722 int acked_fragsize = ((in[0] & 0xff) << 8) | (in[1] & 0xff);
723 if (acked_fragsize == proposed_fragsize) {
724 printf("%d ok.. ", acked_fragsize);
726 max_downstream_frag_size = acked_fragsize;
728 proposed_fragsize += range;
734 printf("%d not ok.. ", proposed_fragsize);
737 proposed_fragsize -= range;
741 warnx("stopped while autodetecting fragment size (Try probing manually with -m)");
745 /* Tried all the way down to 2 and found no good size */
747 warnx("found no accepted fragment size. (Try probing manually with -m)");
750 printf("will use %d\n", max_downstream_frag_size);
752 printf("Setting downstream fragment size to max %d...\n", max_downstream_frag_size);
753 for (i=0; running && i<5 ;i++) {
757 send_set_downstream_fragsize(dns_fd, max_downstream_frag_size);
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));
768 int accepted_fragsize;
770 if (strncmp("BADFRAG", in, 7) == 0) {
771 printf("Server rejected fragsize. Keeping default.");
773 } else if (strncmp("BADIP", in, 5) == 0) {
774 printf("Server rejected sender IP address.\n");
778 accepted_fragsize = ((in[0] & 0xff) << 8) | (in[1] & 0xff);
782 printf("Retrying set fragsize...\n");
784 printf("No reply from server when setting fragsize. Keeping default.\n");
790 get_resolvconf_addr()
792 static char addr[16];
799 if ((fp = fopen("/etc/resolv.conf", "r")) == NULL)
800 err(1, "/etc/resolve.conf");
802 while (feof(fp) == 0) {
803 fgets(buf, sizeof(buf), fp);
805 if (sscanf(buf, "nameserver %15s", addr) == 1) {
817 set_nameserver(const char *cp)
821 if (inet_aton(cp, &addr) != 1)
822 errx(1, "error parsing nameserver address: '%s'", cp);
824 memset(&nameserv, 0, sizeof(nameserv));
825 nameserv.sin_family = AF_INET;
826 nameserv.sin_port = htons(53);
827 nameserv.sin_addr = addr;
832 extern char *__progname;
834 printf("Usage: %s [-v] [-h] [-f] [-u user] [-t chrootdir] [-d device] "
835 "[-P password] [-m maxfragsize] [nameserver] topdomain\n", __progname);
841 extern char *__progname;
843 printf("iodine IP over DNS tunneling client\n");
844 printf("Usage: %s [-v] [-h] [-f] [-u user] [-t chrootdir] [-d device] "
845 "[-P password] [-m maxfragsize] [nameserver] topdomain\n", __progname);
846 printf(" -v to print version info and exit\n");
847 printf(" -h to print this help and exit\n");
848 printf(" -f to keep running in foreground\n");
849 printf(" -u name to drop privileges and run as user 'name'\n");
850 printf(" -t dir to chroot to directory dir\n");
851 printf(" -d device to set tunnel device name\n");
852 printf(" -P password used for authentication (max 32 chars will be used)\n");
853 printf(" -m maxfragsize, to limit size of downstream packets\n");
854 printf("nameserver is the IP number of the relaying nameserver, if absent /etc/resolv.conf is used\n");
855 printf("topdomain is the FQDN that is delegated to the tunnel endpoint.\n");
862 printf("iodine IP over DNS tunneling client\n");
863 printf("version: 0.5.0 from 2009-01-23\n");
869 main(int argc, char **argv)
881 memset(password, 0, 33);
891 autodetect_frag_size = 1;
892 max_downstream_frag_size = 3072;
894 b32 = get_base32_encoder();
895 dataenc = get_base32_encoder();
897 #if !defined(BSD) && !defined(__GLIBC__)
898 __progname = strrchr(argv[0], '/');
899 if (__progname == NULL)
900 __progname = argv[0];
905 while ((choice = getopt(argc, argv, "vfhu:t:d:P:m:")) != -1) {
928 strncpy(password, optarg, sizeof(password));
929 password[sizeof(password)-1] = 0;
931 /* XXX: find better way of cleaning up ps(1) */
932 memset(optarg, 0, strlen(optarg));
935 autodetect_frag_size = 0;
936 max_downstream_frag_size = atoi(optarg);
944 if (geteuid() != 0) {
945 warnx("Run as root and you'll be happy.\n");
955 nameserv_addr = get_resolvconf_addr();
956 topdomain = strdup(argv[0]);
959 nameserv_addr = argv[0];
960 topdomain = strdup(argv[1]);
967 if (max_downstream_frag_size < 1 || max_downstream_frag_size > 0xffff) {
968 warnx("Use a max frag size between 1 and 65535 bytes.\n");
973 set_nameserver(nameserv_addr);
975 if(strlen(topdomain) <= 128) {
976 if(check_topdomain(topdomain)) {
977 warnx("Topdomain contains invalid characters.\n");
982 warnx("Use a topdomain max 128 chars long.\n");
987 if (username != NULL) {
988 if ((pw = getpwnam(username)) == NULL) {
989 warnx("User %s does not exist!\n", username);
995 if (strlen(password) == 0)
996 read_password(password, sizeof(password));
998 if ((tun_fd = open_tun(device)) == -1)
1000 if ((dns_fd = open_dns(0, INADDR_ANY)) == -1)
1003 signal(SIGINT, sighandler);
1004 signal(SIGTERM, sighandler);
1006 if(handshake(dns_fd))
1009 printf("Sending queries for %s to %s\n", topdomain, nameserv_addr);
1011 if (foreground == 0)
1014 if (newroot != NULL)
1017 if (username != NULL) {
1019 gids[0] = pw->pw_gid;
1020 if (setgroups(1, gids) < 0 || setgid(pw->pw_gid) < 0 || setuid(pw->pw_uid) < 0) {
1021 warnx("Could not switch to user %s!\n", username);
1027 downstream_seqno = 0;
1028 downstream_fragment = 0;
1030 down_ack_fragment = 0;
1032 tunnel(tun_fd, dns_fd);