Fix version check and codec check to be backwards compatible

This commit is contained in:
frekky 2016-09-24 21:39:28 +08:00
parent 8c831b0436
commit dbe9a10fc1
3 changed files with 21 additions and 24 deletions

View File

@ -100,9 +100,8 @@ Downstream codec check:
Client sends: Client sends:
First byte y or Y First byte y or Y
1 char, meaning downstream codec to use 1 char, meaning downstream codec to use
rest encoded in base32: 5 bits coded as Base32 char, meaning check variant
1 byte check variant CMC as 3 Base32 chars
2 bytes CMC
Possibly extra data, depending on check variant Possibly extra data, depending on check variant
Server sends: Server sends:
Data encoded with requested downstream codec; data content depending Data encoded with requested downstream codec; data content depending

View File

@ -862,7 +862,7 @@ handshake_waitdns(char *buf, size_t buflen, char cmd, int timeout)
(q.name[0] == 'Y' || q.name[0] == 'y' || (q.name[0] == 'Y' || q.name[0] == 'y' ||
q.name[0] == 'V' || q.name[0] == 'v')) { q.name[0] == 'V' || q.name[0] == 'v')) {
fprintf(stderr, "Got empty reply. This nameserver may not be resolving recursively, use another.\n"); fprintf(stderr, "Got empty reply. This nameserver may not be resolving recursively, use another.\n");
fprintf(stderr, "Try \"iodine [options] ns.%s %s\" first, it might just work.\n", fprintf(stderr, "Try \"iodine [options] %s ns.%s\" first, it might just work.\n",
this.topdomain, this.topdomain); this.topdomain, this.topdomain);
return -2; return -2;
} }
@ -1418,17 +1418,19 @@ send_upenctest(char *s)
static void static void
send_downenctest(char downenc, int variant) send_downenctest(char downenc, int variant)
{ {
uint8_t buf[512] = "y_____.", hdr[5]; char buf[512] = "yTaCMC.";
size_t buf_space = 4;
buf[1] = downenc; buf[1] = tolower(downenc);
buf[2] = b32_5to8(variant);
hdr[0] = variant; /* add 3 bytes base32 CMC (random) */
*(uint32_t *) (hdr + 1) = rand(); uint32_t cmc = rand();
build_hostname(buf, sizeof(buf), hdr, sizeof(hdr), b32->encode((uint8_t *)buf + 3, &buf_space, (uint8_t *) &cmc, 2);
this.topdomain, b32, this.hostname_maxlen, 2); strncat(buf, ".", 512 - strlen(buf));
strncat(buf, this.topdomain, 512 - strlen(buf));
send_query(buf); send_query((uint8_t *)buf);
} }
static void static void

View File

@ -1297,23 +1297,20 @@ handle_dns_version(int dns_fd, struct query *q, uint8_t *domain, int domain_len)
void void
handle_dns_downstream_codec_check(int dns_fd, struct query *q, uint8_t *domain, int domain_len) handle_dns_downstream_codec_check(int dns_fd, struct query *q, uint8_t *domain, int domain_len)
{ {
int codec;
char *datap; char *datap;
int datalen; int datalen, i, codec;
uint8_t unpacked[10];
unpack_data(unpacked, sizeof(unpacked), (uint8_t *)domain + 2, MIN(domain_len - 2, 4), b32); i = b32_8to5(domain[2]); /* check variant: second char in b32 */
switch (unpacked[0]) { /* check variant */ if (i == 1) {
case 1:
datap = DOWNCODECCHECK1; datap = DOWNCODECCHECK1;
datalen = DOWNCODECCHECK1_LEN; datalen = DOWNCODECCHECK1_LEN;
break; } else {
default:
write_dns(dns_fd, q, "BADLEN", 6, 'T'); write_dns(dns_fd, q, "BADLEN", 6, 'T');
return; return;
} }
/* codec to test: first char raw */
codec = toupper(domain[1]); codec = toupper(domain[1]);
switch (codec) { switch (codec) {
case 'T': case 'T':
@ -1868,14 +1865,13 @@ handle_null_request(int dns_fd, struct query *q, int domain_len)
cmd = toupper(in[0]); cmd = toupper(in[0]);
DEBUG(3, "NULL request length %d/%" L "u, command '%c'", domain_len, sizeof(in), cmd); DEBUG(3, "NULL request length %d/%" L "u, command '%c'", domain_len, sizeof(in), cmd);
/* Commands that do not care about userid */ /* Commands that do not care about userid: also these need to be backwards
* compatible with older versions of iodine (at least down to 00000502) */
if (cmd == 'V') { /* Version check - before userid is assigned*/ if (cmd == 'V') { /* Version check - before userid is assigned*/
handle_dns_version(dns_fd, q, in, domain_len); handle_dns_version(dns_fd, q, in, domain_len);
return; return;
} }
else if (cmd == 'Z') { /* Upstream codec check - user independent */ else if (cmd == 'Z') { /* Upstream codec check - user independent */
/* Check for case conservation and chars not allowed according to RFC */
/* Reply with received hostname as data (encoded in base32) */ /* Reply with received hostname as data (encoded in base32) */
write_dns(dns_fd, q, (char *)in, domain_len, 'T'); write_dns(dns_fd, q, (char *)in, domain_len, 'T');
return; return;