Changeset 58d961
- Timestamp:
- 08/06/09 21:48:55 (4 years ago)
- Branches:
- master
- Children:
- e5370a
- Parents:
- 02c06d
- git-author:
- Erik Ekman <yarrick@…> (08/06/09 21:48:55)
- git-committer:
- Erik Ekman <erik@…> (02/04/12 20:34:02)
- Location:
- src
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
src/common.h
rd5acb5 r58d961 22 22 #define RAW_HDR_IDENT_LEN 3 23 23 #define RAW_HDR_CMD 3 24 #define RAW_HDR_CMD_LOGIN 0x01 25 #define RAW_HDR_CMD_DATA 0x02 24 #define RAW_HDR_CMD_LOGIN 0x10 25 #define RAW_HDR_CMD_DATA 0x20 26 27 #define RAW_HDR_CMD_MASK 0xF0 28 #define RAW_HDR_USR_MASK 0x0F 29 #define RAW_HDR_GET_CMD(x) ((x)[RAW_HDR_CMD] & RAW_HDR_CMD_MASK) 30 #define RAW_HDR_GET_USR(x) ((x)[RAW_HDR_CMD] & RAW_HDR_USR_MASK) 26 31 extern const unsigned char raw_header[RAW_HDR_LEN]; 27 32 … … 86 91 }; 87 92 93 enum connection { 94 CONN_RAW_UDP, 95 CONN_DNS_NULL, 96 CONN_MAX 97 }; 98 88 99 void check_superuser(void (*usage_fn)(void)); 89 100 int open_dns(int, in_addr_t); -
src/iodine.c
r02c06d r58d961 61 61 static void send_ping(int fd); 62 62 static void send_chunk(int fd); 63 static void send_raw_data(int fd); 63 64 static int build_hostname(char *buf, size_t buflen, 64 65 const char *data, const size_t datalen, … … 95 96 static struct encoder *dataenc; 96 97 98 /* My connection mode */ 99 static enum connection conn; 100 97 101 #if !defined(BSD) && !defined(__GLIBC__) 98 102 static char *__progname; … … 121 125 122 126 static void 123 send_raw(int fd, char *buf, int buflen, int cmd)127 send_raw(int fd, char *buf, int buflen, int user, int cmd) 124 128 { 125 129 char packet[4096]; … … 132 136 133 137 len += RAW_HDR_LEN; 134 packet[RAW_HDR_CMD] = cmd ;138 packet[RAW_HDR_CMD] = cmd | (user & 0x0F); 135 139 136 140 sendto(fd, packet, len, 0, (struct sockaddr*)&raw_serv, sizeof(raw_serv)); … … 264 268 outpkt.fragment = 0; 265 269 266 send_chunk(dns_fd); 270 if (conn == CONN_DNS_NULL) { 271 send_chunk(dns_fd); 272 } else { 273 send_raw_data(dns_fd); 274 } 267 275 268 276 return read; … … 328 336 329 337 FD_ZERO(&fds); 330 if ( !is_sending()) {338 if ((!is_sending()) || conn == CONN_RAW_UDP) { 331 339 FD_SET(tun_fd, &fds); 332 340 } … … 341 349 err(1, "select"); 342 350 343 if (i == 0 ) /* timeout */351 if (i == 0 && conn == CONN_DNS_NULL) /* timeout */ 344 352 send_ping(dns_fd); 345 353 else { … … 359 367 360 368 static void 369 send_raw_data(int dns_fd) 370 { 371 send_raw(dns_fd, outpkt.data, outpkt.len, userid, RAW_HDR_CMD_DATA); 372 } 373 374 static void 361 375 send_chunk(int fd) 362 376 { … … 508 522 send_raw_udp_login(int dns_fd, int userid, int seed) 509 523 { 510 char buf[1 7];524 char buf[16]; 511 525 login_calculate(buf, 16, password, seed + 1); 512 buf[16] = userid; 513 514 send_raw(dns_fd, buf, sizeof(buf), RAW_HDR_CMD_LOGIN); 526 527 send_raw(dns_fd, buf, sizeof(buf), userid, RAW_HDR_CMD_LOGIN); 515 528 } 516 529 … … 716 729 if (!remoteaddr) { 717 730 fprintf(stderr, " failed to get IP.\n"); 718 return 1;731 return 0; 719 732 } 720 733 fprintf(stderr, " at %s: ", inet_ntoa(server)); … … 744 757 /* recv() needed for windows, dont change to read() */ 745 758 len = recv(dns_fd, in, sizeof(in), 0); 746 if (len >= (1 7+ RAW_HDR_LEN)) {759 if (len >= (16 + RAW_HDR_LEN)) { 747 760 char hash[16]; 748 761 login_calculate(hash, 16, password, seed - 1); 749 762 if (memcmp(in, raw_header, RAW_HDR_IDENT_LEN) == 0 750 && in[RAW_HDR_CMD] == RAW_HDR_CMD_LOGIN 751 && memcmp(&in[RAW_HDR_LEN], hash, sizeof(hash)) == 0 752 && in[16 + RAW_HDR_LEN] == userid) { 763 && RAW_HDR_GET_CMD(in) == RAW_HDR_CMD_LOGIN 764 && memcmp(&in[RAW_HDR_LEN], hash, sizeof(hash)) == 0) { 753 765 754 766 fprintf(stderr, "OK\n"); 755 return 0;767 return 1; 756 768 } 757 769 } … … 762 774 763 775 fprintf(stderr, "failed\n"); 764 return 1;776 return 0; 765 777 } 766 778 … … 1017 1029 } 1018 1030 1019 handshake_raw_udp(dns_fd, seed); 1020 1021 case_preserved = handshake_case_check(dns_fd); 1022 1023 if (case_preserved) { 1024 handshake_switch_codec(dns_fd); 1025 } 1026 1027 if (autodetect_frag_size) { 1028 fragsize = handshake_autoprobe_fragsize(dns_fd); 1029 if (!fragsize) { 1030 return 1; 1031 } 1032 } 1033 1034 handshake_set_fragsize(dns_fd, fragsize); 1031 if (handshake_raw_udp(dns_fd, seed)) { 1032 conn = CONN_RAW_UDP; 1033 } else { 1034 case_preserved = handshake_case_check(dns_fd); 1035 1036 if (case_preserved) { 1037 handshake_switch_codec(dns_fd); 1038 } 1039 1040 if (autodetect_frag_size) { 1041 fragsize = handshake_autoprobe_fragsize(dns_fd); 1042 if (!fragsize) { 1043 return 1; 1044 } 1045 } 1046 1047 handshake_set_fragsize(dns_fd, fragsize); 1048 } 1035 1049 1036 1050 return 0; … … 1179 1193 b32 = get_base32_encoder(); 1180 1194 dataenc = get_base32_encoder(); 1195 conn = CONN_DNS_NULL; 1181 1196 1182 1197 retval = 0; … … 1313 1328 } 1314 1329 1315 fprintf(stderr, "Sending queries for %s to %s\n", topdomain, nameserv_addr); 1330 if (conn == CONN_DNS_NULL) { 1331 fprintf(stderr, "Sending queries for %s to %s\n", topdomain, nameserv_addr); 1332 } else { 1333 fprintf(stderr, "Sending raw traffic directly to %s\n", inet_ntoa(raw_serv.sin_addr)); 1334 } 1316 1335 1317 1336 if (foreground == 0) -
src/iodined.c
ra62ae8 r58d961 86 86 #endif 87 87 88 static int read_dns(int, struct query *);88 static int read_dns(int, int, struct query *); 89 89 static void write_dns(int, struct query *, char *, int); 90 static void handle_full_packet(int, int); 90 91 91 92 static void … … 296 297 { 297 298 struct in_addr tempip; 298 struct ip *hdr;299 unsigned long outlen;300 299 char in[512]; 301 300 char logindata[16]; … … 304 303 char *tmp[2]; 305 304 int userid; 306 int touser;307 305 int version; 308 306 int code; … … 590 588 591 589 if (lastfrag & 1) { /* packet is complete */ 592 int ret; 593 outlen = sizeof(out); 594 ret = uncompress((uint8_t*)out, &outlen, 595 (uint8_t*)users[userid].inpacket.data, users[userid].inpacket.len); 596 597 if (ret == Z_OK) { 598 hdr = (struct ip*) (out + 4); 599 touser = find_user_by_ip(hdr->ip_dst.s_addr); 600 601 if (touser == -1) { 602 /* send the uncompressed packet to tun device */ 603 write_tun(tun_fd, out, outlen); 604 } else { 605 /* send the compressed packet to other client 606 * if another packet is queued, throw away this one. TODO build queue */ 607 if (users[touser].outpacket.len == 0) { 608 memcpy(users[touser].outpacket.data, users[userid].inpacket.data, users[userid].inpacket.len); 609 users[touser].outpacket.len = users[userid].inpacket.len; 610 } 611 } 612 } else { 613 fprintf(stderr, "Discarded data, uncompress() result: %d\n", ret); 614 } 615 users[userid].inpacket.len = users[userid].inpacket.offset = 0; 590 handle_full_packet(tun_fd, userid); 616 591 } 617 592 /* Update seqno and maybe send immediate response packet */ … … 731 706 int inside_topdomain; 732 707 733 if ((read = read_dns(dns_fd, &q)) <= 0)708 if ((read = read_dns(dns_fd, tun_fd, &q)) <= 0) 734 709 return 0; 735 710 … … 821 796 } 822 797 } else { 823 if (FD_ISSET(tun_fd, &fds)) {798 if (FD_ISSET(tun_fd, &fds)) { 824 799 tunnel_tun(tun_fd, dns_fd); 825 800 continue; 826 801 } 827 if (FD_ISSET(dns_fd, &fds)) {802 if (FD_ISSET(dns_fd, &fds)) { 828 803 tunnel_dns(tun_fd, dns_fd, bind_fd); 829 804 continue; 830 805 } 831 if (FD_ISSET(bind_fd, &fds)) {806 if (FD_ISSET(bind_fd, &fds)) { 832 807 tunnel_bind(bind_fd, dns_fd); 833 808 continue; … … 840 815 841 816 static void 842 send_raw(int fd, char *buf, int buflen, int cmd, struct query *q) 817 handle_full_packet(int tun_fd, int userid) 818 { 819 unsigned long outlen; 820 char out[64*1024]; 821 int touser; 822 int ret; 823 824 outlen = sizeof(out); 825 ret = uncompress((uint8_t*)out, &outlen, 826 (uint8_t*)users[userid].inpacket.data, users[userid].inpacket.len); 827 828 if (ret == Z_OK) { 829 struct ip *hdr; 830 831 hdr = (struct ip*) (out + 4); 832 touser = find_user_by_ip(hdr->ip_dst.s_addr); 833 834 if (touser == -1) { 835 /* send the uncompressed packet to tun device */ 836 write_tun(tun_fd, out, outlen); 837 } else { 838 /* send the compressed packet to other client 839 * if another packet is queued, throw away this one. TODO build queue */ 840 if (users[touser].outpacket.len == 0) { 841 memcpy(users[touser].outpacket.data, users[userid].inpacket.data, users[userid].inpacket.len); 842 users[touser].outpacket.len = users[userid].inpacket.len; 843 } 844 } 845 } else { 846 fprintf(stderr, "Discarded data, uncompress() result: %d\n", ret); 847 } 848 users[userid].inpacket.len = users[userid].inpacket.offset = 0; 849 } 850 851 static void 852 send_raw(int fd, char *buf, int buflen, int user, int cmd, struct query *q) 843 853 { 844 854 char packet[4096]; … … 851 861 852 862 len += RAW_HDR_LEN; 853 packet[RAW_HDR_CMD] = cmd ;863 packet[RAW_HDR_CMD] = cmd | (user & 0x0F); 854 864 855 865 sendto(fd, packet, len, 0, &q->from, q->fromlen); … … 857 867 858 868 static void 859 handle_raw_login(char *packet, int len, struct query *q, int fd) 860 { 861 int userid; 869 handle_raw_login(char *packet, int len, struct query *q, int fd, int userid) 870 { 862 871 char myhash[16]; 863 872 864 if (len < 17) return; 865 866 userid = packet[16]; 873 if (len < 16) return; 874 867 875 if (userid < 0 || userid > created_users) return; 868 876 if (!users[userid].active) return; 869 877 878 /* User sends hash of seed + 1 */ 870 879 login_calculate(myhash, 16, password, users[userid].seed + 1); 871 880 if (memcmp(packet, myhash, 16) == 0) { 881 struct sockaddr_in *tempin; 882 883 /* Update query and time info for user */ 884 users[userid].last_pkt = time(NULL); 885 memcpy(&(users[userid].q), q, sizeof(struct query)); 886 887 /* Store remote IP number */ 888 tempin = (struct sockaddr_in *) &(q->from); 889 memcpy(&(users[userid].host), &(tempin->sin_addr), sizeof(struct in_addr)); 890 872 891 /* Correct hash, reply with hash of seed - 1 */ 892 user_set_conn_type(userid, CONN_RAW_UDP); 873 893 users[userid].last_pkt = time(NULL); 874 894 login_calculate(myhash, 16, password, users[userid].seed - 1); 875 memcpy(packet, myhash, 16); 876 send_raw(fd, packet, 17, RAW_HDR_CMD_LOGIN, q); 877 } 895 send_raw(fd, myhash, 16, userid, RAW_HDR_CMD_LOGIN, q); 896 } 897 } 898 899 static void 900 handle_raw_data(char *packet, int len, struct query *q, int dns_fd, int tun_fd, int userid) 901 { 902 if (check_user_and_ip(userid, q) != 0) { 903 return; 904 } 905 906 /* Update query and time info for user */ 907 users[userid].last_pkt = time(NULL); 908 memcpy(&(users[userid].q), q, sizeof(struct query)); 909 910 /* copy to packet buffer, update length */ 911 users[userid].inpacket.offset = 0; 912 memcpy(users[userid].inpacket.data, packet, len); 913 users[userid].inpacket.len = len; 914 915 if (debug >= 1) { 916 fprintf(stderr, "IN pkt raw, total %d, from user %d\n", 917 users[userid].inpacket.len, userid); 918 } 919 920 handle_full_packet(tun_fd, userid); 878 921 } 879 922 880 923 static int 881 raw_decode(char *packet, int len, struct query *q, int fd) 882 { 924 raw_decode(char *packet, int len, struct query *q, int dns_fd, int tun_fd) 925 { 926 int raw_user; 927 883 928 /* minimum length */ 884 929 if (len < RAW_HDR_LEN) return 0; … … 886 931 if (memcmp(packet, raw_header, RAW_HDR_IDENT_LEN)) return 0; 887 932 888 if (packet[RAW_HDR_CMD] == RAW_HDR_CMD_LOGIN) { 889 handle_raw_login(&packet[RAW_HDR_LEN], len - RAW_HDR_LEN, q, fd); 890 } else { 891 warnx("Unhandled raw command %02X\n", packet[RAW_HDR_CMD]); 933 raw_user = RAW_HDR_GET_USR(packet); 934 printf("raw %02x\n", packet[RAW_HDR_CMD]); 935 switch (RAW_HDR_GET_CMD(packet)) { 936 case RAW_HDR_CMD_LOGIN: 937 /* Login challenge */ 938 handle_raw_login(&packet[RAW_HDR_LEN], len - RAW_HDR_LEN, q, dns_fd, raw_user); 939 break; 940 case RAW_HDR_CMD_DATA: 941 /* Data packet */ 942 handle_raw_data(&packet[RAW_HDR_LEN], len - RAW_HDR_LEN, q, dns_fd, tun_fd, raw_user); 943 break; 944 default: 945 warnx("Unhandled raw command %02X from user %d", RAW_HDR_GET_CMD(packet), raw_user); 946 break; 892 947 } 893 948 return 1; … … 895 950 896 951 static int 897 read_dns(int fd, struct query *q)952 read_dns(int fd, int tun_fd, struct query *q) /* FIXME: tun_fd is because of raw_decode() below */ 898 953 { 899 954 struct sockaddr_in from; … … 930 985 931 986 /* TODO do not handle raw packets here! */ 932 if (raw_decode(packet, r, q, fd )) {987 if (raw_decode(packet, r, q, fd, tun_fd)) { 933 988 return 0; 934 989 } … … 1178 1233 1179 1234 topdomain = strdup(argv[1]); 1180 if (strlen(topdomain) <= 128) {1235 if (strlen(topdomain) <= 128) { 1181 1236 if(check_topdomain(topdomain)) { 1182 1237 warnx("Topdomain contains invalid characters."); -
src/user.c
r541959 r58d961 91 91 users[i].out_acked_fragment = 0; 92 92 users[i].fragsize = 4096; 93 users[i].conn = CONN_DNS_NULL; 93 94 } 94 95 … … 162 163 users[i].active = 1; 163 164 users[i].last_pkt = time(NULL); 165 users[i].fragsize = 4096; 166 users[i].conn = CONN_DNS_NULL; 164 167 ret = i; 165 168 break; … … 177 180 users[userid].encoder = enc; 178 181 } 182 183 void 184 user_set_conn_type(int userid, enum connection c) 185 { 186 if (userid < 0 || userid >= USERS) 187 return; 188 189 if (c < 0 || c >= CONN_MAX) 190 return; 191 192 users[userid].conn = c; 193 } 194 -
src/user.h
rd4e077 r58d961 35 35 int out_acked_fragment; 36 36 int fragsize; 37 enum connection conn; 37 38 }; 38 39 … … 45 46 int find_available_user(); 46 47 void user_switch_codec(int userid, struct encoder *enc); 48 void user_set_conn_type(int userid, enum connection c); 47 49 48 50 #endif
Note: See TracChangeset
for help on using the changeset viewer.
