Changeset 401674
- Timestamp:
- 09/20/09 17:11:16 (3 years ago)
- 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)
- File:
-
- 1 edited
-
src/iodined.c (modified) (25 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/iodined.c
rb6eb8d r401674 69 69 static char password[33]; 70 70 static struct encoder *b32; 71 static struct encoder *b64; 71 72 static int created_users; 72 73 … … 86 87 87 88 static int read_dns(int, int, struct query *); 88 static void write_dns(int, struct query *, char *, int );89 static void write_dns(int, struct query *, char *, int, char); 89 90 static void handle_full_packet(int, int); 90 91 … … 120 121 return 1; 121 122 } 122 if (!users[userid].active ) {123 if (!users[userid].active || users[userid].disabled) { 123 124 return 1; 124 125 } … … 226 227 out[8] = userid & 0xff; 227 228 228 write_dns(fd, q, out, sizeof(out) );229 write_dns(fd, q, out, sizeof(out), users[userid].downenc); 229 230 } 230 231 … … 271 272 last, users[userid].outpacket.offset, datalen, users[userid].outpacket.len, userid); 272 273 } 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); 274 275 users[userid].q.id = 0; 275 276 … … 361 362 memcpy(&(users[userid].q), q, sizeof(struct query)); 362 363 users[userid].encoder = get_base32_encoder(); 364 users[userid].downenc = 'T'; 363 365 send_version_response(dns_fd, VERSION_ACK, users[userid].seed, userid, q); 364 366 syslog(LOG_INFO, "accepted version for user #%d from %s", 365 367 userid, inet_ntoa(tempin->sin_addr)); 366 368 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 */ 367 379 } else { 368 380 /* No space for another user */ … … 383 395 384 396 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'); 386 398 syslog(LOG_WARNING, "dropped login request from user #%d from unexpected source %s", 387 399 userid, inet_ntoa(((struct sockaddr_in *) &q->from)->sin_addr)); … … 402 414 tmp[0], tmp[1], my_mtu, netmask); 403 415 404 write_dns(dns_fd, q, out, read );416 write_dns(dns_fd, q, out, read, users[userid].downenc); 405 417 q->id = 0; 406 418 syslog(LOG_NOTICE, "accepted password from user #%d, given IP %s", userid, tmp[1]); … … 409 421 free(tmp[0]); 410 422 } else { 411 write_dns(dns_fd, q, "LNAK", 4 );423 write_dns(dns_fd, q, "LNAK", 4, 'T'); 412 424 syslog(LOG_WARNING, "rejected login request from user #%d from %s, bad password", 413 425 userid, inet_ntoa(((struct sockaddr_in *) &q->from)->sin_addr)); … … 423 435 userid = b32_8to5(in[1]); 424 436 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'); 426 438 return; /* illegal id */ 427 439 } … … 441 453 reply[3] = (addr >> 8) & 0xFF; 442 454 reply[4] = (addr >> 0) & 0xFF; 443 write_dns(dns_fd, q, reply, sizeof(reply) );455 write_dns(dns_fd, q, reply, sizeof(reply), 'T'); 444 456 } else if(in[0] == 'Z' || in[0] == 'z') { 445 457 /* Check for case conservation and chars not allowed according to RFC */ 446 458 447 459 /* 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'); 449 462 return; 450 463 } else if(in[0] == 'S' || in[0] == 's') { … … 452 465 struct encoder *enc; 453 466 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'); 455 468 return; 456 469 } … … 459 472 460 473 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'); 462 475 return; /* illegal id */ 463 476 } … … 469 482 enc = get_base32_encoder(); 470 483 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); 472 485 break; 473 486 case 6: /* 6 bits per byte = base64 */ 474 487 enc = get_base64_encoder(); 475 488 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); 477 490 break; 478 491 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); 480 527 break; 481 528 } … … 487 534 userid = (b32_8to5(in[1]) >> 1) & 15; 488 535 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'); 490 537 return; /* illegal id */ 491 538 } … … 493 540 req_frag_size = ((b32_8to5(in[1]) & 1) << 10) | ((b32_8to5(in[2]) & 31) << 5) | (b32_8to5(in[3]) & 31); 494 541 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); 496 543 } else { 497 544 char buf[2048]; 545 int i; 546 unsigned int v = (unsigned int) rand(); 498 547 499 548 memset(buf, 0, sizeof(buf)); 500 549 buf[0] = (req_frag_size >> 8) & 0xff; 501 550 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); 503 556 } 504 557 return; … … 510 563 userid = unpacked[0]; 511 564 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'); 513 566 return; /* illegal id */ 514 567 } … … 516 569 max_frag_size = ((unpacked[1] & 0xff) << 8) | (unpacked[2] & 0xff); 517 570 if (max_frag_size < 2) { 518 write_dns(dns_fd, q, "BADFRAG", 7 );571 write_dns(dns_fd, q, "BADFRAG", 7, users[userid].downenc); 519 572 } else { 520 573 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); 522 575 } 523 576 return; … … 530 583 userid = unpacked[0]; 531 584 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'); 533 586 return; /* illegal id */ 534 587 } … … 565 618 /* Check user and sending ip number */ 566 619 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'); 568 621 } else { 569 622 /* Decode data header */ … … 638 691 639 692 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 } 640 697 641 698 if (debug >= 2) { … … 660 717 661 718 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 } 662 723 663 724 /* Store sockaddr for q->id */ … … 756 817 if (inside_topdomain) { 757 818 /* This is a query we can handle */ 819 758 820 switch (q.type) { 759 821 case T_NULL: 822 case T_CNAME: 823 case T_A: 824 case T_MX: 825 case T_TXT: 826 /* encoding is "transparent" here */ 760 827 handle_null_request(tun_fd, dns_fd, &q, domain_len); 761 828 break; … … 1045 1112 1046 1113 static void 1047 write_dns(int fd, struct query *q, char *data, int datalen )1114 write_dns(int fd, struct query *q, char *data, int datalen, char downenc) 1048 1115 { 1049 1116 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 } 1053 1199 1054 1200 if (debug >= 2) { … … 1167 1313 1168 1314 b32 = get_base32_encoder(); 1315 b64 = get_base64_encoder(); 1169 1316 1170 1317 retval = 0;
Note: See TracChangeset
for help on using the changeset viewer.
