#6 reworked encoding

This commit is contained in:
Erik Ekman 2007-06-09 16:18:59 +00:00
parent faea33eaae
commit dbfecb5be6
10 changed files with 210 additions and 275 deletions

View file

@ -18,140 +18,160 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "encoding.h"
#include "base32.h" #include "base32.h"
static const char cb32[] = static const char cb32[] =
"abcdefghijklmnopqrstuvwxyz0123456789"; "abcdefghijklmnopqrstuvwxyz0123456789";
static unsigned char rev32[128];
static int reverse_init = 0;
static struct encoder base32_encoder =
{
"BASE32",
base32_encode,
base32_decode,
base32_handles_dots,
base32_handles_dots
};
struct encoder
*get_base32_encoder()
{
return &base32_encoder;
}
int int
base32_encode(char **buf, size_t *buflen, const void *data, size_t size) base32_handles_dots()
{
return 0;
}
int
base32_encode(char *buf, size_t *buflen, const void *data, size_t size)
{ {
size_t newsize; size_t newsize;
char *newbuf; size_t maxsize;
char *s; unsigned char *s;
char *p; unsigned char *p;
char *q; unsigned char *q;
int i; int i;
newsize = 8 * (size / 5 + 1) + 1; memset(buf, 0, *buflen);
if (newsize > *buflen) {
if ((newbuf = realloc(*buf, newsize)) == NULL) {
free(*buf);
*buf = NULL;
*buflen = 0;
return 0;
}
*buf = newbuf; /* how many chars can we encode within the buf */
*buflen = newsize; maxsize = 5 * (*buflen / 8 - 1) - 1;
/* how big will the encoded data be */
newsize = 8 * (size / 5 + 1) + 1;
/* if the buffer is too small, eat some of the data */
if (*buflen < newsize) {
size = maxsize;
} }
p = s = *buf; p = s = (unsigned char *) buf;
q = (char*)data; q = (unsigned char *)data;
for(i=0;i<size;i+=5) { for(i=0;i<size;i+=5) {
p[0] = cb32[(q[0] >> 3)]; p[0] = cb32[((q[0] & 0xf8) >> 3)];
p[1] = cb32[((q[0] & 0x07) << 2) | ((q[1] & 0xc0) >> 6)]; p[1] = cb32[(((q[0] & 0x07) << 2) | ((q[1] & 0xc0) >> 6))];
p[2] = (i+1 < size) ? cb32[((q[1] & 0x3e) >> 1)] : '\0'; p[2] = (i+1 < size) ? cb32[((q[1] & 0x3e) >> 1)] : '\0';
p[3] = (i+1 < size) ? cb32[((q[1] & 0x01) << 4) | ((q[2] & 0xf0) >> 4)] : '\0'; p[3] = (i+1 < size) ? cb32[((q[1] & 0x01) << 4) | ((q[2] & 0xf0) >> 4)] : '\0';
p[4] = (i+2 < size) ? cb32[((q[2] & 0x0f) << 1) | ((q[3] & 0x80) >> 7)] : '\0'; p[4] = (i+2 < size) ? cb32[((q[2] & 0x0f) << 1) | ((q[3] & 0x80) >> 7)] : '\0';
p[5] = (i+3 < size) ? cb32[((q[3] & 0x3e) >> 2)] : '\0'; p[5] = (i+3 < size) ? cb32[((q[3] & 0x7c) >> 2)] : '\0';
p[6] = (i+3 < size) ? cb32[((q[3] & 0x03) << 3) | ((q[4] & 0xe0) > 5)] : '\0'; p[6] = (i+3 < size) ? cb32[((q[3] & 0x03) << 3) | ((q[4] & 0xe0) >> 5)] : '\0';
p[7] = (i+4 < size) ? cb32[((q[4] & 0x1f))] : '\0'; p[7] = (i+4 < size) ? cb32[((q[4] & 0x1f))] : '\0';
q += 5; q += 5;
p += 8; p += 8;
} }
*p = 0; *p = 0;
return strlen(s);
/* store number of bytes from data that was used */
*buflen = size;
return strlen(buf) - 1;
} }
#define DECODE_ERROR 0xffffffff #define DECODE_ERROR 0xffffffff
#define REV32(x) rev32[(int) (x)]
static int static int
pos(char c) decode_token(const unsigned char *t, unsigned char *data, size_t len)
{ {
const char *p;
for (p = cb32; *p; p++)
if (*p == c)
return p - cb32;
return -1;
}
static int
decode_token(const char *t, char *data)
{
int len;
len = strlen(t);
if (len < 2) if (len < 2)
return 0; return 0;
data[0] = ((pos(t[0]) & 0x1f) << 3) | data[0] = ((REV32(t[0]) & 0x1f) << 3) |
((pos(t[1]) & 0x1c) >> 2); ((REV32(t[1]) & 0x1c) >> 2);
if (len < 4) if (len < 4)
return 1; return 1;
data[1] = ((pos(t[1]) & 0x03) << 6) | data[1] = ((REV32(t[1]) & 0x03) << 6) |
((pos(t[2]) & 0x1f) << 1) | ((REV32(t[2]) & 0x1f) << 1) |
((pos(t[3]) & 0x10) >> 4); ((REV32(t[3]) & 0x10) >> 4);
if (len < 5) if (len < 5)
return 2; return 2;
data[2] = ((pos(t[3]) & 0x0f) << 4) | data[2] = ((REV32(t[3]) & 0x0f) << 4) |
((pos(t[4]) & 0x1e) >> 1); ((REV32(t[4]) & 0x1e) >> 1);
if (len < 7) if (len < 7)
return 3; return 3;
data[3] = ((pos(t[4]) & 0x01) << 7) | data[3] = ((REV32(t[4]) & 0x01) << 7) |
((pos(t[5]) & 0x1f) << 2) | ((REV32(t[5]) & 0x1f) << 2) |
((pos(t[6]) & 0x18) >> 3); ((REV32(t[6]) & 0x18) >> 3);
if (len < 8) if (len < 8)
return 4; return 4;
data[4] = ((pos(t[6]) & 0x07) << 5) | data[4] = ((REV32(t[6]) & 0x07) << 5) |
((pos(t[7]) & 0x1f)); ((REV32(t[7]) & 0x1f));
return 5; return 5;
} }
int int
base32_decode(void **buf, size_t *buflen, const char *str) base32_decode(void *buf, size_t *buflen, const char *str, size_t slen)
{ {
unsigned char *q; unsigned char *q;
size_t newsize; size_t newsize;
size_t maxsize;
const char *p; const char *p;
char *newbuf; unsigned char c;
int len; int len;
int i;
newsize = 5 * (strlen(str) / 8 + 1) + 1;
if (newsize > *buflen) {
if ((newbuf = realloc(*buf, newsize)) == NULL) {
free(*buf);
*buf = NULL;
*buflen = 0;
return 0;
}
*buf = newbuf; if (!reverse_init) {
*buflen = newsize; for (i = 0; i < 32; i++) {
c = cb32[i];
rev32[(int) c] = i;
}
reverse_init = 1;
}
/* chars needed to decode slen */
newsize = 5 * (slen / 8 + 1) + 1;
/* encoded chars that fit in buf */
maxsize = 8 * (*buflen / 5 + 1) + 1;
/* if the buffer is too small, eat some of the data */
if (*buflen < newsize) {
slen = maxsize;
} }
q = *buf; q = buf;
for (p = str; *p && strchr(cb32, *p); p += 8) { for (p = str; *p && strchr(cb32, *p); p += 8) {
len = decode_token(p, (char *) q); len = decode_token((unsigned char *) p, (unsigned char *) q, slen);
q += len; q += len;
slen -= 8;
if (len < 5) if (len < 5)
break; break;
} }
*q = '\0'; *q = '\0';
return q - (unsigned char *) *buf; return q - (unsigned char *) buf;
} }

