X-Git-Url: https://git.toastfreeware.priv.at/debian/iodine.git/blobdiff_plain/fd46ed085eb846701d0f8511de424e8f41cba64b..81f2f4b5b93cecc84dcf6f3c80723baefc0a07aa:/src/encoding.c?ds=sidebyside diff --git a/src/encoding.c b/src/encoding.c index 4de10c6..af7620e 100644 --- a/src/encoding.c +++ b/src/encoding.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2007 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,207 +15,116 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include #include +#include "common.h" +#include "encoding.h" -/* For FreeBSD */ -#ifndef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) -#endif +int +build_hostname(char *buf, size_t buflen, + const char *data, const size_t datalen, + const char *topdomain, struct encoder *encoder, int maxlen) +{ + size_t space; + char *b; -#define SPACING 63 -#define ENC_CHUNK 8 -#define RAW_CHUNK 5 + space = MIN((size_t)maxlen, buflen) - strlen(topdomain) - 8; + /* 8 = 5 max header length + 1 dot before topdomain + 2 safety */ -static const char base32[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ98765-"; -static const char padder[] = " 1234"; -static char reverse32[128]; -static int reverse_init = 0; + if (!encoder->places_dots()) + space -= (space / 57); /* space for dots */ -/* Eat 5 bytes from src, write 8 bytes to dest */ -static void -encode_chunk(char *dest, const char *src) -{ - unsigned char c; + memset(buf, 0, buflen); - *dest++ = base32[(*src & 0xF8) >> 3]; /* 1111 1000 first byte */ + encoder->encode(buf, &space, data, datalen); - c = (*src++ & 0x07) << 2; /* 0000 0111 first byte */ - c |= ((*src & 0xC0) >> 6); /* 1100 0000 second byte */ - *dest++ = base32[(int) c]; + if (!encoder->places_dots()) + inline_dotify(buf, buflen); - *dest++ = base32[(*src & 0x3E) >> 1]; /* 0011 1110 second byte */ + b = buf; + b += strlen(buf); - c = (*src++ & 0x01) << 4; /* 0000 0001 second byte */ - c |= ((*src & 0xF0) >> 4); /* 1111 0000 third byte */ - *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 */ + /* move b back one step to see if the dot is there */ + b--; + if (*b != '.') + *++b = '.'; + b++; + /* move b ahead of the string so we can copy to it */ - c = (*src++ & 0x03) << 3; /* 0000 0011 fourth byte */ - c |= ((*src & 0xE0) >> 5); /* 1110 0000 fifth byte */ - *dest++ = base32[(int) c]; + strncpy(b, topdomain, strlen(topdomain)+1); - *dest++ = base32[*src++ & 0x1F]; /* 0001 1111 fifth byte */ + return space; } -/* Eat 8 bytes from src, write 5 bytes to dest */ -static void -decode_chunk(char *dest, char *src) +int +unpack_data(char *buf, size_t buflen, char *data, size_t datalen, struct encoder *enc) { - unsigned char c; - int i; - - if (!reverse_init) { - for (i = 0; i < 32; i++) { - c = base32[i]; - reverse32[(int) c] = i; - } - reverse_init = 1; - } - - c = reverse32[(int) *src++] << 3; /* Take bits 11111 from byte 1 */ - c |= (reverse32[(int) *src] & 0x1C) >> 2; /* Take bits 11100 from byte 2 */ - *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; + if (!enc->eats_dots()) + datalen = inline_undotify(data, datalen); + return enc->decode(buf, &buflen, data, datalen); } int -encode_data(const char *buf, const size_t len, int space, char *dest) +inline_dotify(char *buf, size_t buflen) { - int final; - int write; - int realwrite; - int chunks; - int leftovers; - int i; - char encoded[255]; - char padding[5]; - const char *dp; - char *pp; - char *ep; - - space -= space / SPACING; - chunks = (space - 1) / ENC_CHUNK; - 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)); - ep = encoded; - 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; - *ep++ = padder[leftovers]; - encode_chunk(ep, pp); - - realwrite += ENC_CHUNK + 1; /* plus padding character */ + unsigned dots; + unsigned pos; + unsigned total; + char *reader, *writer; + + total = strlen(buf); + dots = total / 57; + + writer = buf; + writer += total; + writer += dots; + + total += dots; + if (strlen(buf) + dots > buflen) { + writer = buf; + writer += buflen; + total = buflen; } - ep = encoded; - if (len > 0) { - for (i = 1; i <= realwrite; i++) { - if (i % SPACING == 0) { - *dest++ = '.'; - } - *dest++ = *ep++; + + reader = writer - dots; + pos = (unsigned) (reader - buf) + 1; + + while (dots) { + *writer-- = *reader--; + pos--; + if (pos % 57 == 0) { + *writer-- = '.'; + dots--; } } - - return write; + + /* return new length of string */ + return total; } int -decode_data(char *dest, int size, const char *src, char *srcend) +inline_undotify(char *buf, size_t len) { - 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++; + unsigned pos; + unsigned dots; + char *reader, *writer; + + writer = buf; + reader = writer; + + pos = 0; + dots = 0; + + while (pos < len) { + if (*reader == '.') { + reader++; + pos++; + dots++; continue; } - - *ep++ = *src++; - enclen++; - } - chunks = enclen / 8; - padded = enclen % 8; - - 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; + *writer++ = *reader++; + pos++; } - return len; + /* return new length of string */ + return len - dots; } -