diff options
Diffstat (limited to 'external/unbound/sldns/parseutil.c')
-rw-r--r-- | external/unbound/sldns/parseutil.c | 726 |
1 files changed, 0 insertions, 726 deletions
diff --git a/external/unbound/sldns/parseutil.c b/external/unbound/sldns/parseutil.c deleted file mode 100644 index 32717616a..000000000 --- a/external/unbound/sldns/parseutil.c +++ /dev/null @@ -1,726 +0,0 @@ -/* - * parseutil.c - parse utilities for string and wire conversion - * - * (c) NLnet Labs, 2004-2006 - * - * See the file LICENSE for the license - */ -/** - * \file - * - * Utility functions for parsing, base32(DNS variant) and base64 encoding - * and decoding, Hex, Time units, Escape codes. - */ - -#include "config.h" -#include "sldns/parseutil.h" -#include <sys/time.h> -#include <time.h> -#include <ctype.h> - -sldns_lookup_table * -sldns_lookup_by_name(sldns_lookup_table *table, const char *name) -{ - while (table->name != NULL) { - if (strcasecmp(name, table->name) == 0) - return table; - table++; - } - return NULL; -} - -sldns_lookup_table * -sldns_lookup_by_id(sldns_lookup_table *table, int id) -{ - while (table->name != NULL) { - if (table->id == id) - return table; - table++; - } - return NULL; -} - -/* Number of days per month (except for February in leap years). */ -static const int mdays[] = { - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; - -#define LDNS_MOD(x,y) (((x) % (y) < 0) ? ((x) % (y) + (y)) : ((x) % (y))) -#define LDNS_DIV(x,y) (((x) % (y) < 0) ? ((x) / (y) - 1 ) : ((x) / (y))) - -static int -is_leap_year(int year) -{ - return LDNS_MOD(year, 4) == 0 && (LDNS_MOD(year, 100) != 0 - || LDNS_MOD(year, 400) == 0); -} - -static int -leap_days(int y1, int y2) -{ - --y1; - --y2; - return (LDNS_DIV(y2, 4) - LDNS_DIV(y1, 4)) - - (LDNS_DIV(y2, 100) - LDNS_DIV(y1, 100)) + - (LDNS_DIV(y2, 400) - LDNS_DIV(y1, 400)); -} - -/* - * Code adapted from Python 2.4.1 sources (Lib/calendar.py). - */ -time_t -sldns_mktime_from_utc(const struct tm *tm) -{ - int year = 1900 + tm->tm_year; - time_t days = 365 * ((time_t) year - 1970) + leap_days(1970, year); - time_t hours; - time_t minutes; - time_t seconds; - int i; - - for (i = 0; i < tm->tm_mon; ++i) { - days += mdays[i]; - } - if (tm->tm_mon > 1 && is_leap_year(year)) { - ++days; - } - days += tm->tm_mday - 1; - - hours = days * 24 + tm->tm_hour; - minutes = hours * 60 + tm->tm_min; - seconds = minutes * 60 + tm->tm_sec; - - return seconds; -} - -#if SIZEOF_TIME_T <= 4 - -static void -sldns_year_and_yday_from_days_since_epoch(int64_t days, struct tm *result) -{ - int year = 1970; - int new_year; - - while (days < 0 || days >= (int64_t) (is_leap_year(year) ? 366 : 365)) { - new_year = year + (int) LDNS_DIV(days, 365); - days -= (new_year - year) * 365; - days -= leap_days(year, new_year); - year = new_year; - } - result->tm_year = year; - result->tm_yday = (int) days; -} - -/* Number of days per month in a leap year. */ -static const int leap_year_mdays[] = { - 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; - -static void -sldns_mon_and_mday_from_year_and_yday(struct tm *result) -{ - int idays = result->tm_yday; - const int *mon_lengths = is_leap_year(result->tm_year) ? - leap_year_mdays : mdays; - - result->tm_mon = 0; - while (idays >= mon_lengths[result->tm_mon]) { - idays -= mon_lengths[result->tm_mon++]; - } - result->tm_mday = idays + 1; -} - -static void -sldns_wday_from_year_and_yday(struct tm *result) -{ - result->tm_wday = 4 /* 1-1-1970 was a thursday */ - + LDNS_MOD((result->tm_year - 1970), 7) * LDNS_MOD(365, 7) - + leap_days(1970, result->tm_year) - + result->tm_yday; - result->tm_wday = LDNS_MOD(result->tm_wday, 7); - if (result->tm_wday < 0) { - result->tm_wday += 7; - } -} - -static struct tm * -sldns_gmtime64_r(int64_t clock, struct tm *result) -{ - result->tm_isdst = 0; - result->tm_sec = (int) LDNS_MOD(clock, 60); - clock = LDNS_DIV(clock, 60); - result->tm_min = (int) LDNS_MOD(clock, 60); - clock = LDNS_DIV(clock, 60); - result->tm_hour = (int) LDNS_MOD(clock, 24); - clock = LDNS_DIV(clock, 24); - - sldns_year_and_yday_from_days_since_epoch(clock, result); - sldns_mon_and_mday_from_year_and_yday(result); - sldns_wday_from_year_and_yday(result); - result->tm_year -= 1900; - - return result; -} - -#endif /* SIZEOF_TIME_T <= 4 */ - -static int64_t -sldns_serial_arithmitics_time(int32_t time, time_t now) -{ - int32_t offset = time - (int32_t) now; - return (int64_t) now + offset; -} - -struct tm * -sldns_serial_arithmitics_gmtime_r(int32_t time, time_t now, struct tm *result) -{ -#if SIZEOF_TIME_T <= 4 - int64_t secs_since_epoch = sldns_serial_arithmitics_time(time, now); - return sldns_gmtime64_r(secs_since_epoch, result); -#else - time_t secs_since_epoch = sldns_serial_arithmitics_time(time, now); - return gmtime_r(&secs_since_epoch, result); -#endif -} - -int -sldns_hexdigit_to_int(char ch) -{ - switch (ch) { - case '0': return 0; - case '1': return 1; - case '2': return 2; - case '3': return 3; - case '4': return 4; - case '5': return 5; - case '6': return 6; - case '7': return 7; - case '8': return 8; - case '9': return 9; - case 'a': case 'A': return 10; - case 'b': case 'B': return 11; - case 'c': case 'C': return 12; - case 'd': case 'D': return 13; - case 'e': case 'E': return 14; - case 'f': case 'F': return 15; - default: - return -1; - } -} - -uint32_t -sldns_str2period(const char *nptr, const char **endptr) -{ - int sign = 0; - uint32_t i = 0; - uint32_t seconds = 0; - - for(*endptr = nptr; **endptr; (*endptr)++) { - switch (**endptr) { - case ' ': - case '\t': - break; - case '-': - if(sign == 0) { - sign = -1; - } else { - return seconds; - } - break; - case '+': - if(sign == 0) { - sign = 1; - } else { - return seconds; - } - break; - case 's': - case 'S': - seconds += i; - i = 0; - break; - case 'm': - case 'M': - seconds += i * 60; - i = 0; - break; - case 'h': - case 'H': - seconds += i * 60 * 60; - i = 0; - break; - case 'd': - case 'D': - seconds += i * 60 * 60 * 24; - i = 0; - break; - case 'w': - case 'W': - seconds += i * 60 * 60 * 24 * 7; - i = 0; - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - i *= 10; - i += (**endptr - '0'); - break; - default: - seconds += i; - /* disregard signedness */ - return seconds; - } - } - seconds += i; - /* disregard signedness */ - return seconds; -} - -int -sldns_parse_escape(uint8_t *ch_p, const char** str_p) -{ - uint16_t val; - - if ((*str_p)[0] && isdigit((unsigned char)(*str_p)[0]) && - (*str_p)[1] && isdigit((unsigned char)(*str_p)[1]) && - (*str_p)[2] && isdigit((unsigned char)(*str_p)[2])) { - - val = (uint16_t)(((*str_p)[0] - '0') * 100 + - ((*str_p)[1] - '0') * 10 + - ((*str_p)[2] - '0')); - - if (val > 255) { - goto error; - } - *ch_p = (uint8_t)val; - *str_p += 3; - return 1; - - } else if ((*str_p)[0] && !isdigit((unsigned char)(*str_p)[0])) { - - *ch_p = (uint8_t)*(*str_p)++; - return 1; - } -error: - *str_p = NULL; - return 0; /* LDNS_WIREPARSE_ERR_SYNTAX_BAD_ESCAPE */ -} - -/** parse one character, with escape codes */ -int -sldns_parse_char(uint8_t *ch_p, const char** str_p) -{ - switch (**str_p) { - - case '\0': return 0; - - case '\\': *str_p += 1; - return sldns_parse_escape(ch_p, str_p); - - default: *ch_p = (uint8_t)*(*str_p)++; - return 1; - } -} - -size_t sldns_b32_ntop_calculate_size(size_t src_data_length) -{ - return src_data_length == 0 ? 0 : ((src_data_length - 1) / 5 + 1) * 8; -} - -size_t sldns_b32_ntop_calculate_size_no_padding(size_t src_data_length) -{ - return ((src_data_length + 3) * 8 / 5) - 4; -} - -static int -sldns_b32_ntop_base(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz, - int extended_hex, int add_padding) -{ - size_t ret_sz; - const char* b32 = extended_hex ? "0123456789abcdefghijklmnopqrstuv" - : "abcdefghijklmnopqrstuvwxyz234567"; - - size_t c = 0; /* c is used to carry partial base32 character over - * byte boundaries for sizes with a remainder. - * (i.e. src_sz % 5 != 0) - */ - - ret_sz = add_padding ? sldns_b32_ntop_calculate_size(src_sz) - : sldns_b32_ntop_calculate_size_no_padding(src_sz); - - /* Do we have enough space? */ - if (dst_sz < ret_sz + 1) - return -1; - - /* We know the size; terminate the string */ - dst[ret_sz] = '\0'; - - /* First process all chunks of five */ - while (src_sz >= 5) { - /* 00000... ........ ........ ........ ........ */ - dst[0] = b32[(src[0] ) >> 3]; - - /* .....111 11...... ........ ........ ........ */ - dst[1] = b32[(src[0] & 0x07) << 2 | src[1] >> 6]; - - /* ........ ..22222. ........ ........ ........ */ - dst[2] = b32[(src[1] & 0x3e) >> 1]; - - /* ........ .......3 3333.... ........ ........ */ - dst[3] = b32[(src[1] & 0x01) << 4 | src[2] >> 4]; - - /* ........ ........ ....4444 4....... ........ */ - dst[4] = b32[(src[2] & 0x0f) << 1 | src[3] >> 7]; - - /* ........ ........ ........ .55555.. ........ */ - dst[5] = b32[(src[3] & 0x7c) >> 2]; - - /* ........ ........ ........ ......66 666..... */ - dst[6] = b32[(src[3] & 0x03) << 3 | src[4] >> 5]; - - /* ........ ........ ........ ........ ...77777 */ - dst[7] = b32[(src[4] & 0x1f) ]; - - src_sz -= 5; - src += 5; - dst += 8; - } - /* Process what remains */ - switch (src_sz) { - case 4: /* ........ ........ ........ ......66 666..... */ - dst[6] = b32[(src[3] & 0x03) << 3]; - - /* ........ ........ ........ .55555.. ........ */ - dst[5] = b32[(src[3] & 0x7c) >> 2]; - - /* ........ ........ ....4444 4....... ........ */ - c = src[3] >> 7 ; - case 3: dst[4] = b32[(src[2] & 0x0f) << 1 | c]; - - /* ........ .......3 3333.... ........ ........ */ - c = src[2] >> 4 ; - case 2: dst[3] = b32[(src[1] & 0x01) << 4 | c]; - - /* ........ ..22222. ........ ........ ........ */ - dst[2] = b32[(src[1] & 0x3e) >> 1]; - - /* .....111 11...... ........ ........ ........ */ - c = src[1] >> 6 ; - case 1: dst[1] = b32[(src[0] & 0x07) << 2 | c]; - - /* 00000... ........ ........ ........ ........ */ - dst[0] = b32[ src[0] >> 3]; - } - /* Add padding */ - if (add_padding) { - switch (src_sz) { - case 1: dst[2] = '='; - dst[3] = '='; - case 2: dst[4] = '='; - case 3: dst[5] = '='; - dst[6] = '='; - case 4: dst[7] = '='; - } - } - return (int)ret_sz; -} - -int -sldns_b32_ntop(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz) -{ - return sldns_b32_ntop_base(src, src_sz, dst, dst_sz, 0, 1); -} - -int -sldns_b32_ntop_extended_hex(const uint8_t* src, size_t src_sz, - char* dst, size_t dst_sz) -{ - return sldns_b32_ntop_base(src, src_sz, dst, dst_sz, 1, 1); -} - -size_t sldns_b32_pton_calculate_size(size_t src_text_length) -{ - return src_text_length * 5 / 8; -} - -static int -sldns_b32_pton_base(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz, - int extended_hex, int check_padding) -{ - size_t i = 0; - char ch = '\0'; - uint8_t buf[8]; - uint8_t* start = dst; - - while (src_sz) { - /* Collect 8 characters in buf (if possible) */ - for (i = 0; i < 8; i++) { - - do { - ch = *src++; - --src_sz; - - } while (isspace((unsigned char)ch) && src_sz > 0); - - if (ch == '=' || ch == '\0') - break; - - else if (extended_hex) - - if (ch >= '0' && ch <= '9') - buf[i] = (uint8_t)ch - '0'; - else if (ch >= 'a' && ch <= 'v') - buf[i] = (uint8_t)ch - 'a' + 10; - else if (ch >= 'A' && ch <= 'V') - buf[i] = (uint8_t)ch - 'A' + 10; - else - return -1; - - else if (ch >= 'a' && ch <= 'z') - buf[i] = (uint8_t)ch - 'a'; - else if (ch >= 'A' && ch <= 'Z') - buf[i] = (uint8_t)ch - 'A'; - else if (ch >= '2' && ch <= '7') - buf[i] = (uint8_t)ch - '2' + 26; - else - return -1; - } - /* Less that 8 characters. We're done. */ - if (i < 8) - break; - - /* Enough space available at the destination? */ - if (dst_sz < 5) - return -1; - - /* 00000... ........ ........ ........ ........ */ - /* .....111 11...... ........ ........ ........ */ - dst[0] = buf[0] << 3 | buf[1] >> 2; - - /* .....111 11...... ........ ........ ........ */ - /* ........ ..22222. ........ ........ ........ */ - /* ........ .......3 3333.... ........ ........ */ - dst[1] = buf[1] << 6 | buf[2] << 1 | buf[3] >> 4; - - /* ........ .......3 3333.... ........ ........ */ - /* ........ ........ ....4444 4....... ........ */ - dst[2] = buf[3] << 4 | buf[4] >> 1; - - /* ........ ........ ....4444 4....... ........ */ - /* ........ ........ ........ .55555.. ........ */ - /* ........ ........ ........ ......66 666..... */ - dst[3] = buf[4] << 7 | buf[5] << 2 | buf[6] >> 3; - - /* ........ ........ ........ ......66 666..... */ - /* ........ ........ ........ ........ ...77777 */ - dst[4] = buf[6] << 5 | buf[7]; - - dst += 5; - dst_sz -= 5; - } - /* Not ending on a eight byte boundary? */ - if (i > 0 && i < 8) { - - /* Enough space available at the destination? */ - if (dst_sz < (i + 1) / 2) - return -1; - - switch (i) { - case 7: /* ........ ........ ........ ......66 666..... */ - /* ........ ........ ........ .55555.. ........ */ - /* ........ ........ ....4444 4....... ........ */ - dst[3] = buf[4] << 7 | buf[5] << 2 | buf[6] >> 3; - - case 5: /* ........ ........ ....4444 4....... ........ */ - /* ........ .......3 3333.... ........ ........ */ - dst[2] = buf[3] << 4 | buf[4] >> 1; - - case 4: /* ........ .......3 3333.... ........ ........ */ - /* ........ ..22222. ........ ........ ........ */ - /* .....111 11...... ........ ........ ........ */ - dst[1] = buf[1] << 6 | buf[2] << 1 | buf[3] >> 4; - - case 2: /* .....111 11...... ........ ........ ........ */ - /* 00000... ........ ........ ........ ........ */ - dst[0] = buf[0] << 3 | buf[1] >> 2; - - break; - - default: - return -1; - } - dst += (i + 1) / 2; - - if (check_padding) { - /* Check remaining padding characters */ - if (ch != '=') - return -1; - - /* One down, 8 - i - 1 more to come... */ - for (i = 8 - i - 1; i > 0; i--) { - - do { - if (src_sz == 0) - return -1; - ch = *src++; - src_sz--; - - } while (isspace((unsigned char)ch)); - - if (ch != '=') - return -1; - } - } - } - return dst - start; -} - -int -sldns_b32_pton(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz) -{ - return sldns_b32_pton_base(src, src_sz, dst, dst_sz, 0, 1); -} - -int -sldns_b32_pton_extended_hex(const char* src, size_t src_sz, - uint8_t* dst, size_t dst_sz) -{ - return sldns_b32_pton_base(src, src_sz, dst, dst_sz, 1, 1); -} - -size_t sldns_b64_ntop_calculate_size(size_t srcsize) -{ - return ((((srcsize + 2) / 3) * 4) + 1); -} - -/* RFC 1521, section 5.2. - * - * The encoding process represents 24-bit groups of input bits as output - * strings of 4 encoded characters. Proceeding from left to right, a - * 24-bit input group is formed by concatenating 3 8-bit input groups. - * These 24 bits are then treated as 4 concatenated 6-bit groups, each - * of which is translated into a single digit in the base64 alphabet. - * - * This routine does not insert spaces or linebreaks after 76 characters. - */ -int sldns_b64_ntop(uint8_t const *src, size_t srclength, - char *target, size_t targsize) -{ - const char* b64 = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - const char pad64 = '='; - size_t i = 0, o = 0; - if(targsize < sldns_b64_ntop_calculate_size(srclength)) - return -1; - /* whole chunks: xxxxxxyy yyyyzzzz zzwwwwww */ - while(i+3 <= srclength) { - if(o+4 > targsize) return -1; - target[o] = b64[src[i] >> 2]; - target[o+1] = b64[ ((src[i]&0x03)<<4) | (src[i+1]>>4) ]; - target[o+2] = b64[ ((src[i+1]&0x0f)<<2) | (src[i+2]>>6) ]; - target[o+3] = b64[ (src[i+2]&0x3f) ]; - i += 3; - o += 4; - } - /* remainder */ - switch(srclength - i) { - case 2: - /* two at end, converted into A B C = */ - target[o] = b64[src[i] >> 2]; - target[o+1] = b64[ ((src[i]&0x03)<<4) | (src[i+1]>>4) ]; - target[o+2] = b64[ ((src[i+1]&0x0f)<<2) ]; - target[o+3] = pad64; - /* i += 2; */ - o += 4; - break; - case 1: - /* one at end, converted into A B = = */ - target[o] = b64[src[i] >> 2]; - target[o+1] = b64[ ((src[i]&0x03)<<4) ]; - target[o+2] = pad64; - target[o+3] = pad64; - /* i += 1; */ - o += 4; - break; - case 0: - default: - /* nothing */ - break; - } - /* assert: i == srclength */ - if(o+1 > targsize) return -1; - target[o] = 0; - return (int)o; -} - -size_t sldns_b64_pton_calculate_size(size_t srcsize) -{ - return (((((srcsize + 3) / 4) * 3)) + 1); -} - -int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize) -{ - const uint8_t pad64 = 64; /* is 64th in the b64 array */ - const char* s = src; - uint8_t in[4]; - size_t o = 0, incount = 0; - - while(*s) { - /* skip any character that is not base64 */ - /* conceptually we do: - const char* b64 = pad'=' is appended to array - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - const char* d = strchr(b64, *s++); - and use d-b64; - */ - char d = *s++; - if(d <= 'Z' && d >= 'A') - d -= 'A'; - else if(d <= 'z' && d >= 'a') - d = d - 'a' + 26; - else if(d <= '9' && d >= '0') - d = d - '0' + 52; - else if(d == '+') - d = 62; - else if(d == '/') - d = 63; - else if(d == '=') - d = 64; - else continue; - in[incount++] = (uint8_t)d; - if(incount != 4) - continue; - /* process whole block of 4 characters into 3 output bytes */ - if(in[3] == pad64 && in[2] == pad64) { /* A B = = */ - if(o+1 > targsize) - return -1; - target[o] = (in[0]<<2) | ((in[1]&0x30)>>4); - o += 1; - break; /* we are done */ - } else if(in[3] == pad64) { /* A B C = */ - if(o+2 > targsize) - return -1; - target[o] = (in[0]<<2) | ((in[1]&0x30)>>4); - target[o+1]= ((in[1]&0x0f)<<4) | ((in[2]&0x3c)>>2); - o += 2; - break; /* we are done */ - } else { - if(o+3 > targsize) - return -1; - /* write xxxxxxyy yyyyzzzz zzwwwwww */ - target[o] = (in[0]<<2) | ((in[1]&0x30)>>4); - target[o+1]= ((in[1]&0x0f)<<4) | ((in[2]&0x3c)>>2); - target[o+2]= ((in[2]&0x03)<<6) | in[3]; - o += 3; - } - incount = 0; - } - return (int)o; -} |