View file

@ -17,7 +17,9 @@
#ifndef __BASE32_H__ #ifndef __BASE32_H__
#define __BASE32_H__ #define __BASE32_H__
int base32_encode(char **, size_t *, const void *, size_t); struct encoder *get_base32_encoder(void);
int base32_decode(void **, size_t *, const char *); int base32_handles_dots();
int base32_encode(char *, size_t *, const void *, size_t);
int base32_decode(void *, size_t *, const char *, size_t);
#endif #endif

View file

@ -14,207 +14,71 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <stdio.h>
#include <strings.h>
#include <string.h> #include <string.h>
#include "encoding.h"
/* For FreeBSD */ int
#ifndef MIN inline_dotify(char *buf, size_t buflen)
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
#define SPACING 63
#define ENC_CHUNK 8
#define RAW_CHUNK 5
static const char base32[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ98765-";
static const char padder[] = " 1234";
static char reverse32[128];
static int reverse_init = 0;
/* Eat 5 bytes from src, write 8 bytes to dest */
static void
encode_chunk(char *dest, const char *src)
{ {
unsigned char c; unsigned dots;
unsigned pos;
unsigned total;
char *reader, *writer;
*dest++ = base32[(*src & 0xF8) >> 3]; /* 1111 1000 first byte */ total = strlen(buf);
dots = total / 62;
c = (*src++ & 0x07) << 2; /* 0000 0111 first byte */ writer = buf;
c |= ((*src & 0xC0) >> 6); /* 1100 0000 second byte */ writer += total;
*dest++ = base32[(int) c]; writer += dots;
*dest++ = base32[(*src & 0x3E) >> 1]; /* 0011 1110 second byte */ total += dots;
if (strlen(buf) + dots > buflen) {
writer = buf;
writer += buflen;
total = buflen;
}
c = (*src++ & 0x01) << 4; /* 0000 0001 second byte */ reader = writer - dots;
c |= ((*src & 0xF0) >> 4); /* 1111 0000 third byte */ pos = (unsigned) (reader - buf) + 1;
*dest++ = base32[(int) c];
c = (*src++ & 0x0F) << 1; /* 0000 1111 third byte */
c |= ((*src & 0x80) >> 7); /* 1000 0000 fourth byte */
*dest++ = base32[(int) c];
*dest++ = base32[(*src & 0x7C) >> 2]; /* 0111 1100 fourth byte */
c = (*src++ & 0x03) << 3; /* 0000 0011 fourth byte */ while (dots) {
c |= ((*src & 0xE0) >> 5); /* 1110 0000 fifth byte */ if (pos % 62 == 0) {
*dest++ = base32[(int) c]; *writer-- = '.';
dots--;
*dest++ = base32[*src++ & 0x1F]; /* 0001 1111 fifth byte */
}
/* Eat 8 bytes from src, write 5 bytes to dest */
static void
decode_chunk(char *dest, char *src)
{
unsigned char c;
int i;
if (!reverse_init) {
for (i = 0; i < 32; i++) {
c = base32[i];
reverse32[(int) c] = i;
} }
reverse_init = 1; *writer-- = *reader--;
pos--;
} }
c = reverse32[(int) *src++] << 3; /* Take bits 11111 from byte 1 */ /* return new length of string */
c |= (reverse32[(int) *src] & 0x1C) >> 2; /* Take bits 11100 from byte 2 */ return total;
*dest++ = c;
c = (reverse32[(int) *src++] & 0x3) << 6; /* Take bits 00011 from byte 2 */
c |= reverse32[(int) *src++] << 1; /* Take bits 11111 from byte 3 */
c |= (reverse32[(int) *src] & 0x10) >> 4; /* Take bits 10000 from byte 4 */
*dest++ = c;
c = (reverse32[(int) *src++] & 0xF) << 4; /* Take bits 01111 from byte 4 */
c |= (reverse32[(int) *src] & 0x1E) >> 1; /* Take bits 11110 from byte 5 */
*dest++ = c;
c = reverse32[(int) *src++] << 7; /* Take bits 00001 from byte 5 */
c |= reverse32[(int) *src++] << 2; /* Take bits 11111 from byte 6 */
c |= (reverse32[(int) *src] & 0x18) >> 3; /* Take bits 11000 from byte 7 */
*dest++ = c;
c = (reverse32[(int) *src++] & 0x7) << 5; /* Take bits 00111 from byte 7 */
c |= reverse32[(int) *src++]; /* Take bits 11111 from byte 8 */
*dest++ = c;
} }
int int
encode_data(const char *buf, const size_t len, int space, char *dest) inline_undotify(char *buf, size_t len)
{ {
int final; unsigned pos;
int write; unsigned dots;
int realwrite; char *reader, *writer;
int chunks;
int leftovers;
int i;
char encoded[255];
char padding[5];
const char *dp;
char *pp;
char *ep;
space -= space / SPACING; writer = buf;
chunks = (space - 1) / ENC_CHUNK; reader = writer;
while ((chunks + 1) * ENC_CHUNK + 1 > space) {
chunks--;
}
write = RAW_CHUNK * chunks;
write = MIN(write, len); /* do not use more bytes than is available; */
final = (write == len); /* is this the last block? */
chunks = write / RAW_CHUNK;
leftovers = write % RAW_CHUNK;
memset(encoded, 0, sizeof(encoded)); pos = 0;
ep = encoded; dots = 0;
dp = buf;
for (i = 0; i < chunks; i++) {
encode_chunk(ep, dp);
ep += ENC_CHUNK;
dp += RAW_CHUNK;
}
realwrite = ENC_CHUNK * chunks;
memset(padding, 0, sizeof(padding));
pp = padding;
if (leftovers) {
pp += RAW_CHUNK - leftovers;
memcpy(pp, dp, leftovers);
pp = padding; while (pos < len) {
*ep++ = padder[leftovers]; if (*reader == '.') {
encode_chunk(ep, pp); reader++;
pos++;
realwrite += ENC_CHUNK + 1; /* plus padding character */ dots++;
}
ep = encoded;
if (len > 0) {
for (i = 1; i <= realwrite; i++) {
if (i % SPACING == 0) {
*dest++ = '.';
}
*dest++ = *ep++;
}
}
return write;
}
int
decode_data(char *dest, int size, const char *src, char *srcend)
{
int len;
int i;
int chunks;
int padded;
char encoded[255];
char padding[5];
int enclen;
char *pp;
char *ep;
memset(encoded, 0, sizeof(encoded));
memset(dest, 0, size);
/* First byte is not encoded */
*dest++ = *src++;
len = 1;
ep = encoded;
enclen = 0;
while(enclen < sizeof(encoded) && src < srcend) {
if(*src == '.') {
src++;
continue; continue;
} }
*writer++ = *reader++;
*ep++ = *src++; pos++;
enclen++;
} }
chunks = enclen / 8;
padded = enclen % 8; /* return new length of string */
return len - dots;
ep = encoded;
for (i = 0; i < chunks-1; i++) {
decode_chunk(dest, ep);
dest += RAW_CHUNK;
ep += ENC_CHUNK;
len += RAW_CHUNK;
}
/* Read last chunk */
if (padded) {
pp = padding;
padded = *ep++ - '0';
decode_chunk(pp, ep);
pp += RAW_CHUNK - padded;
memcpy(dest, pp, padded);
len += padded;
} else {
decode_chunk(dest, ep);
len += RAW_CHUNK;
}
return len;
} }

View file

@ -17,7 +17,16 @@
#ifndef _ENCODING_H_ #ifndef _ENCODING_H_
#define _ENCODING_H_ #define _ENCODING_H_
int encode_data(const char *, const size_t, int, char *); int inline_dotify(char *, size_t);
int decode_data(char *, int, const char *, char *); int inline_undotify(char *, size_t);
struct encoder {
char name[8];
int (*encode) (char *, size_t *, const void *, size_t);
int (*decode) (void *, size_t *, const char *, size_t);
int (*places_dots) (void);
int (*eats_dots) (void);
};
#endif /* _ENCODING_H_ */ #endif /* _ENCODING_H_ */

View file

@ -35,6 +35,8 @@
#endif #endif
#include "common.h" #include "common.h"
#include "encoding.h"
#include "base32.h"
#include "dns.h" #include "dns.h"
#include "login.h" #include "login.h"
#include "tun.h" #include "tun.h"
@ -62,6 +64,8 @@ static int packetpos;
static int packetlen; static int packetlen;
static uint16_t chunkid; static uint16_t chunkid;
static struct encoder *enc;
static void static void
sighandler(int sig) sighandler(int sig)
{ {
@ -92,23 +96,31 @@ build_hostname(char *buf, size_t buflen,
const char *data, const size_t datalen, const char *data, const size_t datalen,
const char *topdomain) const char *topdomain)
{ {
int consumed; int encsize;
int avail; unsigned space;
char *b; char *b;
avail = MIN(0xFF, buflen) - strlen(topdomain) - 2;
memset(buf, 0, buflen);
b = buf;
consumed = encode_data(data, datalen, avail, b);
space = MIN(0xFF, buflen) - strlen(topdomain) - 2;
if (!enc->places_dots())
space -= (space / 62); /* space for dots */
memset(buf, 0, buflen);
encsize = enc->encode(buf, &space, data, datalen);
if (!enc->places_dots())
inline_dotify(buf, buflen);
b = buf;
b += strlen(buf); b += strlen(buf);
if (*b != '.') if (*b != '.')
*b++ = '.'; *b++ = '.';
strncpy(b, topdomain, strlen(topdomain)+1); strncpy(b, topdomain, strlen(topdomain)+1);
return consumed; return space;
} }
int int
@ -522,6 +534,8 @@ main(int argc, char **argv)
newroot = NULL; newroot = NULL;
device = NULL; device = NULL;
chunkid = 0; chunkid = 0;
enc = get_base32_encoder();
while ((choice = getopt(argc, argv, "vfhu:t:d:P:")) != -1) { while ((choice = getopt(argc, argv, "vfhu:t:d:P:")) != -1) {
switch(choice) { switch(choice) {

View file

@ -34,10 +34,11 @@
#include "common.h" #include "common.h"
#include "dns.h" #include "dns.h"
#include "encoding.h"
#include "base32.h"
#include "user.h" #include "user.h"
#include "login.h" #include "login.h"
#include "tun.h" #include "tun.h"
#include "encoding.h"
#include "version.h" #include "version.h"
int running = 1; int running = 1;
@ -46,6 +47,8 @@ char *topdomain;
char password[33]; char password[33];
struct encoder *b32;
int my_mtu; int my_mtu;
in_addr_t my_ip; in_addr_t my_ip;
@ -123,6 +126,14 @@ send_version_response(int fd, version_ack_t ack, uint32_t payload, struct user *
write_dns(fd, &u->q, out, sizeof(out)); write_dns(fd, &u->q, out, sizeof(out));
} }
static int
unpack_data(char *buf, size_t buflen, char *data, size_t datalen, struct encoder *enc)
{
if (!enc->eats_dots())
datalen = inline_undotify(data, datalen);
return enc->decode(buf, &buflen, data, datalen);
}
static int static int
tunnel_dns(int tun_fd, int dns_fd) tunnel_dns(int tun_fd, int dns_fd)
{ {
@ -133,6 +144,7 @@ tunnel_dns(int tun_fd, int dns_fd)
char logindata[16]; char logindata[16];
char out[64*1024]; char out[64*1024];
char in[64*1024]; char in[64*1024];
char unpacked[64*1024];
char *tmp[2]; char *tmp[2];
int userid; int userid;
int touser; int touser;
@ -145,14 +157,15 @@ tunnel_dns(int tun_fd, int dns_fd)
return 0; return 0;
if(in[0] == 'V' || in[0] == 'v') { if(in[0] == 'V' || in[0] == 'v') {
read = unpack_data(unpacked, sizeof(unpacked), &(in[1]), read - 1, b32);
/* Version greeting, compare and send ack/nak */ /* Version greeting, compare and send ack/nak */
if (read > 4) { if (read > 4) {
/* Received V + 32bits version */ /* Received V + 32bits version */
version = (((in[1] & 0xff) << 24) | version = (((unpacked[0] & 0xff) << 24) |
((in[2] & 0xff) << 16) | ((unpacked[1] & 0xff) << 16) |
((in[3] & 0xff) << 8) | ((unpacked[2] & 0xff) << 8) |
((in[4] & 0xff))); ((unpacked[3] & 0xff)));
if (version == VERSION) { if (version == VERSION) {
userid = find_available_user(); userid = find_available_user();
@ -161,6 +174,7 @@ tunnel_dns(int tun_fd, int dns_fd)
memcpy(&(users[userid].host), &(dummy.q.from), dummy.q.fromlen); memcpy(&(users[userid].host), &(dummy.q.from), dummy.q.fromlen);
memcpy(&(users[userid].q), &(dummy.q), sizeof(struct query)); memcpy(&(users[userid].q), &(dummy.q), sizeof(struct query));
users[userid].addrlen = dummy.q.fromlen; users[userid].addrlen = dummy.q.fromlen;
users[userid].encoder = get_base32_encoder();
send_version_response(dns_fd, VERSION_ACK, users[userid].seed, &users[userid]); send_version_response(dns_fd, VERSION_ACK, users[userid].seed, &users[userid]);
users[userid].q.id = 0; users[userid].q.id = 0;
} else { } else {
@ -174,8 +188,9 @@ tunnel_dns(int tun_fd, int dns_fd)
send_version_response(dns_fd, VERSION_NACK, VERSION, &dummy); send_version_response(dns_fd, VERSION_NACK, VERSION, &dummy);
} }
} else if(in[0] == 'L' || in[0] == 'l') { } else if(in[0] == 'L' || in[0] == 'l') {
read = unpack_data(unpacked, sizeof(unpacked), &(in[1]), read - 1, b32);
/* Login phase, handle auth */ /* Login phase, handle auth */
userid = in[1]; userid = unpacked[0];
if (userid < 0 || userid >= USERS) { if (userid < 0 || userid >= USERS) {
write_dns(dns_fd, &(dummy.q), "BADIP", 5); write_dns(dns_fd, &(dummy.q), "BADIP", 5);
return 0; /* illegal id */ return 0; /* illegal id */
@ -187,7 +202,7 @@ tunnel_dns(int tun_fd, int dns_fd)
memcmp(&(users[userid].host), &(dummy.q.from), dummy.q.fromlen) != 0) { memcmp(&(users[userid].host), &(dummy.q.from), dummy.q.fromlen) != 0) {
write_dns(dns_fd, &(dummy.q), "BADIP", 5); write_dns(dns_fd, &(dummy.q), "BADIP", 5);
} else { } else {
if (read >= 18 && (memcmp(logindata, in+2, 16) == 0)) { if (read >= 18 && (memcmp(logindata, unpacked+1, 16) == 0)) {
/* Login ok, send ip/mtu info */ /* Login ok, send ip/mtu info */
tempip.s_addr = my_ip; tempip.s_addr = my_ip;
@ -208,8 +223,9 @@ tunnel_dns(int tun_fd, int dns_fd)
} }
} }
} else if(in[0] == 'P' || in[0] == 'p') { } else if(in[0] == 'P' || in[0] == 'p') {
read = unpack_data(unpacked, sizeof(unpacked), &(in[1]), read - 1, b32);
/* Ping packet, store userid */ /* Ping packet, store userid */
userid = in[1]; userid = unpacked[0];
if (userid < 0 || userid >= USERS) { if (userid < 0 || userid >= USERS) {
write_dns(dns_fd, &(dummy.q), "BADIP", 5); write_dns(dns_fd, &(dummy.q), "BADIP", 5);
return 0; /* illegal id */ return 0; /* illegal id */
@ -237,12 +253,16 @@ tunnel_dns(int tun_fd, int dns_fd)
memcmp(&(users[userid].host), &(dummy.q.from), dummy.q.fromlen) != 0) { memcmp(&(users[userid].host), &(dummy.q.from), dummy.q.fromlen) != 0) {
write_dns(dns_fd, &(dummy.q), "BADIP", 5); write_dns(dns_fd, &(dummy.q), "BADIP", 5);
} else { } else {
/* decode with this users encoding */
read = unpack_data(unpacked, sizeof(unpacked), &(in[1]), read - 1,
users[userid].encoder);
users[userid].last_pkt = time(NULL); users[userid].last_pkt = time(NULL);
memcpy(&(users[userid].q), &(dummy.q), sizeof(struct query)); memcpy(&(users[userid].q), &(dummy.q), sizeof(struct query));
users[userid].addrlen = dummy.q.fromlen; users[userid].addrlen = dummy.q.fromlen;
memcpy(users[userid].inpacket.data + users[userid].inpacket.offset, in + 1, read - 1); memcpy(users[userid].inpacket.data + users[userid].inpacket.offset, unpacked, read);
users[userid].inpacket.len += read - 1; users[userid].inpacket.len += read;
users[userid].inpacket.offset += read - 1; users[userid].inpacket.offset += read;
if (code & 1) { if (code & 1) {
outlen = sizeof(out); outlen = sizeof(out);
@ -351,10 +371,11 @@ read_dns(int fd, struct query *q, char *buf, int buflen)
if (r > 0) { if (r > 0) {
dns_decode(buf, buflen, q, QR_QUERY, packet, r); dns_decode(buf, buflen, q, QR_QUERY, packet, r);
domain = strstr(q->name, topdomain); domain = strstr(q->name, topdomain);
rv = decode_data(buf, buflen, q->name, domain); rv = (int) (domain - q->name);
memcpy(buf, q->name, MIN(rv, buflen));
q->fromlen = addrlen; q->fromlen = addrlen;
memcpy((struct sockaddr*)&q->from, (struct sockaddr*)&from, addrlen); memcpy((struct sockaddr*)&q->from, (struct sockaddr*)&from, addrlen);
} else if (r < 0) { } else if (r < 0) {
/* Error */ /* Error */
perror("recvfrom"); perror("recvfrom");
rv = 0; rv = 0;
@ -438,6 +459,8 @@ main(int argc, char **argv)
listen_ip = INADDR_ANY; listen_ip = INADDR_ANY;
port = 53; port = 53;
b32 = get_base32_encoder();
memset(password, 0, 33); memset(password, 0, 33);
srand(time(NULL)); srand(time(NULL));

View file

@ -47,5 +47,6 @@ login_calculate(char *buf, int buflen, char *pass, int seed)
md5_init(&ctx); md5_init(&ctx);
md5_append(&ctx, temp, 32); md5_append(&ctx, temp, 32);
md5_finish(&ctx, (unsigned char *) buf); md5_finish(&ctx, (unsigned char *) buf);
} }

View file

@ -23,6 +23,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include "common.h" #include "common.h"
#include "encoding.h"
#include "user.h" #include "user.h"
struct user users[USERS]; struct user users[USERS];

View file

@ -30,6 +30,7 @@ struct user {
struct query q; struct query q;
struct packet inpacket; struct packet inpacket;
struct packet outpacket; struct packet outpacket;
struct encoder *encoder;
}; };
extern struct user users[USERS]; extern struct user users[USERS];

View file

@ -19,7 +19,7 @@
/* This is the version of the network protocol /* This is the version of the network protocol
It is usually equal to the latest iodine version number */ It is usually equal to the latest iodine version number */
#define VERSION 0x00000400 #define VERSION 0x00000401
#endif /* _VERSION_H_ */ #endif /* _VERSION_H_ */