Changeset 401674


Ignore:
Timestamp:
09/20/09 17:11:16 (4 years ago)
Author:
J. A. Bezemer <J.A.Bezemer@…>
Branches:
master
Children:
d4d88d
Parents:
55cfed
git-author:
J. A. Bezemer <J.A.Bezemer@…> (09/20/09 17:11:16)
git-committer:
Erik Ekman <erik@…> (02/04/12 20:34:04)
Message:

update server code #75

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/iodined.c

    rb6eb8d r401674  
    6969static char password[33]; 
    7070static struct encoder *b32; 
     71static struct encoder *b64; 
    7172static int created_users; 
    7273 
     
    8687 
    8788static int read_dns(int, int, struct query *); 
    88 static void write_dns(int, struct query *, char *, int); 
     89static void write_dns(int, struct query *, char *, int, char); 
    8990static void handle_full_packet(int, int); 
    9091 
     
    120121                return 1;  
    121122        } 
    122         if (!users[userid].active) { 
     123        if (!users[userid].active || users[userid].disabled) { 
    123124                return 1; 
    124125        } 
     
    226227        out[8] = userid & 0xff; 
    227228 
    228         write_dns(fd, q, out, sizeof(out)); 
     229        write_dns(fd, q, out, sizeof(out), users[userid].downenc); 
    229230} 
    230231 
     
    271272                        last, users[userid].outpacket.offset, datalen, users[userid].outpacket.len, userid); 
    272273        } 
    273         write_dns(dns_fd, &users[userid].q, pkt, datalen + 2); 
     274        write_dns(dns_fd, &users[userid].q, pkt, datalen + 2, users[userid].downenc); 
    274275        users[userid].q.id = 0; 
    275276 
     
    361362                                memcpy(&(users[userid].q), q, sizeof(struct query)); 
    362363                                users[userid].encoder = get_base32_encoder(); 
     364                                users[userid].downenc = 'T'; 
    363365                                send_version_response(dns_fd, VERSION_ACK, users[userid].seed, userid, q); 
    364366                                syslog(LOG_INFO, "accepted version for user #%d from %s", 
    365367                                        userid, inet_ntoa(tempin->sin_addr)); 
    366368                                users[userid].q.id = 0; 
     369                                users[userid].outpacket.len = 0; 
     370                                users[userid].outpacket.offset = 0; 
     371                                users[userid].outpacket.sentlen = 0; 
     372                                users[userid].outpacket.seqno = 0; 
     373                                users[userid].outpacket.fragment = 0; 
     374                                users[userid].inpacket.len = 0; 
     375                                users[userid].inpacket.offset = 0; 
     376                                users[userid].inpacket.seqno = 0; 
     377                                users[userid].inpacket.fragment = 0; 
     378                                users[userid].fragsize = 100; /* very safe */ 
    367379                        } else { 
    368380                                /* No space for another user */ 
     
    383395 
    384396                if (check_user_and_ip(userid, q) != 0) { 
    385                         write_dns(dns_fd, q, "BADIP", 5); 
     397                        write_dns(dns_fd, q, "BADIP", 5, 'T'); 
    386398                        syslog(LOG_WARNING, "dropped login request from user #%d from unexpected source %s", 
    387399                                userid, inet_ntoa(((struct sockaddr_in *) &q->from)->sin_addr)); 
     
    402414                                                tmp[0], tmp[1], my_mtu, netmask); 
    403415 
    404                                 write_dns(dns_fd, q, out, read); 
     416                                write_dns(dns_fd, q, out, read, users[userid].downenc); 
    405417                                q->id = 0; 
    406418                                syslog(LOG_NOTICE, "accepted password from user #%d, given IP %s", userid, tmp[1]); 
     
    409421                                free(tmp[0]); 
    410422                        } else { 
    411                                 write_dns(dns_fd, q, "LNAK", 4); 
     423                                write_dns(dns_fd, q, "LNAK", 4, 'T'); 
    412424                                syslog(LOG_WARNING, "rejected login request from user #%d from %s, bad password", 
    413425                                        userid, inet_ntoa(((struct sockaddr_in *) &q->from)->sin_addr)); 
     
    423435                userid = b32_8to5(in[1]); 
    424436                if (check_user_and_ip(userid, q) != 0) { 
    425                         write_dns(dns_fd, q, "BADIP", 5); 
     437                        write_dns(dns_fd, q, "BADIP", 5, 'T'); 
    426438                        return; /* illegal id */ 
    427439                } 
     
    441453                reply[3] = (addr >>  8) & 0xFF; 
    442454                reply[4] = (addr >>  0) & 0xFF; 
    443                 write_dns(dns_fd, q, reply, sizeof(reply)); 
     455                write_dns(dns_fd, q, reply, sizeof(reply), 'T'); 
    444456        } else if(in[0] == 'Z' || in[0] == 'z') { 
    445457                /* Check for case conservation and chars not allowed according to RFC */ 
    446458 
    447459                /* Reply with received hostname as data */ 
    448                 write_dns(dns_fd, q, in, domain_len); 
     460                /* No userid here, reply with lowest-grade downenc */ 
     461                write_dns(dns_fd, q, in, domain_len, 'T'); 
    449462                return; 
    450463        } else if(in[0] == 'S' || in[0] == 's') { 
     
    452465                struct encoder *enc; 
    453466                if (domain_len < 3) { /* len at least 3, example: "S15" */ 
    454                         write_dns(dns_fd, q, "BADLEN", 6); 
     467                        write_dns(dns_fd, q, "BADLEN", 6, 'T'); 
    455468                        return; 
    456469                } 
     
    459472                 
    460473                if (check_user_and_ip(userid, q) != 0) { 
    461                         write_dns(dns_fd, q, "BADIP", 5); 
     474                        write_dns(dns_fd, q, "BADIP", 5, 'T'); 
    462475                        return; /* illegal id */ 
    463476                } 
     
    469482                        enc = get_base32_encoder(); 
    470483                        user_switch_codec(userid, enc); 
    471                         write_dns(dns_fd, q, enc->name, strlen(enc->name)); 
     484                        write_dns(dns_fd, q, enc->name, strlen(enc->name), users[userid].downenc); 
    472485                        break; 
    473486                case 6: /* 6 bits per byte = base64 */ 
    474487                        enc = get_base64_encoder(); 
    475488                        user_switch_codec(userid, enc); 
    476                         write_dns(dns_fd, q, enc->name, strlen(enc->name)); 
     489                        write_dns(dns_fd, q, enc->name, strlen(enc->name), users[userid].downenc); 
    477490                        break; 
    478491                default: 
    479                         write_dns(dns_fd, q, "BADCODEC", 8); 
     492                        write_dns(dns_fd, q, "BADCODEC", 8, users[userid].downenc); 
     493                        break; 
     494                } 
     495                return; 
     496        } else if(in[0] == 'O' || in[0] == 'o') { 
     497                if (domain_len != 4) { /* len = 4, example: "O1T." */ 
     498                        write_dns(dns_fd, q, "BADLEN", 6, 'T'); 
     499                        return; 
     500                } 
     501 
     502                userid = b32_8to5(in[1]); 
     503 
     504                if (check_user_and_ip(userid, q) != 0) { 
     505                        write_dns(dns_fd, q, "BADIP", 5, 'T'); 
     506                        return; /* illegal id */ 
     507                } 
     508 
     509                switch (in[2]) { 
     510                case 'T': 
     511                case 't': 
     512                        users[userid].downenc = 'T'; 
     513                        write_dns(dns_fd, q, "Base32", 6, users[userid].downenc); 
     514                        break; 
     515                case 'S': 
     516                case 's': 
     517                        users[userid].downenc = 'S'; 
     518                        write_dns(dns_fd, q, "Base64", 6, users[userid].downenc); 
     519                        break; 
     520                case 'R': 
     521                case 'r': 
     522                        users[userid].downenc = 'R'; 
     523                        write_dns(dns_fd, q, "Raw", 3, users[userid].downenc); 
     524                        break; 
     525                default: 
     526                        write_dns(dns_fd, q, "BADCODEC", 8, users[userid].downenc); 
    480527                        break; 
    481528                } 
     
    487534                userid = (b32_8to5(in[1]) >> 1) & 15; 
    488535                if (check_user_and_ip(userid, q) != 0) { 
    489                         write_dns(dns_fd, q, "BADIP", 5); 
     536                        write_dns(dns_fd, q, "BADIP", 5, 'T'); 
    490537                        return; /* illegal id */ 
    491538                } 
     
    493540                req_frag_size = ((b32_8to5(in[1]) & 1) << 10) | ((b32_8to5(in[2]) & 31) << 5) | (b32_8to5(in[3]) & 31); 
    494541                if (req_frag_size < 2 || req_frag_size > 2047) {         
    495                         write_dns(dns_fd, q, "BADFRAG", 7); 
     542                        write_dns(dns_fd, q, "BADFRAG", 7, users[userid].downenc); 
    496543                } else { 
    497544                        char buf[2048]; 
     545                        int i; 
     546                        unsigned int v = (unsigned int) rand(); 
    498547 
    499548                        memset(buf, 0, sizeof(buf)); 
    500549                        buf[0] = (req_frag_size >> 8) & 0xff; 
    501550                        buf[1] = req_frag_size & 0xff; 
    502                         write_dns(dns_fd, q, buf, req_frag_size); 
     551                        /* make checkable pseudo-random sequence */ 
     552                        buf[2] = 107; 
     553                        for (i = 3; i < 2048; i++, v += 107) 
     554                                buf[i] = (char) (v & 0xff); 
     555                        write_dns(dns_fd, q, buf, req_frag_size, users[userid].downenc); 
    503556                } 
    504557                return; 
     
    510563                userid = unpacked[0]; 
    511564                if (check_user_and_ip(userid, q) != 0) { 
    512                         write_dns(dns_fd, q, "BADIP", 5); 
     565                        write_dns(dns_fd, q, "BADIP", 5, 'T'); 
    513566                        return; /* illegal id */ 
    514567                } 
     
    516569                max_frag_size = ((unpacked[1] & 0xff) << 8) | (unpacked[2] & 0xff); 
    517570                if (max_frag_size < 2) {         
    518                         write_dns(dns_fd, q, "BADFRAG", 7); 
     571                        write_dns(dns_fd, q, "BADFRAG", 7, users[userid].downenc); 
    519572                } else { 
    520573                        users[userid].fragsize = max_frag_size; 
    521                         write_dns(dns_fd, q, &unpacked[1], 2); 
     574                        write_dns(dns_fd, q, &unpacked[1], 2, users[userid].downenc); 
    522575                } 
    523576                return; 
     
    530583                userid = unpacked[0]; 
    531584                if (check_user_and_ip(userid, q) != 0) { 
    532                         write_dns(dns_fd, q, "BADIP", 5); 
     585                        write_dns(dns_fd, q, "BADIP", 5, 'T'); 
    533586                        return; /* illegal id */ 
    534587                } 
     
    565618                /* Check user and sending ip number */ 
    566619                if (check_user_and_ip(userid, q) != 0) { 
    567                         write_dns(dns_fd, q, "BADIP", 5); 
     620                        write_dns(dns_fd, q, "BADIP", 5, 'T'); 
    568621                } else { 
    569622                        /* Decode data header */ 
     
    638691 
    639692        len = dns_encode_ns_response(buf, sizeof(buf), q, topdomain); 
     693        if (len < 1) { 
     694                warnx("dns_encode_ns_response doesn't fit"); 
     695                return; 
     696        } 
    640697         
    641698        if (debug >= 2) { 
     
    660717 
    661718        len = dns_encode(buf, sizeof(buf), q, QR_QUERY, q->name, strlen(q->name)); 
     719        if (len < 1) { 
     720                warnx("dns_encode doesn't fit"); 
     721                return; 
     722        } 
    662723 
    663724        /* Store sockaddr for q->id */ 
     
    756817        if (inside_topdomain) { 
    757818                /* This is a query we can handle */ 
     819 
    758820                switch (q.type) { 
    759821                case T_NULL: 
     822                case T_CNAME: 
     823                case T_A: 
     824                case T_MX: 
     825                case T_TXT: 
     826                        /* encoding is "transparent" here */ 
    760827                        handle_null_request(tun_fd, dns_fd, &q, domain_len); 
    761828                        break; 
     
    10451112 
    10461113static void 
    1047 write_dns(int fd, struct query *q, char *data, int datalen) 
     1114write_dns(int fd, struct query *q, char *data, int datalen, char downenc) 
    10481115{ 
    10491116        char buf[64*1024]; 
    1050         int len; 
    1051  
    1052         len = dns_encode(buf, sizeof(buf), q, QR_ANSWER, data, datalen); 
     1117        int len = 0; 
     1118 
     1119        if (q->type == T_CNAME || q->type == T_A || q->type == T_MX) { 
     1120                static int td1 = 0; 
     1121                static int td2 = 0; 
     1122                char cnamebuf[1024];            /* max 255 */ 
     1123                size_t space; 
     1124                char *b; 
     1125 
     1126                /* Make a rotating topdomain to prevent filtering */ 
     1127                td1+=3; 
     1128                td2+=7; 
     1129                if (td1>=26) td1-=26; 
     1130                if (td2>=25) td2-=25; 
     1131 
     1132                /* encode data,datalen to CNAME/MX answer */ 
     1133                /* (adapted from build_hostname() in iodine.c) */ 
     1134 
     1135                space = MIN(0xFF, sizeof(cnamebuf)) - 4 - 2; 
     1136                /* -1 encoding type, -3 ".xy", -2 for safety */ 
     1137 
     1138                memset(cnamebuf, 0, sizeof(cnamebuf)); 
     1139 
     1140                if (downenc == 'S') { 
     1141                        cnamebuf[0] = 'I'; 
     1142                        if (!b64->places_dots()) 
     1143                                space -= (space / 57);  /* space for dots */ 
     1144                        b64->encode(cnamebuf+1, &space, data, datalen); 
     1145                        if (!b64->places_dots()) 
     1146                                inline_dotify(cnamebuf, sizeof(cnamebuf), 57); 
     1147                } else { 
     1148                        cnamebuf[0] = 'H'; 
     1149                        if (!b32->places_dots()) 
     1150                                space -= (space / 57);  /* space for dots */ 
     1151                        b32->encode(cnamebuf+1, &space, data, datalen); 
     1152                        if (!b32->places_dots()) 
     1153                                inline_dotify(cnamebuf, sizeof(cnamebuf), 57); 
     1154                } 
     1155 
     1156                /* Add dot (if it wasn't there already) and topdomain */ 
     1157                b = cnamebuf; 
     1158                b += strlen(cnamebuf); 
     1159                if (*b != '.')  
     1160                        *b++ = '.'; 
     1161 
     1162                *b = 'a' + td1; 
     1163                b++; 
     1164                *b = 'a' + td2; 
     1165                b++; 
     1166                *b = '\0'; 
     1167 
     1168                len = dns_encode(buf, sizeof(buf), q, QR_ANSWER, cnamebuf, sizeof(cnamebuf)); 
     1169        } 
     1170        else if (q->type == T_TXT) { 
     1171                /* TXT with base32 */ 
     1172                char txtbuf[64*1024]; 
     1173                size_t space = sizeof(txtbuf) - 1;; 
     1174 
     1175                memset(txtbuf, 0, sizeof(txtbuf)); 
     1176 
     1177                if (downenc == 'S') { 
     1178                        txtbuf[0] = 'S';        /* plain base64(Sixty-four) */ 
     1179                        len = b64->encode(txtbuf+1, &space, data, datalen); 
     1180                } 
     1181                else if (downenc == 'R') { 
     1182                        txtbuf[0] = 'R';        /* Raw binary data */ 
     1183                        len = MIN(datalen, sizeof(txtbuf) - 1); 
     1184                        memcpy(txtbuf + 1, data, len); 
     1185                } else { 
     1186                        txtbuf[0] = 'T';        /* plain base32(Thirty-two) */ 
     1187                        len = b32->encode(txtbuf+1, &space, data, datalen); 
     1188                } 
     1189                len = dns_encode(buf, sizeof(buf), q, QR_ANSWER, txtbuf, len+1); 
     1190        } else { 
     1191                /* Normal NULL-record encode */ 
     1192                len = dns_encode(buf, sizeof(buf), q, QR_ANSWER, data, datalen); 
     1193        } 
     1194 
     1195        if (len < 1) { 
     1196                warnx("dns_encode doesn't fit"); 
     1197                return; 
     1198        } 
    10531199         
    10541200        if (debug >= 2) { 
     
    11671313 
    11681314        b32 = get_base32_encoder(); 
     1315        b64 = get_base64_encoder(); 
    11691316         
    11701317        retval = 0; 
Note: See TracChangeset for help on using the changeset viewer.