Changeset 27fdc2


Ignore:
Timestamp:
08/16/09 14:30:26 (3 years ago)
Author:
Erik Ekman <yarrick@…>
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)
Message:

Split the client code out from the file with the main() func

Location:
src
Files:
4 added
4 edited

Legend:

Unmodified
Added
Removed
  • src/Makefile

    r24871f r27fdc2  
    11COMMONOBJS = tun.o dns.o read.o encoding.o login.o base32.o base64.o md5.o common.o 
    2 CLIENTOBJS = iodine.o 
     2CLIENTOBJS = iodine.o client.o util.o 
    33CLIENT = ../bin/iodine 
    44SERVEROBJS = iodined.o user.o fw_query.o 
  • src/iodine.c

    r1137ac r27fdc2  
    2525#include <sys/time.h> 
    2626#include <fcntl.h> 
    27 #include <zlib.h> 
    2827#include <time.h> 
    2928 
     
    3231#include <winsock2.h> 
    3332#else 
    34 #include <arpa/nameser.h> 
    35 #ifdef DARWIN 
    36 #include <arpa/nameser8_compat.h> 
    37 #endif 
    38 #include <sys/socket.h> 
    39 #include <err.h> 
    40 #include <arpa/inet.h> 
    41 #include <netinet/in.h> 
    4233#include <grp.h> 
    4334#include <pwd.h> 
    44 #include <netdb.h> 
    4535#endif 
    4636 
    4737#include "common.h" 
    48 #include "encoding.h" 
    49 #include "base32.h" 
    50 #include "base64.h" 
    51 #include "dns.h" 
    52 #include "login.h" 
    5338#include "tun.h" 
    54 #include "version.h" 
     39#include "client.h" 
     40#include "util.h" 
    5541 
    5642#ifdef WINDOWS32 
     
    5945#endif 
    6046 
    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 packets 
    97  * Defaults to Base32, can be changed after handshake */ 
    98 static struct encoder *dataenc; 
    99  
    100 /* My connection mode */ 
    101 static enum connection conn; 
    102  
    10347#if !defined(BSD) && !defined(__GLIBC__) 
    10448static char *__progname; 
     
    10852sighandler(int sig)  
    10953{ 
    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(); 
    115455} 
    115556 
     
    1205106{ 
    1206107        char *nameserv_addr; 
     108        char *topdomain; 
    1207109#ifndef WINDOWS32 
    1208110        struct passwd *pw; 
    1209111#endif 
    1210112        char *username; 
     113        char password[33]; 
    1211114        int foreground; 
    1212115        char *newroot; 
     
    1222125        int raw_mode; 
    1223126 
    1224         memset(password, 0, 33); 
    1225127        nameserv_addr = NULL; 
     128        topdomain = NULL; 
    1226129#ifndef WINDOWS32 
    1227130        pw = NULL; 
     
    1232135        context = NULL; 
    1233136        device = NULL; 
    1234         chunkid = 0; 
    1235137        pidfile = NULL; 
    1236  
    1237         outpkt.seqno = 0; 
    1238         inpkt.len = 0; 
    1239138 
    1240139        autodetect_frag_size = 1; 
    1241140        max_downstream_frag_size = 3072; 
     141        retval = 0; 
    1242142        raw_mode = 1; 
    1243  
    1244         b32 = get_base32_encoder(); 
    1245         dataenc = get_base32_encoder(); 
    1246         conn = CONN_DNS_NULL; 
    1247  
    1248         retval = 0; 
    1249143 
    1250144#ifdef WINDOWS32 
     
    1253147 
    1254148        srand((unsigned) time(NULL)); 
    1255         rand_seed = rand(); 
     149        client_init(); 
    1256150         
    1257151#if !defined(BSD) && !defined(__GLIBC__) 
     
    1336230 
    1337231        if (nameserv_addr) { 
    1338                 set_nameserver(nameserv_addr); 
     232                client_set_nameserver(nameserv_addr); 
    1339233        } else { 
    1340234                usage(); 
     
    1354248        } 
    1355249 
     250        client_set_topdomain(topdomain); 
     251         
    1356252        if (username != NULL) { 
    1357253#ifndef WINDOWS32 
     
    1366262        if (strlen(password) == 0)  
    1367263                read_password(password, sizeof(password)); 
     264         
     265        client_set_password(password); 
    1368266 
    1369267        if ((tun_fd = open_tun(device)) == -1) { 
     
    1379277        signal(SIGTERM, sighandler); 
    1380278 
    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)) { 
    1382280                retval = 1; 
    1383281                goto cleanup2; 
    1384282        } 
    1385283         
    1386         if (conn == CONN_DNS_NULL) { 
     284        if (client_get_conn() == CONN_DNS_NULL) { 
    1387285                fprintf(stderr, "Sending queries for %s to %s\n", topdomain, nameserv_addr); 
    1388286        } 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()); 
    1390288        } 
    1391289 
     
    1414312                do_setcon(context); 
    1415313 
    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); 
    1422315 
    1423316cleanup2: 
  • src/login.c

    r155f0c r27fdc2  
    3030 */ 
    3131void  
    32 login_calculate(char *buf, int buflen, char *pass, int seed)  
     32login_calculate(char *buf, int buflen, const char *pass, int seed)  
    3333{ 
    3434        unsigned char temp[32]; 
  • src/login.h

    ra5031e r27fdc2  
    1818#define __LOGIN_H__ 
    1919 
    20 void login_calculate(char *, int, char *, int); 
     20void login_calculate(char *, int, const char *, int); 
    2121 
    2222#endif 
Note: See TracChangeset for help on using the changeset viewer.