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:
First byte y or Y
1 char, meaning downstream codec to use
rest encoded in base32:
1 byte check variant
2 bytes CMC
5 bits coded as Base32 char, meaning check variant
CMC as 3 Base32 chars
Possibly extra data, depending on check variant
Server sends:
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] == 'V' || q.name[0] == 'v')) {
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);
return -2;
}
@ -1418,17 +1418,19 @@ send_upenctest(char *s)
static void
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;
*(uint32_t *) (hdr + 1) = rand();
/* add 3 bytes base32 CMC (random) */
uint32_t cmc = rand();
build_hostname(buf, sizeof(buf), hdr, sizeof(hdr),
this.topdomain, b32, this.hostname_maxlen, 2);
send_query(buf);
b32->encode((uint8_t *)buf + 3, &buf_space, (uint8_t *) &cmc, 2);
strncat(buf, ".", 512 - strlen(buf));
strncat(buf, this.topdomain, 512 - strlen(buf));
send_query((uint8_t *)buf);
}
static void

View File

@ -1297,23 +1297,20 @@ handle_dns_version(int dns_fd, struct query *q, uint8_t *domain, int domain_len)
void
handle_dns_downstream_codec_check(int dns_fd, struct query *q, uint8_t *domain, int domain_len)
{
int codec;
char *datap;
int datalen;
uint8_t unpacked[10];
int datalen, i, codec;
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 */
case 1:
if (i == 1) {
datap = DOWNCODECCHECK1;
datalen = DOWNCODECCHECK1_LEN;
break;
default:
} else {
write_dns(dns_fd, q, "BADLEN", 6, 'T');
return;
}
/* codec to test: first char raw */
codec = toupper(domain[1]);
switch (codec) {
case 'T':
@ -1868,19 +1865,18 @@ handle_null_request(int dns_fd, struct query *q, int domain_len)
cmd = toupper(in[0]);
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*/
handle_dns_version(dns_fd, q, in, domain_len);
return;
}
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) */
write_dns(dns_fd, q, (char *)in, domain_len, 'T');
return;
}
else if (cmd == 'Y') { /* Downstream codec check - user independent*/
else if (cmd == 'Y') { /* Downstream codec check - user independent */
handle_dns_downstream_codec_check(dns_fd, q, in, domain_len);
return;
}