Changeset 27fdc2
- Timestamp:
- 08/16/09 14:30:26 (3 years ago)
- Branches:
- master
- Children:
- 807469
- Parents:
- a3757a
- git-author:
- Erik Ekman <yarrick@…> (08/16/09 14:30:26)
- git-committer:
- Erik Ekman <erik@…> (02/04/12 20:34:03)
- Location:
- src
- Files:
-
- 4 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Makefile
r24871f r27fdc2 1 1 COMMONOBJS = tun.o dns.o read.o encoding.o login.o base32.o base64.o md5.o common.o 2 CLIENTOBJS = iodine.o 2 CLIENTOBJS = iodine.o client.o util.o 3 3 CLIENT = ../bin/iodine 4 4 SERVEROBJS = iodined.o user.o fw_query.o -
src/iodine.c
r1137ac r27fdc2 25 25 #include <sys/time.h> 26 26 #include <fcntl.h> 27 #include <zlib.h>28 27 #include <time.h> 29 28 … … 32 31 #include <winsock2.h> 33 32 #else 34 #include <arpa/nameser.h>35 #ifdef DARWIN36 #include <arpa/nameser8_compat.h>37 #endif38 #include <sys/socket.h>39 #include <err.h>40 #include <arpa/inet.h>41 #include <netinet/in.h>42 33 #include <grp.h> 43 34 #include <pwd.h> 44 #include <netdb.h>45 35 #endif 46 36 47 37 #include "common.h" 48 #include "encoding.h"49 #include "base32.h"50 #include "base64.h"51 #include "dns.h"52 #include "login.h"53 38 #include "tun.h" 54 #include "version.h" 39 #include "client.h" 40 #include "util.h" 55 41 56 42 #ifdef WINDOWS32 … … 59 45 #endif 60 46 61 #define PING_TIMEOUT(t) ((t) >= (conn == CONN_DNS_NULL ? 1 : 20))62 63 static void send_ping(int fd);64 static void send_chunk(int fd);65 static void send_raw_data(int fd);66 static int build_hostname(char *buf, size_t buflen,67 const char *data, const size_t datalen,68 const char *topdomain, struct encoder *encoder);69 70 static int running = 1;71 static char password[33];72 73 static struct sockaddr_in nameserv;74 static struct sockaddr_in raw_serv;75 static char *topdomain;76 77 static uint16_t rand_seed;78 static int downstream_seqno;79 static int downstream_fragment;80 static int down_ack_seqno;81 static int down_ack_fragment;82 83 /* Current up/downstream IP packet */84 static struct packet outpkt;85 static struct packet inpkt;86 87 /* My userid at the server */88 static char userid;89 90 /* DNS id for next packet */91 static uint16_t chunkid;92 93 /* Base32 encoder used for non-data packets */94 static struct encoder *b32;95 96 /* The encoder used for data packets97 * Defaults to Base32, can be changed after handshake */98 static struct encoder *dataenc;99 100 /* My connection mode */101 static enum connection conn;102 103 47 #if !defined(BSD) && !defined(__GLIBC__) 104 48 static char *__progname; … … 108 52 sighandler(int sig) 109 53 { 110 running = 0; 111 } 112 113 static void 114 send_query(int fd, char *hostname) 115 { 116 char packet[4096]; 117 struct query q; 118 size_t len; 119 120 q.id = ++chunkid; 121 q.type = T_NULL; 122 123 len = dns_encode(packet, sizeof(packet), &q, QR_QUERY, hostname, strlen(hostname)); 124 125 sendto(fd, packet, len, 0, (struct sockaddr*)&nameserv, sizeof(nameserv)); 126 } 127 128 static void 129 send_raw(int fd, char *buf, int buflen, int user, int cmd) 130 { 131 char packet[4096]; 132 int len; 133 134 len = MIN(sizeof(packet) - RAW_HDR_LEN, buflen); 135 136 memcpy(packet, raw_header, RAW_HDR_LEN); 137 if (len) { 138 memcpy(&packet[RAW_HDR_LEN], buf, len); 139 } 140 141 len += RAW_HDR_LEN; 142 packet[RAW_HDR_CMD] = cmd | (user & 0x0F); 143 144 sendto(fd, packet, len, 0, (struct sockaddr*)&raw_serv, sizeof(raw_serv)); 145 } 146 147 static void 148 send_packet(int fd, char cmd, const char *data, const size_t datalen) 149 { 150 char buf[4096]; 151 152 buf[0] = cmd; 153 154 build_hostname(buf + 1, sizeof(buf) - 1, data, datalen, topdomain, b32); 155 send_query(fd, buf); 156 } 157 158 static int 159 build_hostname(char *buf, size_t buflen, 160 const char *data, const size_t datalen, 161 const char *topdomain, struct encoder *encoder) 162 { 163 int encsize; 164 size_t space; 165 char *b; 166 167 space = MIN(0xFF, buflen) - strlen(topdomain) - 7; 168 if (!encoder->places_dots()) 169 space -= (space / 57); /* space for dots */ 170 171 memset(buf, 0, buflen); 172 173 encsize = encoder->encode(buf, &space, data, datalen); 174 175 if (!encoder->places_dots()) 176 inline_dotify(buf, buflen); 177 178 b = buf; 179 b += strlen(buf); 180 181 if (*b != '.') 182 *b++ = '.'; 183 184 strncpy(b, topdomain, strlen(topdomain)+1); 185 186 return space; 187 } 188 189 static int 190 is_sending() 191 { 192 return (outpkt.len != 0); 193 } 194 195 static int 196 read_dns(int dns_fd, int tun_fd, char *buf, int buflen) /* FIXME: tun_fd needed for raw handling */ 197 { 198 struct sockaddr_in from; 199 char data[64*1024]; 200 socklen_t addrlen; 201 struct query q; 202 int r; 203 204 addrlen = sizeof(struct sockaddr); 205 if ((r = recvfrom(dns_fd, data, sizeof(data), 0, 206 (struct sockaddr*)&from, &addrlen)) == -1) { 207 warn("recvfrom"); 208 return 0; 209 } 210 211 if (conn == CONN_DNS_NULL) { 212 int rv; 213 214 rv = dns_decode(buf, buflen, &q, QR_ANSWER, data, r); 215 216 /* decode the data header, update seqno and frag before next request */ 217 if (rv >= 2) { 218 downstream_seqno = (buf[1] >> 5) & 7; 219 downstream_fragment = (buf[1] >> 1) & 15; 220 } 221 222 223 if (is_sending()) { 224 if (chunkid == q.id) { 225 /* Got ACK on sent packet */ 226 outpkt.offset += outpkt.sentlen; 227 if (outpkt.offset == outpkt.len) { 228 /* Packet completed */ 229 outpkt.offset = 0; 230 outpkt.len = 0; 231 outpkt.sentlen = 0; 232 233 /* If the ack contains unacked frag number but no data, 234 * send a ping to ack the frag number and get more data*/ 235 if (rv == 2 && ( 236 downstream_seqno != down_ack_seqno || 237 downstream_fragment != down_ack_fragment 238 )) { 239 240 send_ping(dns_fd); 241 } 242 } else { 243 /* More to send */ 244 send_chunk(dns_fd); 245 } 246 } 247 } 248 return rv; 249 } else { /* CONN_RAW_UDP */ 250 unsigned long datalen; 251 char buf[64*1024]; 252 253 /* minimum length */ 254 if (r < RAW_HDR_LEN) return 0; 255 /* should start with header */ 256 if (memcmp(data, raw_header, RAW_HDR_IDENT_LEN)) return 0; 257 /* should be data packet */ 258 if (RAW_HDR_GET_CMD(data) != RAW_HDR_CMD_DATA) return 0; 259 /* should be my user id */ 260 if (RAW_HDR_GET_USR(data) != userid) return 0; 261 262 r -= RAW_HDR_LEN; 263 datalen = sizeof(buf); 264 if (uncompress((uint8_t*)buf, &datalen, (uint8_t*) &data[RAW_HDR_LEN], r) == Z_OK) { 265 write_tun(tun_fd, buf, datalen); 266 } 267 return 0; 268 } 269 } 270 271 272 static int 273 tunnel_tun(int tun_fd, int dns_fd) 274 { 275 unsigned long outlen; 276 unsigned long inlen; 277 char out[64*1024]; 278 char in[64*1024]; 279 ssize_t read; 280 281 if ((read = read_tun(tun_fd, in, sizeof(in))) <= 0) 282 return -1; 283 284 outlen = sizeof(out); 285 inlen = read; 286 compress2((uint8_t*)out, &outlen, (uint8_t*)in, inlen, 9); 287 288 memcpy(outpkt.data, out, MIN(outlen, sizeof(outpkt.data))); 289 outpkt.sentlen = 0; 290 outpkt.offset = 0; 291 outpkt.len = outlen; 292 outpkt.seqno++; 293 outpkt.fragment = 0; 294 295 if (conn == CONN_DNS_NULL) { 296 send_chunk(dns_fd); 297 } else { 298 send_raw_data(dns_fd); 299 } 300 301 return read; 302 } 303 304 static int 305 tunnel_dns(int tun_fd, int dns_fd) 306 { 307 unsigned long datalen; 308 char buf[64*1024]; 309 size_t read; 310 311 if ((read = read_dns(dns_fd, tun_fd, buf, sizeof(buf))) <= 2) 312 return -1; 313 314 if (downstream_seqno != inpkt.seqno) { 315 /* New packet */ 316 inpkt.seqno = downstream_seqno; 317 inpkt.fragment = downstream_fragment; 318 inpkt.len = 0; 319 } else if (downstream_fragment <= inpkt.fragment) { 320 /* Duplicate fragment */ 321 return -1; 322 } 323 inpkt.fragment = downstream_fragment; 324 325 datalen = MIN(read - 2, sizeof(inpkt.data) - inpkt.len); 326 327 /* Skip 2 byte data header and append to packet */ 328 memcpy(&inpkt.data[inpkt.len], &buf[2], datalen); 329 inpkt.len += datalen; 330 331 if (buf[1] & 1) { /* If last fragment flag is set */ 332 /* Uncompress packet and send to tun */ 333 datalen = sizeof(buf); 334 if (uncompress((uint8_t*)buf, &datalen, (uint8_t*) inpkt.data, inpkt.len) == Z_OK) { 335 write_tun(tun_fd, buf, datalen); 336 } 337 inpkt.len = 0; 338 } 339 340 /* If we have nothing to send, send a ping to get more data */ 341 if (!is_sending()) 342 send_ping(dns_fd); 343 344 return read; 345 } 346 347 static int 348 tunnel(int tun_fd, int dns_fd) 349 { 350 struct timeval tv; 351 fd_set fds; 352 int rv; 353 int i; 354 int seconds; 355 356 rv = 0; 357 seconds = 0; 358 359 while (running) { 360 tv.tv_sec = 1; 361 tv.tv_usec = 0; 362 363 364 FD_ZERO(&fds); 365 if ((!is_sending()) || conn == CONN_RAW_UDP) { 366 FD_SET(tun_fd, &fds); 367 } 368 FD_SET(dns_fd, &fds); 369 370 i = select(MAX(tun_fd, dns_fd) + 1, &fds, NULL, NULL, &tv); 371 372 if (running == 0) 373 break; 374 375 if (i < 0) 376 err(1, "select"); 377 378 if (i == 0) { /* timeout */ 379 seconds++; 380 } else { 381 if (FD_ISSET(tun_fd, &fds)) { 382 seconds = 0; 383 if (tunnel_tun(tun_fd, dns_fd) <= 0) 384 continue; 385 } 386 if (FD_ISSET(dns_fd, &fds)) { 387 if (tunnel_dns(tun_fd, dns_fd) <= 0) 388 continue; 389 } 390 } 391 392 if (PING_TIMEOUT(seconds)) { 393 send_ping(dns_fd); 394 seconds = 0; 395 } 396 } 397 398 return rv; 399 } 400 401 static void 402 send_raw_data(int dns_fd) 403 { 404 send_raw(dns_fd, outpkt.data, outpkt.len, userid, RAW_HDR_CMD_DATA); 405 } 406 407 static void 408 send_chunk(int fd) 409 { 410 char hex[] = "0123456789ABCDEF"; 411 char buf[4096]; 412 int avail; 413 int code; 414 char *p; 415 416 p = outpkt.data; 417 p += outpkt.offset; 418 avail = outpkt.len - outpkt.offset; 419 420 outpkt.sentlen = build_hostname(buf + 4, sizeof(buf) - 4, p, avail, topdomain, dataenc); 421 422 /* Build upstream data header (see doc/proto_xxxxxxxx.txt) */ 423 424 buf[0] = hex[userid & 15]; /* First byte is 4 bits userid */ 425 426 code = ((outpkt.seqno & 7) << 2) | ((outpkt.fragment & 15) >> 2); 427 buf[1] = b32_5to8(code); /* Second byte is 3 bits seqno, 2 upper bits fragment count */ 428 429 code = ((outpkt.fragment & 3) << 3) | (downstream_seqno & 7); 430 buf[2] = b32_5to8(code); /* Third byte is 2 bits lower fragment count, 3 bits downstream packet seqno */ 431 432 code = ((downstream_fragment & 15) << 1) | (outpkt.sentlen == avail); 433 buf[3] = b32_5to8(code); /* Fourth byte is 4 bits downstream fragment count, 1 bit last frag flag */ 434 435 down_ack_seqno = downstream_seqno; 436 down_ack_fragment = downstream_fragment; 437 438 outpkt.fragment++; 439 send_query(fd, buf); 440 } 441 442 static void 443 send_login(int fd, char *login, int len) 444 { 445 char data[19]; 446 447 memset(data, 0, sizeof(data)); 448 data[0] = userid; 449 memcpy(&data[1], login, MIN(len, 16)); 450 451 data[17] = (rand_seed >> 8) & 0xff; 452 data[18] = (rand_seed >> 0) & 0xff; 453 454 rand_seed++; 455 456 send_packet(fd, 'L', data, sizeof(data)); 457 } 458 459 static void 460 send_ping(int fd) 461 { 462 if (conn == CONN_DNS_NULL) { 463 char data[4]; 464 465 if (is_sending()) { 466 outpkt.sentlen = 0; 467 outpkt.offset = 0; 468 outpkt.len = 0; 469 } 470 471 data[0] = userid; 472 data[1] = ((downstream_seqno & 7) << 4) | (downstream_fragment & 15); 473 data[2] = (rand_seed >> 8) & 0xff; 474 data[3] = (rand_seed >> 0) & 0xff; 475 476 down_ack_seqno = downstream_seqno; 477 down_ack_fragment = downstream_fragment; 478 479 rand_seed++; 480 481 send_packet(fd, 'P', data, sizeof(data)); 482 } else { 483 send_raw(fd, NULL, 0, userid, RAW_HDR_CMD_PING); 484 } 485 } 486 487 static void 488 send_fragsize_probe(int fd, int fragsize) 489 { 490 char probedata[256]; 491 char buf[4096]; 492 493 /* build a large query domain which is random and maximum size */ 494 memset(probedata, MIN(1, rand_seed & 0xff), sizeof(probedata)); 495 probedata[1] = MIN(1, (rand_seed >> 8) & 0xff); 496 rand_seed++; 497 build_hostname(buf + 4, sizeof(buf) - 4, probedata, sizeof(probedata), topdomain, dataenc); 498 499 fragsize &= 2047; 500 501 buf[0] = 'r'; /* Probe downstream fragsize packet */ 502 buf[1] = b32_5to8((userid << 1) | ((fragsize >> 10) & 1)); 503 buf[2] = b32_5to8((fragsize >> 5) & 31); 504 buf[3] = b32_5to8(fragsize & 31); 505 506 send_query(fd, buf); 507 } 508 509 static void 510 send_set_downstream_fragsize(int fd, int fragsize) 511 { 512 char data[5]; 513 514 data[0] = userid; 515 data[1] = (fragsize & 0xff00) >> 8; 516 data[2] = (fragsize & 0x00ff); 517 data[3] = (rand_seed >> 8) & 0xff; 518 data[4] = (rand_seed >> 0) & 0xff; 519 520 rand_seed++; 521 522 send_packet(fd, 'N', data, sizeof(data)); 523 } 524 525 static void 526 send_version(int fd, uint32_t version) 527 { 528 char data[6]; 529 530 data[0] = (version >> 24) & 0xff; 531 data[1] = (version >> 16) & 0xff; 532 data[2] = (version >> 8) & 0xff; 533 data[3] = (version >> 0) & 0xff; 534 535 data[4] = (rand_seed >> 8) & 0xff; 536 data[5] = (rand_seed >> 0) & 0xff; 537 538 rand_seed++; 539 540 send_packet(fd, 'V', data, sizeof(data)); 541 } 542 543 static void 544 send_ip_request(int fd, int userid) 545 { 546 char buf[512] = "I____."; 547 buf[1] = b32_5to8(userid); 548 549 buf[2] = b32_5to8((rand_seed >> 10) & 0x1f); 550 buf[3] = b32_5to8((rand_seed >> 5) & 0x1f); 551 buf[4] = b32_5to8((rand_seed ) & 0x1f); 552 rand_seed++; 553 554 strncat(buf, topdomain, 512 - strlen(buf)); 555 send_query(fd, buf); 556 } 557 558 static void 559 send_raw_udp_login(int dns_fd, int userid, int seed) 560 { 561 char buf[16]; 562 login_calculate(buf, 16, password, seed + 1); 563 564 send_raw(dns_fd, buf, sizeof(buf), userid, RAW_HDR_CMD_LOGIN); 565 } 566 567 static void 568 send_case_check(int fd) 569 { 570 /* The '+' plus character is not allowed according to RFC. 571 * Expect to get SERVFAIL or similar if it is rejected. 572 */ 573 char buf[512] = "zZ+-aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyY1234."; 574 575 strncat(buf, topdomain, 512 - strlen(buf)); 576 send_query(fd, buf); 577 } 578 579 static void 580 send_codec_switch(int fd, int userid, int bits) 581 { 582 char buf[512] = "S_____."; 583 buf[1] = b32_5to8(userid); 584 buf[2] = b32_5to8(bits); 585 586 buf[3] = b32_5to8((rand_seed >> 10) & 0x1f); 587 buf[4] = b32_5to8((rand_seed >> 5) & 0x1f); 588 buf[5] = b32_5to8((rand_seed ) & 0x1f); 589 rand_seed++; 590 591 strncat(buf, topdomain, 512 - strlen(buf)); 592 send_query(fd, buf); 593 } 594 595 static int 596 handshake_version(int dns_fd, int *seed) 597 { 598 struct timeval tv; 599 char in[4096]; 600 fd_set fds; 601 uint32_t payload; 602 int i; 603 int r; 604 int read; 605 606 for (i = 0; running && i < 5; i++) { 607 tv.tv_sec = i + 1; 608 tv.tv_usec = 0; 609 610 send_version(dns_fd, VERSION); 611 612 FD_ZERO(&fds); 613 FD_SET(dns_fd, &fds); 614 615 r = select(dns_fd + 1, &fds, NULL, NULL, &tv); 616 617 if(r > 0) { 618 read = read_dns(dns_fd, 0, in, sizeof(in)); 619 620 if(read <= 0) { 621 if (read == 0) { 622 warn("handshake read"); 623 } 624 /* if read < 0 then warning has been printed already */ 625 continue; 626 } 627 628 if (read >= 9) { 629 payload = (((in[4] & 0xff) << 24) | 630 ((in[5] & 0xff) << 16) | 631 ((in[6] & 0xff) << 8) | 632 ((in[7] & 0xff))); 633 634 if (strncmp("VACK", in, 4) == 0) { 635 *seed = payload; 636 userid = in[8]; 637 638 fprintf(stderr, "Version ok, both using protocol v 0x%08x. You are user #%d\n", VERSION, userid); 639 return 0; 640 } else if (strncmp("VNAK", in, 4) == 0) { 641 warnx("You use protocol v 0x%08x, server uses v 0x%08x. Giving up", 642 VERSION, payload); 643 return 1; 644 } else if (strncmp("VFUL", in, 4) == 0) { 645 warnx("Server full, all %d slots are taken. Try again later", payload); 646 return 1; 647 } 648 } else 649 warnx("did not receive proper login challenge"); 650 } 651 652 fprintf(stderr, "Retrying version check...\n"); 653 } 654 warnx("couldn't connect to server"); 655 return 1; 656 } 657 658 static int 659 handshake_login(int dns_fd, int seed) 660 { 661 struct timeval tv; 662 char in[4096]; 663 char login[16]; 664 char server[65]; 665 char client[65]; 666 int mtu; 667 fd_set fds; 668 int i; 669 int r; 670 int read; 671 672 login_calculate(login, 16, password, seed); 673 674 for (i=0; running && i<5 ;i++) { 675 tv.tv_sec = i + 1; 676 tv.tv_usec = 0; 677 678 send_login(dns_fd, login, 16); 679 680 FD_ZERO(&fds); 681 FD_SET(dns_fd, &fds); 682 683 r = select(dns_fd + 1, &fds, NULL, NULL, &tv); 684 685 if(r > 0) { 686 read = read_dns(dns_fd, 0, in, sizeof(in)); 687 688 if(read <= 0) { 689 warn("read"); 690 continue; 691 } 692 693 if (read > 0) { 694 int netmask; 695 if (strncmp("LNAK", in, 4) == 0) { 696 fprintf(stderr, "Bad password\n"); 697 return 1; 698 } else if (sscanf(in, "%64[^-]-%64[^-]-%d-%d", 699 server, client, &mtu, &netmask) == 4) { 700 701 server[64] = 0; 702 client[64] = 0; 703 if (tun_setip(client, netmask) == 0 && 704 tun_setmtu(mtu) == 0) { 705 return 0; 706 } else { 707 errx(4, "Failed to set IP and MTU"); 708 } 709 } else { 710 fprintf(stderr, "Received bad handshake\n"); 711 } 712 } 713 } 714 715 fprintf(stderr, "Retrying login...\n"); 716 } 717 warnx("couldn't login to server"); 718 return 1; 719 } 720 721 static int 722 handshake_raw_udp(int dns_fd, int seed) 723 { 724 struct timeval tv; 725 char in[4096]; 726 fd_set fds; 727 int i; 728 int r; 729 int len; 730 unsigned remoteaddr = 0; 731 struct in_addr server; 732 733 fprintf(stderr, "Testing raw UDP data to the server (skip with -r)\n"); 734 for (i=0; running && i<3 ;i++) { 735 tv.tv_sec = i + 1; 736 tv.tv_usec = 0; 737 738 send_ip_request(dns_fd, userid); 739 740 FD_ZERO(&fds); 741 FD_SET(dns_fd, &fds); 742 743 r = select(dns_fd + 1, &fds, NULL, NULL, &tv); 744 745 if(r > 0) { 746 len = read_dns(dns_fd, 0, in, sizeof(in)); 747 if (len == 5 && in[0] == 'I') { 748 /* Received IP address */ 749 remoteaddr = (in[1] & 0xff); 750 remoteaddr <<= 8; 751 remoteaddr |= (in[2] & 0xff); 752 remoteaddr <<= 8; 753 remoteaddr |= (in[3] & 0xff); 754 remoteaddr <<= 8; 755 remoteaddr |= (in[4] & 0xff); 756 server.s_addr = ntohl(remoteaddr); 757 break; 758 } 759 } else { 760 fprintf(stderr, "."); 761 fflush(stderr); 762 } 763 } 764 765 if (!remoteaddr) { 766 fprintf(stderr, "Failed to get raw server IP, will use DNS mode.\n"); 767 return 0; 768 } 769 fprintf(stderr, "Server is at %s, trying raw login: ", inet_ntoa(server)); 770 fflush(stderr); 771 772 /* Store address to iodined server */ 773 memset(&raw_serv, 0, sizeof(raw_serv)); 774 raw_serv.sin_family = AF_INET; 775 raw_serv.sin_port = htons(53); 776 raw_serv.sin_addr = server; 777 778 /* do login against port 53 on remote server 779 * based on the old seed. If reply received, 780 * switch to raw udp mode */ 781 for (i=0; running && i<4 ;i++) { 782 tv.tv_sec = i + 1; 783 tv.tv_usec = 0; 784 785 send_raw_udp_login(dns_fd, userid, seed); 786 787 FD_ZERO(&fds); 788 FD_SET(dns_fd, &fds); 789 790 r = select(dns_fd + 1, &fds, NULL, NULL, &tv); 791 792 if(r > 0) { 793 /* recv() needed for windows, dont change to read() */ 794 len = recv(dns_fd, in, sizeof(in), 0); 795 if (len >= (16 + RAW_HDR_LEN)) { 796 char hash[16]; 797 login_calculate(hash, 16, password, seed - 1); 798 if (memcmp(in, raw_header, RAW_HDR_IDENT_LEN) == 0 799 && RAW_HDR_GET_CMD(in) == RAW_HDR_CMD_LOGIN 800 && memcmp(&in[RAW_HDR_LEN], hash, sizeof(hash)) == 0) { 801 802 fprintf(stderr, "OK\n"); 803 return 1; 804 } 805 } 806 } 807 fprintf(stderr, "."); 808 fflush(stderr); 809 } 810 811 fprintf(stderr, "failed\n"); 812 return 0; 813 } 814 815 static int 816 handshake_case_check(int dns_fd) 817 { 818 struct timeval tv; 819 char in[4096]; 820 fd_set fds; 821 int i; 822 int r; 823 int read; 824 int case_preserved; 825 826 case_preserved = 0; 827 for (i=0; running && i<5 ;i++) { 828 tv.tv_sec = i + 1; 829 tv.tv_usec = 0; 830 831 send_case_check(dns_fd); 832 833 FD_ZERO(&fds); 834 FD_SET(dns_fd, &fds); 835 836 r = select(dns_fd + 1, &fds, NULL, NULL, &tv); 837 838 if(r > 0) { 839 read = read_dns(dns_fd, 0, in, sizeof(in)); 840 841 if (read > 0) { 842 if (in[0] == 'z' || in[0] == 'Z') { 843 if (read < (27 * 2)) { 844 fprintf(stderr, "Received short case check reply. Will use base32 encoder\n"); 845 return case_preserved; 846 } else { 847 int k; 848 849 /* TODO enhance this, base128 is probably also possible */ 850 case_preserved = 1; 851 for (k = 0; k < 27 && case_preserved; k += 2) { 852 if (in[k] == in[k+1]) { 853 /* test string: zZ+-aAbBcCdDeE... */ 854 case_preserved = 0; 855 } 856 } 857 return case_preserved; 858 } 859 } else { 860 fprintf(stderr, "Received bad case check reply\n"); 861 } 862 } else { 863 fprintf(stderr, "Got error on case check, will use base32\n"); 864 return case_preserved; 865 } 866 } 867 868 fprintf(stderr, "Retrying case check...\n"); 869 } 870 871 fprintf(stderr, "No reply on case check, continuing\n"); 872 return case_preserved; 873 } 874 875 static void 876 handshake_switch_codec(int dns_fd) 877 { 878 struct timeval tv; 879 char in[4096]; 880 fd_set fds; 881 int i; 882 int r; 883 int read; 884 885 dataenc = get_base64_encoder(); 886 fprintf(stderr, "Switching to %s codec\n", dataenc->name); 887 /* Send to server that this user will use base64 from now on */ 888 for (i=0; running && i<5 ;i++) { 889 int bits; 890 tv.tv_sec = i + 1; 891 tv.tv_usec = 0; 892 893 bits = 6; /* base64 = 6 bits per byte */ 894 895 send_codec_switch(dns_fd, userid, bits); 896 897 FD_ZERO(&fds); 898 FD_SET(dns_fd, &fds); 899 900 r = select(dns_fd + 1, &fds, NULL, NULL, &tv); 901 902 if(r > 0) { 903 read = read_dns(dns_fd, 0, in, sizeof(in)); 904 905 if (read > 0) { 906 if (strncmp("BADLEN", in, 6) == 0) { 907 fprintf(stderr, "Server got bad message length. "); 908 goto codec_revert; 909 } else if (strncmp("BADIP", in, 5) == 0) { 910 fprintf(stderr, "Server rejected sender IP address. "); 911 goto codec_revert; 912 } else if (strncmp("BADCODEC", in, 8) == 0) { 913 fprintf(stderr, "Server rejected the selected codec. "); 914 goto codec_revert; 915 } 916 in[read] = 0; /* zero terminate */ 917 fprintf(stderr, "Server switched to codec %s\n", in); 918 return; 919 } 920 } 921 fprintf(stderr, "Retrying codec switch...\n"); 922 } 923 fprintf(stderr, "No reply from server on codec switch. "); 924 925 codec_revert: 926 fprintf(stderr, "Falling back to base32\n"); 927 dataenc = get_base32_encoder(); 928 } 929 930 static int 931 handshake_autoprobe_fragsize(int dns_fd) 932 { 933 struct timeval tv; 934 char in[4096]; 935 fd_set fds; 936 int i; 937 int r; 938 int read; 939 int proposed_fragsize = 768; 940 int range = 768; 941 int max_fragsize = 0; 942 943 max_fragsize = 0; 944 fprintf(stderr, "Autoprobing max downstream fragment size... (skip with -m fragsize)\n"); 945 while (running && range > 0 && (range >= 8 || !max_fragsize)) { 946 for (i=0; running && i<3 ;i++) { 947 tv.tv_sec = 1; 948 tv.tv_usec = 0; 949 send_fragsize_probe(dns_fd, proposed_fragsize); 950 951 FD_ZERO(&fds); 952 FD_SET(dns_fd, &fds); 953 954 r = select(dns_fd + 1, &fds, NULL, NULL, &tv); 955 956 if(r > 0) { 957 read = read_dns(dns_fd, 0, in, sizeof(in)); 958 959 if (read > 0) { 960 /* We got a reply */ 961 int acked_fragsize = ((in[0] & 0xff) << 8) | (in[1] & 0xff); 962 if (acked_fragsize == proposed_fragsize) { 963 if (read == proposed_fragsize) { 964 fprintf(stderr, "%d ok.. ", acked_fragsize); 965 fflush(stderr); 966 max_fragsize = acked_fragsize; 967 } 968 } 969 if (strncmp("BADIP", in, 5) == 0) { 970 fprintf(stderr, "got BADIP.. "); 971 fflush(stderr); 972 } 973 break; 974 } 975 } 976 fprintf(stderr, "."); 977 fflush(stderr); 978 } 979 range >>= 1; 980 if (max_fragsize == proposed_fragsize) { 981 /* Try bigger */ 982 proposed_fragsize += range; 983 } else { 984 /* Try smaller */ 985 fprintf(stderr, "%d not ok.. ", proposed_fragsize); 986 fflush(stderr); 987 proposed_fragsize -= range; 988 } 989 } 990 if (!running) { 991 fprintf(stderr, "\n"); 992 warnx("stopped while autodetecting fragment size (Try probing manually with -m)"); 993 return 0; 994 } 995 if (range == 0) { 996 /* Tried all the way down to 2 and found no good size */ 997 fprintf(stderr, "\n"); 998 warnx("found no accepted fragment size. (Try probing manually with -m)"); 999 return 0; 1000 } 1001 fprintf(stderr, "will use %d\n", max_fragsize); 1002 return max_fragsize; 1003 } 1004 1005 static void 1006 handshake_set_fragsize(int dns_fd, int fragsize) 1007 { 1008 struct timeval tv; 1009 char in[4096]; 1010 fd_set fds; 1011 int i; 1012 int r; 1013 int read; 1014 1015 fprintf(stderr, "Setting downstream fragment size to max %d...\n", fragsize); 1016 for (i=0; running && i<5 ;i++) { 1017 tv.tv_sec = i + 1; 1018 tv.tv_usec = 0; 1019 1020 send_set_downstream_fragsize(dns_fd, fragsize); 1021 1022 FD_ZERO(&fds); 1023 FD_SET(dns_fd, &fds); 1024 1025 r = select(dns_fd + 1, &fds, NULL, NULL, &tv); 1026 1027 if(r > 0) { 1028 read = read_dns(dns_fd, 0, in, sizeof(in)); 1029 1030 if (read > 0) { 1031 int accepted_fragsize; 1032 1033 if (strncmp("BADFRAG", in, 7) == 0) { 1034 fprintf(stderr, "Server rejected fragsize. Keeping default."); 1035 return; 1036 } else if (strncmp("BADIP", in, 5) == 0) { 1037 fprintf(stderr, "Server rejected sender IP address.\n"); 1038 return; 1039 } 1040 1041 accepted_fragsize = ((in[0] & 0xff) << 8) | (in[1] & 0xff); 1042 return; 1043 } 1044 } 1045 fprintf(stderr, "Retrying set fragsize...\n"); 1046 } 1047 fprintf(stderr, "No reply from server when setting fragsize. Keeping default.\n"); 1048 } 1049 1050 static int 1051 handshake(int dns_fd, int raw_mode, int autodetect_frag_size, int fragsize) 1052 { 1053 int seed; 1054 int case_preserved; 1055 int r; 1056 1057 r = handshake_version(dns_fd, &seed); 1058 if (r) { 1059 return r; 1060 } 1061 1062 r = handshake_login(dns_fd, seed); 1063 if (r) { 1064 return r; 1065 } 1066 1067 if (raw_mode && handshake_raw_udp(dns_fd, seed)) { 1068 conn = CONN_RAW_UDP; 1069 } else { 1070 if (raw_mode == 0) { 1071 fprintf(stderr, "Skipping raw mode\n"); 1072 } 1073 case_preserved = handshake_case_check(dns_fd); 1074 1075 if (case_preserved) { 1076 handshake_switch_codec(dns_fd); 1077 } 1078 1079 if (autodetect_frag_size) { 1080 fragsize = handshake_autoprobe_fragsize(dns_fd); 1081 if (!fragsize) { 1082 return 1; 1083 } 1084 } 1085 1086 handshake_set_fragsize(dns_fd, fragsize); 1087 } 1088 1089 return 0; 1090 } 1091 1092 static char * 1093 get_resolvconf_addr() 1094 { 1095 static char addr[16]; 1096 char *rv; 1097 #ifndef WINDOWS32 1098 char buf[80]; 1099 FILE *fp; 1100 1101 rv = NULL; 1102 1103 if ((fp = fopen("/etc/resolv.conf", "r")) == NULL) 1104 err(1, "/etc/resolve.conf"); 1105 1106 while (feof(fp) == 0) { 1107 fgets(buf, sizeof(buf), fp); 1108 1109 if (sscanf(buf, "nameserver %15s", addr) == 1) { 1110 rv = addr; 1111 break; 1112 } 1113 } 1114 1115 fclose(fp); 1116 #else /* !WINDOWS32 */ 1117 FIXED_INFO *fixed_info; 1118 ULONG buflen; 1119 DWORD ret; 1120 1121 rv = NULL; 1122 fixed_info = malloc(sizeof(FIXED_INFO)); 1123 buflen = sizeof(FIXED_INFO); 1124 1125 if (GetNetworkParams(fixed_info, &buflen) == ERROR_BUFFER_OVERFLOW) { 1126 /* official ugly api workaround */ 1127 free(fixed_info); 1128 fixed_info = malloc(buflen); 1129 } 1130 1131 ret = GetNetworkParams(fixed_info, &buflen); 1132 if (ret == NO_ERROR) { 1133 strncpy(addr, fixed_info->DnsServerList.IpAddress.String, sizeof(addr)); 1134 addr[15] = 0; 1135 rv = addr; 1136 } 1137 free(fixed_info); 1138 #endif 1139 return rv; 1140 } 1141 1142 static void 1143 set_nameserver(const char *cp) 1144 { 1145 struct in_addr addr; 1146 1147 if (inet_aton(cp, &addr) != 1) 1148 errx(1, "error parsing nameserver address: '%s'", cp); 1149 1150 memset(&nameserv, 0, sizeof(nameserv)); 1151 nameserv.sin_family = AF_INET; 1152 nameserv.sin_port = htons(53); 1153 nameserv.sin_addr = addr; 54 client_stop(); 1154 55 } 1155 56 … … 1205 106 { 1206 107 char *nameserv_addr; 108 char *topdomain; 1207 109 #ifndef WINDOWS32 1208 110 struct passwd *pw; 1209 111 #endif 1210 112 char *username; 113 char password[33]; 1211 114 int foreground; 1212 115 char *newroot; … … 1222 125 int raw_mode; 1223 126 1224 memset(password, 0, 33);1225 127 nameserv_addr = NULL; 128 topdomain = NULL; 1226 129 #ifndef WINDOWS32 1227 130 pw = NULL; … … 1232 135 context = NULL; 1233 136 device = NULL; 1234 chunkid = 0;1235 137 pidfile = NULL; 1236 1237 outpkt.seqno = 0;1238 inpkt.len = 0;1239 138 1240 139 autodetect_frag_size = 1; 1241 140 max_downstream_frag_size = 3072; 141 retval = 0; 1242 142 raw_mode = 1; 1243 1244 b32 = get_base32_encoder();1245 dataenc = get_base32_encoder();1246 conn = CONN_DNS_NULL;1247 1248 retval = 0;1249 143 1250 144 #ifdef WINDOWS32 … … 1253 147 1254 148 srand((unsigned) time(NULL)); 1255 rand_seed = rand();149 client_init(); 1256 150 1257 151 #if !defined(BSD) && !defined(__GLIBC__) … … 1336 230 1337 231 if (nameserv_addr) { 1338 set_nameserver(nameserv_addr);232 client_set_nameserver(nameserv_addr); 1339 233 } else { 1340 234 usage(); … … 1354 248 } 1355 249 250 client_set_topdomain(topdomain); 251 1356 252 if (username != NULL) { 1357 253 #ifndef WINDOWS32 … … 1366 262 if (strlen(password) == 0) 1367 263 read_password(password, sizeof(password)); 264 265 client_set_password(password); 1368 266 1369 267 if ((tun_fd = open_tun(device)) == -1) { … … 1379 277 signal(SIGTERM, sighandler); 1380 278 1381 if ( handshake(dns_fd, raw_mode, autodetect_frag_size, max_downstream_frag_size)) {279 if (client_handshake(dns_fd, raw_mode, autodetect_frag_size, max_downstream_frag_size)) { 1382 280 retval = 1; 1383 281 goto cleanup2; 1384 282 } 1385 283 1386 if (c onn== CONN_DNS_NULL) {284 if (client_get_conn() == CONN_DNS_NULL) { 1387 285 fprintf(stderr, "Sending queries for %s to %s\n", topdomain, nameserv_addr); 1388 286 } else { 1389 fprintf(stderr, "Sending raw traffic directly to %s\n", inet_ntoa(raw_serv.sin_addr));287 fprintf(stderr, "Sending raw traffic directly to %s\n", client_get_raw_addr()); 1390 288 } 1391 289 … … 1414 312 do_setcon(context); 1415 313 1416 downstream_seqno = 0; 1417 downstream_fragment = 0; 1418 down_ack_seqno = 0; 1419 down_ack_fragment = 0; 1420 1421 tunnel(tun_fd, dns_fd); 314 client_tunnel(tun_fd, dns_fd); 1422 315 1423 316 cleanup2: -
src/login.c
r155f0c r27fdc2 30 30 */ 31 31 void 32 login_calculate(char *buf, int buflen, c har *pass, int seed)32 login_calculate(char *buf, int buflen, const char *pass, int seed) 33 33 { 34 34 unsigned char temp[32]; -
src/login.h
ra5031e r27fdc2 18 18 #define __LOGIN_H__ 19 19 20 void login_calculate(char *, int, c har *, int);20 void login_calculate(char *, int, const char *, int); 21 21 22 22 #endif
Note: See TracChangeset
for help on using the changeset viewer.
