diff --git a/lib/dns/Makefile.in b/lib/dns/Makefile.in index b392f74251..44f876af93 100644 --- a/lib/dns/Makefile.in +++ b/lib/dns/Makefile.in @@ -13,7 +13,7 @@ CDEFINES = CWARNINGS = OBJS = name.o rbt.o rdata.o rdatalist.o rdataset.o \ - result.o version.o rdataslab.o + result.o version.o rdataslab.o master.o SUBDIRS = include TARGETS = timestamp diff --git a/lib/dns/gen.c b/lib/dns/gen.c index 5eeb430de7..4aacc6bbca 100644 --- a/lib/dns/gen.c +++ b/lib/dns/gen.c @@ -15,7 +15,7 @@ * SOFTWARE. */ - /* $Id: gen.c,v 1.9 1999/01/20 07:14:35 marka Exp $ */ + /* $Id: gen.c,v 1.10 1999/01/27 13:38:18 marka Exp $ */ #include @@ -166,7 +166,7 @@ doswitch(char *name, char *function, char *args, } if (subswitch) { fprintf(stdout, "\t\tdefault: %s; break; \\\n", res); - fputs(/*{*/ "\t\t}\n", stdout); + fputs(/*{*/ "\t\t} \\\n", stdout); fputs("\t\tbreak; \\\n", stdout); } if (first) diff --git a/lib/dns/include/dns/master.h b/lib/dns/include/dns/master.h new file mode 100644 index 0000000000..249c85203b --- /dev/null +++ b/lib/dns/include/dns/master.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 1999 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifndef DNS_MASTER_H +#define DNS_MASTER_H 1 + +#include + +#include +#include +#include +#include + +dns_result_t dns_load_master(char *master_file, + dns_name_t *origin, + dns_rdataclass_t class, + dns_result_t (*callback)(dns_name_t *owner, + dns_rdataset_t *dataset), + isc_mem_t *mctx); +#endif /* DNS_MASTER_H */ diff --git a/lib/dns/include/dns/result.h b/lib/dns/include/dns/result.h index 9c44c225c9..7a7050d7a1 100644 --- a/lib/dns/include/dns/result.h +++ b/lib/dns/include/dns/result.h @@ -43,8 +43,9 @@ typedef unsigned int dns_result_t; #define DNS_R_RANGE 20 #define DNS_R_EXISTS 21 #define DNS_R_NOTFOUND 22 +#define DNS_R_SYNTAX 23 -#define DNS_R_LASTENTRY 22 /* Last entry on list. */ +#define DNS_R_LASTENTRY 23 /* Last entry on list. */ #define DNS_R_UNEXPECTED 0xFFFFFFFFL diff --git a/lib/dns/master.c b/lib/dns/master.c new file mode 100644 index 0000000000..078d9b6d08 --- /dev/null +++ b/lib/dns/master.c @@ -0,0 +1,457 @@ +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef ISC_LIST(dns_rdatalist_t) rdatalist_head_t; + +static dns_result_t commit(rdatalist_head_t *, dns_name_t *, + dns_result_t (*)(dns_name_t *, + dns_rdataset_t *)); +static isc_boolean_t is_glue(rdatalist_head_t *, dns_name_t *); +static dns_rdatalist_t *grow_rdatalist(int, dns_rdatalist_t *, int, + rdatalist_head_t *, + rdatalist_head_t *, + isc_mem_t *mctx); +static dns_rdata_t *grow_rdata(int, dns_rdata_t *, int, + rdatalist_head_t *, rdatalist_head_t *, + isc_mem_t *); + + +dns_result_t +dns_load_master(char *master_file, dns_name_t *origin, + dns_rdataclass_t zclass, dns_result_t (*callback)(), + isc_mem_t *mctx) +{ + dns_rdataclass_t class; + dns_rdatatype_t type; + unsigned long ttl = 0; + dns_name_t current_name; + dns_name_t glue_name; + dns_name_t new_name; + isc_boolean_t ttl_known = ISC_FALSE; + isc_boolean_t current_known = ISC_FALSE; + isc_boolean_t in_glue = ISC_FALSE; + isc_boolean_t current_has_delegation = ISC_FALSE; + isc_boolean_t done = ISC_FALSE; + isc_token_t token; + isc_lex_t *lex = NULL; + dns_result_t result = DNS_R_UNEXPECTED; + rdatalist_head_t glue_list; + rdatalist_head_t current_list; + unsigned int options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF; + dns_rdatalist_t *this; + dns_rdatalist_t *rdatalist = NULL; + dns_rdatalist_t *new_rdatalist; + int rdlcount = 0; + int rdlcount_save = 0; + int rdatalist_size = 0; + isc_result_t lexres; + isc_buffer_t buffer; + isc_buffer_t target; + isc_buffer_t target_save; + dns_rdata_t *rdata = NULL; + dns_rdata_t *new_rdata; + int rdcount = 0; + int rdcount_save = 0; + int rdata_size = 0; + unsigned char *target_mem = NULL; + int target_size = 64*1024; + + dns_name_init(¤t_name, NULL); + dns_name_init(&glue_name, NULL); + + ISC_LIST_INIT(glue_list); + ISC_LIST_INIT(current_list); + + if (isc_lex_create(mctx, 256, &lex) != ISC_R_SUCCESS) + goto cleanup; + + if (isc_lex_openfile(lex, master_file) != ISC_R_SUCCESS) + goto cleanup; + + target_mem = isc_mem_get(mctx, target_size); + if (target_mem == NULL) { + result = DNS_R_NOSPACE; + goto cleanup; + } + isc_buffer_init(&target, target_mem, target_size, + ISC_BUFFERTYPE_BINARY); + target_save = target; + do { + options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF | + ISC_LEXOPT_INITIALWS | ISC_LEXOPT_DNSMULTILINE; + lexres = isc_lex_gettoken(lex, options, &token); + if (lexres != ISC_R_SUCCESS) { + result = DNS_R_UNEXPECTED; + goto cleanup; + } + + if (token.type == isc_tokentype_eof) { + done = ISC_TRUE; + continue; + } + + if (token.type == isc_tokentype_eol) + continue; /* blank line */ + + if (token.type == isc_tokentype_initialws) { + if (!current_known) { + result = DNS_R_UNKNOWN; + goto cleanup; + } + /* still working on the same name */ + } else if (token.type == isc_tokentype_string) { + + /* XXX "$" Support */ + + dns_name_init(&new_name, NULL); + isc_buffer_init(&buffer, token.value.as_region.base, + token.value.as_region.length, + ISC_BUFFERTYPE_TEXT); + isc_buffer_add(&buffer, token.value.as_region.length); + isc_buffer_setactive(&buffer, + token.value.as_region.length); + /* XXX name memory */ + result = dns_name_fromtext(&new_name, &buffer, + origin, ISC_FALSE, &target); + + if (result != DNS_R_SUCCESS) + goto cleanup; + /* + * commit glue and pop stacks + */ + if (in_glue && dns_name_compare(&glue_name, + &new_name) != 0) { + result = commit(&glue_list, + &glue_name, callback); + if (result != DNS_R_SUCCESS) + goto cleanup; + dns_name_invalidate(&glue_name); + in_glue = ISC_FALSE; + rdcount = rdcount_save; + rdlcount = rdlcount_save; + target = target_save; + } + + if (!current_known || + dns_name_compare(¤t_name, &new_name) != 0) { + if (current_has_delegation && + is_glue(¤t_list, &new_name)) { + in_glue = ISC_TRUE; + rdcount_save = rdcount; + rdlcount_save = rdlcount; + target_save = target; + glue_name = new_name; + } else { + result = commit(¤t_list, + ¤t_name, + callback); + if (result != DNS_R_SUCCESS) + goto cleanup; + rdcount = 0; + rdlcount = 0; + current_name = new_name; + current_known = ISC_TRUE; + current_has_delegation = ISC_FALSE; + } + } + } else { + result = DNS_R_UNEXPECTED; + goto cleanup; + } + + type = 0; + class = 0; + + options = ISC_LEXOPT_NUMBER | ISC_LEXOPT_DNSMULTILINE; + if (isc_lex_gettoken(lex, options, &token) != ISC_R_SUCCESS) { + result = DNS_R_UNEXPECTED; + goto cleanup; + } + options = ISC_LEXOPT_DNSMULTILINE; + + if (token.type == isc_tokentype_number) { + ttl = token.value.as_ulong; + ttl_known = ISC_TRUE; + if (isc_lex_gettoken(lex, options, &token) != + ISC_R_SUCCESS) { + result = DNS_R_UNEXPECTED; + goto cleanup; + } + } else if (!ttl_known) { + result = DNS_R_UNEXPECTED; + goto cleanup; + } + + if (token.type != isc_tokentype_string) { + result = DNS_R_UNEXPECTED; + goto cleanup; + } + + if (dns_rdataclass_fromtext(&class, &token.value.as_textregion) + == DNS_R_SUCCESS) { + + if (isc_lex_gettoken(lex, options, &token) != + ISC_R_SUCCESS) { + result = DNS_R_UNEXPECTED; + goto cleanup; + } + } + + if (token.type != isc_tokentype_string) { + result = DNS_R_UNEXPECTED; + goto cleanup; + } + + if (dns_rdatatype_fromtext(&type, &token.value.as_textregion) + != DNS_R_SUCCESS) { + result = DNS_R_UNEXPECTED; + goto cleanup; + } + + if (class != 0 && class != zclass) { + result = DNS_R_UNEXPECTED; + goto cleanup; + } + + if (type == 2 && !in_glue) + current_has_delegation = ISC_TRUE; + if (in_glue) + this = ISC_LIST_HEAD(glue_list); + else + this = ISC_LIST_HEAD(current_list); + + while ((this = ISC_LIST_HEAD(current_list)) != NULL) { + if (this->type == type) + break; + this = ISC_LIST_NEXT(this, link); + } + if (this == NULL) { + if (rdlcount == rdatalist_size) { + new_rdatalist = + grow_rdatalist(rdatalist_size + 32, + rdatalist, + rdatalist_size, + ¤t_list, + &glue_list, + mctx); + if (new_rdatalist == NULL) { + result = DNS_R_NOSPACE; + goto cleanup; + } + rdatalist = new_rdatalist; + rdatalist_size += 32; + } + this = &rdatalist[rdlcount++]; + this->type = type; + this->class = zclass; + this->ttl = ttl; + ISC_LIST_INIT(this->rdata); + ISC_LINK_INIT(this, link); + if (in_glue) + ISC_LIST_PREPEND(glue_list, this, link); + else + ISC_LIST_PREPEND(current_list, this, link); + } + if (rdcount == rdata_size) { + new_rdata = grow_rdata(rdata_size + 512, rdata, + rdata_size, ¤t_list, + &glue_list, mctx); + if (new_rdata == NULL) { + result = DNS_R_NOSPACE; + goto cleanup; + } + rdata_size += 512; + rdata = new_rdata; + } + result = dns_rdata_fromtext(&rdata[rdcount], class, type, + lex, origin, ISC_FALSE, &target); + if (result != DNS_R_SUCCESS) + goto cleanup; + ISC_LIST_PREPEND(this->rdata, &rdata[rdcount], link); + rdcount++; + } while (!done); + result = commit(¤t_list, ¤t_name, callback); + if (result != DNS_R_SUCCESS) + goto cleanup; + result = commit(&glue_list, &glue_name, callback); + if (result != DNS_R_SUCCESS) + goto cleanup; + result = DNS_R_SUCCESS; + + cleanup: + if (lex != NULL) { + isc_lex_close(lex); + isc_lex_destroy(&lex); + } + while ((this = ISC_LIST_HEAD(current_list)) != NULL) + ISC_LIST_UNLINK(current_list, this, link); + while ((this = ISC_LIST_HEAD(glue_list)) != NULL) + ISC_LIST_UNLINK(glue_list, this, link); + if (rdatalist != NULL) + isc_mem_put(mctx, rdatalist, + rdatalist_size * sizeof *rdatalist); + if (rdata != NULL) + isc_mem_put(mctx, rdata, rdata_size * sizeof *rdata); + if (target_mem) + isc_mem_put(mctx, target_mem, target_size); + return (result); +} + +static dns_rdatalist_t * +grow_rdatalist(int new_len, dns_rdatalist_t *old, int old_len, + rdatalist_head_t *current, rdatalist_head_t *glue, + isc_mem_t *mctx) +{ + dns_rdatalist_t *new; + int rdlcount = 0; + ISC_LIST(dns_rdatalist_t) save; + dns_rdatalist_t *this; + + new = isc_mem_get(mctx, new_len * sizeof *new); + if (new == NULL) + return (NULL); + + ISC_LIST_INIT(save); + this = ISC_LIST_HEAD(*current); + while ((this = ISC_LIST_HEAD(*current)) != NULL) { + ISC_LIST_UNLINK(*current, this, link); + ISC_LIST_APPEND(save, this, link); + } + while ((this = ISC_LIST_HEAD(save)) != NULL) { + ISC_LIST_UNLINK(save, this, link); + new[rdlcount] = *this; + ISC_LIST_APPEND(*current, &new[rdlcount], link); + rdlcount++; + } + + ISC_LIST_INIT(save); + this = ISC_LIST_HEAD(*glue); + while ((this = ISC_LIST_HEAD(*glue)) != NULL) { + ISC_LIST_UNLINK(*glue, this, link); + ISC_LIST_APPEND(save, this, link); + } + while ((this = ISC_LIST_HEAD(save)) != NULL) { + ISC_LIST_UNLINK(save, this, link); + new[rdlcount] = *this; + ISC_LIST_APPEND(*glue, &new[rdlcount], link); + rdlcount++; + } + + INSIST(rdlcount == old_len); + if (old != NULL) + isc_mem_put(mctx, old, old_len * sizeof *old); + return (new); +} + +static dns_rdata_t * +grow_rdata(int new_len, dns_rdata_t *old, int old_len, + rdatalist_head_t *current, rdatalist_head_t *glue, + isc_mem_t *mctx) +{ + dns_rdata_t *new; + int rdcount = 0; + ISC_LIST(dns_rdata_t) save; + dns_rdatalist_t *this; + dns_rdata_t *rdata; + + new = isc_mem_get(mctx, new_len * sizeof *new); + if (new == NULL) + return (NULL); + memset(new, 0, new_len * sizeof *new); + /* copy current relinking */ + this = ISC_LIST_HEAD(*current); + while (this != NULL) { + ISC_LIST_INIT(save); + while ((rdata = ISC_LIST_HEAD(this->rdata)) != NULL) { + ISC_LIST_UNLINK(this->rdata, rdata, link); + ISC_LIST_APPEND(save, rdata, link); + } + while ((rdata = ISC_LIST_HEAD(save)) != NULL) { + ISC_LIST_UNLINK(save, rdata, link); + new[rdcount] = *rdata; + ISC_LIST_APPEND(this->rdata, &new[rdcount], link); + rdcount++; + } + this = ISC_LIST_NEXT(this, link); + } + /* copy glue relinking */ + this = ISC_LIST_HEAD(*glue); + while (this != NULL) { + ISC_LIST_INIT(save); + while ((rdata = ISC_LIST_HEAD(this->rdata)) != NULL) { + ISC_LIST_UNLINK(this->rdata, rdata, link); + ISC_LIST_APPEND(save, rdata, link); + } + while ((rdata = ISC_LIST_HEAD(save)) != NULL) { + ISC_LIST_UNLINK(save, rdata, link); + new[rdcount] = *rdata; + ISC_LIST_APPEND(this->rdata, &new[rdcount], link); + rdcount++; + } + this = ISC_LIST_NEXT(this, link); + } + INSIST(rdcount == old_len); + if (old != NULL) + isc_mem_put(mctx, old, old_len * sizeof *old); + return (new); +} + +static dns_result_t +commit(rdatalist_head_t *head, dns_name_t *owner, dns_result_t (*callback)()) { + dns_rdatalist_t *this; + dns_rdataset_t dataset; + dns_result_t result; + + while ((this = ISC_LIST_HEAD(*head)) != NULL) { + + dns_rdataset_init(&dataset); + dns_rdatalist_tordataset(this, &dataset); + result = ((*callback)(owner, &dataset)); + if (result != DNS_R_SUCCESS) + return (result); + ISC_LIST_UNLINK(*head, this, link); + } + return (DNS_R_SUCCESS); +} + +static isc_boolean_t +is_glue(rdatalist_head_t *head, dns_name_t *owner) { + dns_rdatalist_t *this; + dns_rdata_t *rdata; + isc_region_t region; + dns_name_t name; + + /* find NS rrset */ + this = ISC_LIST_HEAD(*head); + while (this != NULL) { + if (this->type == 2) + break; + this = ISC_LIST_NEXT(this, link); + } + if (this == NULL) + return (ISC_FALSE); + + rdata = ISC_LIST_HEAD(this->rdata); + while (rdata != NULL) { + dns_name_init(&name, NULL); + dns_rdata_toregion(rdata, ®ion); + dns_name_fromregion(&name, ®ion); + if (dns_name_compare(&name, owner) == 0) + return (ISC_TRUE); + } + return (ISC_FALSE); +} diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c index 7e1908478e..5ba918c739 100644 --- a/lib/dns/rdata.c +++ b/lib/dns/rdata.c @@ -15,7 +15,7 @@ * SOFTWARE. */ - /* $Id: rdata.c,v 1.14 1999/01/27 06:07:57 halley Exp $ */ + /* $Id: rdata.c,v 1.15 1999/01/27 13:38:18 marka Exp $ */ #include @@ -51,9 +51,9 @@ static isc_boolean_t buffer_empty(isc_buffer_t *source); static void buffer_fromregion(isc_buffer_t *buffer, isc_region_t *region, unsigned int type); -static isc_result_t uint32_tobuffer(unsigned long value, +static dns_result_t uint32_tobuffer(unsigned long value, isc_buffer_t *target); -static isc_result_t uint16_tobuffer(unsigned long value, +static dns_result_t uint16_tobuffer(unsigned long value, isc_buffer_t *target); static unsigned long uint32_fromregion(isc_region_t *region); static unsigned short uint16_fromregion(isc_region_t *region); @@ -62,6 +62,17 @@ static dns_result_t gettoken(isc_lex_t *lexer, isc_token_t *token, static dns_result_t mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length); static int compare_region(isc_region_t *r1, isc_region_t *r2); +static int hexvalue(char value); +static dns_result_t base64_totext(isc_region_t *source, + isc_buffer_t *target); +static dns_result_t base64_tobuffer(isc_lex_t *lexer, + isc_buffer_t *target); +static dns_result_t time_totext(unsigned long value, + isc_buffer_t *target); + +static const char hexdigits[] = "0123456789abcdef"; +static const char decdigits[] = "0123456789"; +static const char octdigits[] = "01234567"; #include "code.h" @@ -70,6 +81,7 @@ static int compare_region(isc_region_t *r1, isc_region_t *r2); #define METATYPES \ { 0, "NONE", META }, \ + { 23, "NSAP-PTR", RESERVED }, \ { 100, "UINFO", RESERVED }, \ { 101, "UID", RESERVED }, \ { 102, "GID", RESERVED }, \ @@ -556,7 +568,7 @@ buffer_fromregion(isc_buffer_t *buffer, isc_region_t *region, isc_buffer_setactive(buffer, region->length); } -static isc_result_t +static dns_result_t uint32_tobuffer(unsigned long value, isc_buffer_t *target) { isc_region_t region; @@ -571,7 +583,7 @@ uint32_tobuffer(unsigned long value, isc_buffer_t *target) { return (DNS_R_SUCCESS); } -static isc_result_t +static dns_result_t uint16_tobuffer(unsigned long value, isc_buffer_t *target) { isc_region_t region; @@ -609,7 +621,8 @@ uint16_fromregion(isc_region_t *region) { static dns_result_t gettoken(isc_lex_t *lexer, isc_token_t *token, isc_tokentype_t expect, isc_boolean_t eol) { - unsigned int options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF; + unsigned int options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF | + ISC_LEXOPT_DNSMULTILINE; if (expect == isc_tokentype_qstring) options |= ISC_LEXOPT_QSTRING; @@ -657,3 +670,108 @@ compare_region(isc_region_t *r1, isc_region_t *r2) { else return ((r1->length < r2->length) ? -1 : 1); } + +static int +hexvalue(char value) { + char *s; + if (!isascii(value&0xff)) + return (-1); + if (isupper(value)) + value = tolower(value); + if ((s = strchr(hexdigits, value)) == NULL) + return (-1); + return (s - hexdigits); +} + +static const char base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + +static dns_result_t +base64_totext(isc_region_t *source, isc_buffer_t *target) { + char buf[5]; + int loops = 0; + + memset(buf, 0, sizeof buf); + RETERR(str_totext("( " /*)*/, target)); + while (source->length > 2) { + buf[0] = base64[(source->base[0]>>2)&0x3f]; + buf[1] = base64[((source->base[0]<<4)&0x30)| + ((source->base[1]>>4)&0x0f)]; + buf[2] = base64[((source->base[1]<<4)&0x3c)| + ((source->base[2]>>6)&0x03)]; + buf[3] = base64[source->base[2]&0x3f]; + RETERR(str_totext(buf, target)); + isc_region_consume(source, 3); + if (source->length != 0 && ++loops == 15) { + loops = 0; + RETERR(str_totext(" ", target)); + } + } + if (source->length == 2) { + buf[0] = base64[(source->base[0]>>2)&0x3f]; + buf[1] = base64[((source->base[0]<<4)&0x30)| + ((source->base[1]>>4)&0x0f)]; + buf[2] = base64[((source->base[1]<<4)&0x3c)]; + buf[3] = '='; + RETERR(str_totext(buf, target)); + } else if (source->length == 1) { + buf[0] = base64[(source->base[0]>>2)&0x3f]; + buf[1] = base64[((source->base[0]<<4)&0x30)]; + buf[2] = buf[3] = '='; + RETERR(str_totext(buf, target)); + } + RETERR(str_totext(" )", target)); + return (DNS_R_SUCCESS); +} + +static dns_result_t +base64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target) { + int digits = 0; + isc_textregion_t *tr; + int val[4]; + unsigned char buf[3]; + int seen_end = 0; + unsigned int i; + isc_token_t token; + char *s; + int n; + + + while (1) { + RETERR(gettoken(lexer, &token, isc_tokentype_string, ISC_TRUE)); + if (token.type != isc_tokentype_string) + break; + tr = &token.value.as_textregion; + for (i = 0 ;i < tr->length; i++) { + if (seen_end) + return (DNS_R_SYNTAX); + if ((s = strchr(base64, tr->base[i])) == NULL) + return (DNS_R_SYNTAX); + val[digits++] = s - base64; + if (digits == 4) { + if (val[1] == 64 || val[2] == 64) + return (DNS_R_SYNTAX); + if (val[2] == 64 && val[3] != 64) + return (DNS_R_SYNTAX); + buf[0] = (val[0]<<2)|(val[1]>>4); + buf[1] = (val[1]<<4)|(val[2]>>2); + buf[2] = (val[2]<<2)|(val[3]); + n = (val[2] == 64) ? 1 : + (val[3] == 64) ? 2 : 3; + RETERR(mem_tobuffer(target, buf, n)); + digits = 0; + if (val[2] == 64 || val[3] != 64) + seen_end = 1; + } + } + } + isc_lex_ungettoken(lexer, &token); + if (digits) + return (DNS_R_SYNTAX); + return (DNS_R_SUCCESS); +} + +static dns_result_t +time_totext(unsigned long value, isc_buffer_t *target) { + return (DNS_R_NOTIMPLEMENTED); +} diff --git a/lib/dns/rdata/generic/key_25.c b/lib/dns/rdata/generic/key_25.c new file mode 100644 index 0000000000..08b3f4a4b6 --- /dev/null +++ b/lib/dns/rdata/generic/key_25.c @@ -0,0 +1,172 @@ +/* + * Copyright (C) 1999 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + + /* $Id: key_25.c,v 1.1 1999/01/27 13:38:20 marka Exp $ */ + + /* RFC 2065 */ + +#ifndef RDATA_GENERIC_KEY_25_H +#define RDATA_GENERIC_KEY_25_H + +static dns_result_t +fromtext_key(dns_rdataclass_t class, dns_rdatatype_t type, + isc_lex_t *lexer, dns_name_t *origin, + isc_boolean_t downcase, isc_buffer_t *target) { + isc_token_t token; + unsigned char c; + unsigned int flags; + + REQUIRE(type == 25); + + class = class; /*unused*/ + origin = origin; /*unused*/ + downcase = downcase; /*unused*/ + + RETERR(gettoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); + if (token.value.as_ulong > 0xffff) + return (DNS_R_RANGE); + RETERR(uint16_tobuffer(token.value.as_ulong, target)); + flags = token.value.as_ulong; + + RETERR(gettoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); + if (token.value.as_ulong > 0xff) + return (DNS_R_RANGE); + c = token.value.as_ulong; + RETERR(mem_tobuffer(target, &c, 1)); + + RETERR(gettoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); + if (token.value.as_ulong > 0xff) + return (DNS_R_RANGE); + c = token.value.as_ulong; + RETERR(mem_tobuffer(target, &c, 1)); + + /* No Key? */ + if ((flags & 0xc000) == 0xc000) + return (DNS_R_SUCCESS); + + return (base64_tobuffer(lexer, target)); +} + +static dns_result_t +totext_key(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target) { + isc_region_t sr; + char buf[sizeof "64000"]; + unsigned int flags; + + REQUIRE(rdata->type == 25); + + origin = origin; /*unused*/ + + dns_rdata_toregion(rdata, &sr); + + /* flags */ + flags = uint16_fromregion(&sr); + isc_region_consume(&sr, 2); + sprintf(buf, "%u", flags); + RETERR(str_totext(buf, target)); + RETERR(str_totext(" ", target)); + + /* protocol */ + sprintf(buf, "%u", sr.base[0]); + isc_region_consume(&sr, 1); + RETERR(str_totext(buf, target)); + RETERR(str_totext(" ", target)); + + /* algorithm */ + sprintf(buf, "%u", sr.base[0]); + isc_region_consume(&sr, 1); + RETERR(str_totext(buf, target)); + + /* No Key? */ + if ((flags & 0xc000) == 0xc00) + return (DNS_R_SUCCESS); + + /* key */ + RETERR(str_totext(" ", target)); + return (base64_totext(&sr, target)); +} + +static dns_result_t +fromwire_key(dns_rdataclass_t class, dns_rdatatype_t type, + isc_buffer_t *source, dns_decompress_t *dctx, + isc_boolean_t downcase, isc_buffer_t *target) { + isc_region_t sr; + + REQUIRE(type == 25); + + class = class; /*unused*/ + dctx = dctx; /*unused*/ + downcase = downcase; /*unused*/ + + isc_buffer_active(source, &sr); + if (sr.length < 4) + return (DNS_R_UNEXPECTEDEND); + + isc_buffer_forward(source, sr.length); + return (mem_tobuffer(target, sr.base, sr.length)); +} + +static dns_result_t +towire_key(dns_rdata_t *rdata, dns_compress_t *cctx, isc_buffer_t *target) { + isc_region_t sr; + + REQUIRE(rdata->type == 25); + + cctx = cctx; /*unused*/ + + dns_rdata_toregion(rdata, &sr); + return (mem_tobuffer(target, sr.base, sr.length)); +} + +static int +compare_key(dns_rdata_t *rdata1, dns_rdata_t *rdata2) { + isc_region_t r1; + isc_region_t r2; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->class == rdata2->class); + REQUIRE(rdata1->type == 25); + + dns_rdata_toregion(rdata1, &r1); + dns_rdata_toregion(rdata2, &r2); + return (compare_region(&r1, &r2)); +} + +static dns_result_t +fromstruct_key(dns_rdataclass_t class, dns_rdatatype_t type, void *source, + isc_buffer_t *target) { + + REQUIRE(type == 25); + + class = class; /*unused*/ + + source = source; + target = target; + + return (DNS_R_NOTIMPLEMENTED); +} + +static dns_result_t +tostruct_key(dns_rdata_t *rdata, void *target) { + + REQUIRE(rdata->type == 25); + + target = target; + + return (DNS_R_NOTIMPLEMENTED); +} +#endif /* RDATA_GENERIC_KEY_25_H */ diff --git a/lib/dns/rdata/generic/key_25.h b/lib/dns/rdata/generic/key_25.h new file mode 100644 index 0000000000..ca65498f12 --- /dev/null +++ b/lib/dns/rdata/generic/key_25.h @@ -0,0 +1,172 @@ +/* + * Copyright (C) 1999 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + + /* $Id: key_25.h,v 1.1 1999/01/27 13:38:20 marka Exp $ */ + + /* RFC 2065 */ + +#ifndef RDATA_GENERIC_KEY_25_H +#define RDATA_GENERIC_KEY_25_H + +static dns_result_t +fromtext_key(dns_rdataclass_t class, dns_rdatatype_t type, + isc_lex_t *lexer, dns_name_t *origin, + isc_boolean_t downcase, isc_buffer_t *target) { + isc_token_t token; + unsigned char c; + unsigned int flags; + + REQUIRE(type == 25); + + class = class; /*unused*/ + origin = origin; /*unused*/ + downcase = downcase; /*unused*/ + + RETERR(gettoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); + if (token.value.as_ulong > 0xffff) + return (DNS_R_RANGE); + RETERR(uint16_tobuffer(token.value.as_ulong, target)); + flags = token.value.as_ulong; + + RETERR(gettoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); + if (token.value.as_ulong > 0xff) + return (DNS_R_RANGE); + c = token.value.as_ulong; + RETERR(mem_tobuffer(target, &c, 1)); + + RETERR(gettoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); + if (token.value.as_ulong > 0xff) + return (DNS_R_RANGE); + c = token.value.as_ulong; + RETERR(mem_tobuffer(target, &c, 1)); + + /* No Key? */ + if ((flags & 0xc000) == 0xc000) + return (DNS_R_SUCCESS); + + return (base64_tobuffer(lexer, target)); +} + +static dns_result_t +totext_key(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target) { + isc_region_t sr; + char buf[sizeof "64000"]; + unsigned int flags; + + REQUIRE(rdata->type == 25); + + origin = origin; /*unused*/ + + dns_rdata_toregion(rdata, &sr); + + /* flags */ + flags = uint16_fromregion(&sr); + isc_region_consume(&sr, 2); + sprintf(buf, "%u", flags); + RETERR(str_totext(buf, target)); + RETERR(str_totext(" ", target)); + + /* protocol */ + sprintf(buf, "%u", sr.base[0]); + isc_region_consume(&sr, 1); + RETERR(str_totext(buf, target)); + RETERR(str_totext(" ", target)); + + /* algorithm */ + sprintf(buf, "%u", sr.base[0]); + isc_region_consume(&sr, 1); + RETERR(str_totext(buf, target)); + + /* No Key? */ + if ((flags & 0xc000) == 0xc00) + return (DNS_R_SUCCESS); + + /* key */ + RETERR(str_totext(" ", target)); + return (base64_totext(&sr, target)); +} + +static dns_result_t +fromwire_key(dns_rdataclass_t class, dns_rdatatype_t type, + isc_buffer_t *source, dns_decompress_t *dctx, + isc_boolean_t downcase, isc_buffer_t *target) { + isc_region_t sr; + + REQUIRE(type == 25); + + class = class; /*unused*/ + dctx = dctx; /*unused*/ + downcase = downcase; /*unused*/ + + isc_buffer_active(source, &sr); + if (sr.length < 4) + return (DNS_R_UNEXPECTEDEND); + + isc_buffer_forward(source, sr.length); + return (mem_tobuffer(target, sr.base, sr.length)); +} + +static dns_result_t +towire_key(dns_rdata_t *rdata, dns_compress_t *cctx, isc_buffer_t *target) { + isc_region_t sr; + + REQUIRE(rdata->type == 25); + + cctx = cctx; /*unused*/ + + dns_rdata_toregion(rdata, &sr); + return (mem_tobuffer(target, sr.base, sr.length)); +} + +static int +compare_key(dns_rdata_t *rdata1, dns_rdata_t *rdata2) { + isc_region_t r1; + isc_region_t r2; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->class == rdata2->class); + REQUIRE(rdata1->type == 25); + + dns_rdata_toregion(rdata1, &r1); + dns_rdata_toregion(rdata2, &r2); + return (compare_region(&r1, &r2)); +} + +static dns_result_t +fromstruct_key(dns_rdataclass_t class, dns_rdatatype_t type, void *source, + isc_buffer_t *target) { + + REQUIRE(type == 25); + + class = class; /*unused*/ + + source = source; + target = target; + + return (DNS_R_NOTIMPLEMENTED); +} + +static dns_result_t +tostruct_key(dns_rdata_t *rdata, void *target) { + + REQUIRE(rdata->type == 25); + + target = target; + + return (DNS_R_NOTIMPLEMENTED); +} +#endif /* RDATA_GENERIC_KEY_25_H */ diff --git a/lib/dns/rdata/generic/minfo_14.c b/lib/dns/rdata/generic/minfo_14.c index 1db1801167..5e5d4706aa 100644 --- a/lib/dns/rdata/generic/minfo_14.c +++ b/lib/dns/rdata/generic/minfo_14.c @@ -15,7 +15,7 @@ * SOFTWARE. */ - /* $Id: minfo_14.c,v 1.6 1999/01/22 05:02:46 marka Exp $ */ + /* $Id: minfo_14.c,v 1.7 1999/01/27 13:38:20 marka Exp $ */ #ifndef RDATA_GENERIC_MINFO_14_H #define RDATA_GENERIC_MINFO_14_H @@ -110,7 +110,7 @@ towire_minfo(dns_rdata_t *rdata, dns_compress_t *cctx, isc_buffer_t *target) { dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&rmail, ®ion); - isc_region_consume(®ion, rmail.length); + isc_region_consume(®ion, name_length(&rmail)); RETERR(dns_name_towire(&rmail, cctx, target)); diff --git a/lib/dns/rdata/generic/minfo_14.h b/lib/dns/rdata/generic/minfo_14.h index b2116a6478..7b7d2e38a5 100644 --- a/lib/dns/rdata/generic/minfo_14.h +++ b/lib/dns/rdata/generic/minfo_14.h @@ -15,7 +15,7 @@ * SOFTWARE. */ - /* $Id: minfo_14.h,v 1.6 1999/01/22 05:02:46 marka Exp $ */ + /* $Id: minfo_14.h,v 1.7 1999/01/27 13:38:20 marka Exp $ */ #ifndef RDATA_GENERIC_MINFO_14_H #define RDATA_GENERIC_MINFO_14_H @@ -110,7 +110,7 @@ towire_minfo(dns_rdata_t *rdata, dns_compress_t *cctx, isc_buffer_t *target) { dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&rmail, ®ion); - isc_region_consume(®ion, rmail.length); + isc_region_consume(®ion, name_length(&rmail)); RETERR(dns_name_towire(&rmail, cctx, target)); diff --git a/lib/dns/rdata/generic/sig_24.c b/lib/dns/rdata/generic/sig_24.c new file mode 100644 index 0000000000..8f8745652e --- /dev/null +++ b/lib/dns/rdata/generic/sig_24.c @@ -0,0 +1,301 @@ +/* + * Copyright (C) 1999 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + + /* $Id: sig_24.c,v 1.1 1999/01/27 13:38:20 marka Exp $ */ + + /* RFC 2065 */ + +#ifndef RDATA_GENERIC_SIG_24_H +#define RDATA_GENERIC_SIG_24_H + +static dns_result_t +fromtext_sig(dns_rdataclass_t class, dns_rdatatype_t type, + isc_lex_t *lexer, dns_name_t *origin, + isc_boolean_t downcase, isc_buffer_t *target) { + isc_token_t token; + unsigned char c; + dns_rdatatype_t covered; + isc_textregion_t *tsr; + char *e; + dns_result_t result; + dns_name_t name; + isc_buffer_t buffer; + + REQUIRE(type == 24); + + class = class; /*unused*/ + origin = origin; /*unused*/ + downcase = downcase; /*unused*/ + + /* type covered */ + RETERR(gettoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); + tsr = &token.value.as_textregion; + result = dns_rdatatype_fromtext(&covered, tsr); + if (result != DNS_R_SUCCESS && result != DNS_R_NOTIMPLEMENTED) { + covered = strtol(token.value.as_pointer, &e, 10); + if (*e != NULL) + return (result); + } + RETERR(uint16_tobuffer(covered, target)); + + /* algorithm */ + RETERR(gettoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); + if (token.value.as_ulong > 0xff) + return (DNS_R_RANGE); + c = token.value.as_ulong; + RETERR(mem_tobuffer(target, &c, 1)); + + /* labels */ + RETERR(gettoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); + if (token.value.as_ulong > 0xff) + return (DNS_R_RANGE); + c = token.value.as_ulong; + RETERR(mem_tobuffer(target, &c, 1)); + + /* original ttl */ + RETERR(gettoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); + RETERR(uint32_tobuffer(token.value.as_ulong, target)); + + /* signature expiration */ + RETERR(gettoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); + return (DNS_R_NOTIMPLEMENTED); + + /* time signed */ + RETERR(gettoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); + return (DNS_R_NOTIMPLEMENTED); + + /* key footprint */ + RETERR(gettoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); + RETERR(uint16_tobuffer(token.value.as_ulong, target)); + + /* signer */ + RETERR(gettoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); + dns_name_init(&name, NULL); + buffer_fromregion(&buffer, &token.value.as_region, + ISC_BUFFERTYPE_TEXT); + origin = (origin != NULL) ? origin : dns_rootname; + RETERR(dns_name_fromtext(&name, &buffer, origin, downcase, target)); + + /* sig */ + return (base64_tobuffer(lexer, target)); +} + +static dns_result_t +totext_sig(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target) { + isc_region_t sr; + char buf[sizeof "4294967295"]; + dns_rdatatype_t covered; + unsigned long ttl; + unsigned long when; + unsigned long exp; + unsigned long foot; + dns_name_t name; + dns_name_t prefix; + isc_boolean_t sub; + + REQUIRE(rdata->type == 24); + + origin = origin; /*unused*/ + + dns_rdata_toregion(rdata, &sr); + + /* type covered */ + covered = uint16_fromregion(&sr); + isc_region_consume(&sr, 2); + RETERR(dns_rdatatype_totext(covered, target)); + RETERR(str_totext(" ", target)); + + /* algorithm */ + sprintf(buf, "%u", sr.base[0]); + isc_region_consume(&sr, 1); + RETERR(str_totext(buf, target)); + RETERR(str_totext(" ", target)); + + /* labels */ + sprintf(buf, "%u", sr.base[0]); + isc_region_consume(&sr, 1); + RETERR(str_totext(buf, target)); + RETERR(str_totext(" ", target)); + + /* ttl */ + ttl = uint32_fromregion(&sr); + isc_region_consume(&sr, 4); + sprintf(buf, "%lu", ttl); + RETERR(str_totext(buf, target)); + RETERR(str_totext(" ", target)); + + /* sig exp */ + exp = uint32_fromregion(&sr); + isc_region_consume(&sr, 4); + RETERR(time_totext(exp, target)); + RETERR(str_totext(" ", target)); + + /* time signed */ + when = uint32_fromregion(&sr); + isc_region_consume(&sr, 4); + RETERR(time_totext(when, target)); + RETERR(str_totext(" ", target)); + + /* footprint */ + foot = uint16_fromregion(&sr); + isc_region_consume(&sr, 2); + sprintf(buf, "%lu", ttl); + RETERR(str_totext(buf, target)); + RETERR(str_totext(" ", target)); + + /* signer */ + dns_name_init(&name, NULL); + dns_name_init(&prefix, NULL); + dns_name_fromregion(&name, &sr); + sub = name_prefix(&name, origin, &prefix); + RETERR(dns_name_totext(&prefix, sub, target)); + RETERR(str_totext(" ", target)); + + /* sig */ + return (base64_totext(&sr, target)); +} + +static dns_result_t +fromwire_sig(dns_rdataclass_t class, dns_rdatatype_t type, + isc_buffer_t *source, dns_decompress_t *dctx, + isc_boolean_t downcase, isc_buffer_t *target) { + isc_region_t sr; + dns_name_t name; + + REQUIRE(type == 24); + + class = class; /*unused*/ + + isc_buffer_active(source, &sr); + /* + * type covered: 2 + * algorithm: 1 + * labels: 1 + * original ttl: 4 + * signature expiration: 4 + * time signed: 4 + * key footprint: 2 + */ + if (sr.length < 18) + return (DNS_R_UNEXPECTEDEND); + + isc_buffer_forward(source, 18); + RETERR(mem_tobuffer(target, sr.base, sr.length)); + + /* signer */ + dns_name_init(&name, NULL); + RETERR(dns_name_fromwire(&name, source, dctx, downcase, target)); + + /* sig */ + isc_buffer_active(source, &sr); + return(mem_tobuffer(target, sr.base, sr.length)); +} + +static dns_result_t +towire_sig(dns_rdata_t *rdata, dns_compress_t *cctx, isc_buffer_t *target) { + isc_region_t sr; + dns_name_t name; + + REQUIRE(rdata->type == 24); + + dns_rdata_toregion(rdata, &sr); + /* + * type covered: 2 + * algorithm: 1 + * labels: 1 + * original ttl: 4 + * signature expiration: 4 + * time signed: 4 + * key footprint: 2 + */ + RETERR(mem_tobuffer(target, sr.base, 18)); + isc_region_consume(&sr, 18); + + /* signer */ + dns_name_init(&name, NULL); + dns_name_fromregion(&name, &sr); + isc_region_consume(&sr, name_length(&name)); + RETERR(dns_name_towire(&name, cctx, target)); + + /* signature */ + return (mem_tobuffer(target, sr.base, sr.length)); +} + +static int +compare_sig(dns_rdata_t *rdata1, dns_rdata_t *rdata2) { + isc_region_t r1; + isc_region_t r2; + dns_name_t name1; + dns_name_t name2; + int result; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->class == rdata2->class); + REQUIRE(rdata1->type == 24); + + dns_rdata_toregion(rdata1, &r1); + dns_rdata_toregion(rdata2, &r2); + + INSIST(r1.length > 18); + INSIST(r2.length > 18); + r1.length = 18; + r2.length = 18; + result = compare_region(&r1, &r2); + if (result != 0) + return (result); + + dns_name_init(&name1, NULL); + dns_name_init(&name2, NULL); + dns_rdata_toregion(rdata1, &r1); + dns_rdata_toregion(rdata2, &r2); + isc_region_consume(&r1, 18); + isc_region_consume(&r2, 18); + dns_name_fromregion(&name1, &r1); + dns_name_fromregion(&name2, &r2); + result = dns_name_compare(&name1, &name2); + if (result != 0) + return (result); + isc_region_consume(&r1, name_length(&name1)); + isc_region_consume(&r2, name_length(&name2)); + + return (compare_region(&r1, &r2)); +} + +static dns_result_t +fromstruct_sig(dns_rdataclass_t class, dns_rdatatype_t type, void *source, + isc_buffer_t *target) { + + REQUIRE(type == 24); + + class = class; /*unused*/ + + source = source; + target = target; + + return (DNS_R_NOTIMPLEMENTED); +} + +static dns_result_t +tostruct_sig(dns_rdata_t *rdata, void *target) { + + REQUIRE(rdata->type == 24); + + target = target; + + return (DNS_R_NOTIMPLEMENTED); +} +#endif /* RDATA_GENERIC_SIG_24_H */ diff --git a/lib/dns/rdata/generic/sig_24.h b/lib/dns/rdata/generic/sig_24.h new file mode 100644 index 0000000000..28e8f0da9d --- /dev/null +++ b/lib/dns/rdata/generic/sig_24.h @@ -0,0 +1,301 @@ +/* + * Copyright (C) 1999 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + + /* $Id: sig_24.h,v 1.1 1999/01/27 13:38:20 marka Exp $ */ + + /* RFC 2065 */ + +#ifndef RDATA_GENERIC_SIG_24_H +#define RDATA_GENERIC_SIG_24_H + +static dns_result_t +fromtext_sig(dns_rdataclass_t class, dns_rdatatype_t type, + isc_lex_t *lexer, dns_name_t *origin, + isc_boolean_t downcase, isc_buffer_t *target) { + isc_token_t token; + unsigned char c; + dns_rdatatype_t covered; + isc_textregion_t *tsr; + char *e; + dns_result_t result; + dns_name_t name; + isc_buffer_t buffer; + + REQUIRE(type == 24); + + class = class; /*unused*/ + origin = origin; /*unused*/ + downcase = downcase; /*unused*/ + + /* type covered */ + RETERR(gettoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); + tsr = &token.value.as_textregion; + result = dns_rdatatype_fromtext(&covered, tsr); + if (result != DNS_R_SUCCESS && result != DNS_R_NOTIMPLEMENTED) { + covered = strtol(token.value.as_pointer, &e, 10); + if (*e != NULL) + return (result); + } + RETERR(uint16_tobuffer(covered, target)); + + /* algorithm */ + RETERR(gettoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); + if (token.value.as_ulong > 0xff) + return (DNS_R_RANGE); + c = token.value.as_ulong; + RETERR(mem_tobuffer(target, &c, 1)); + + /* labels */ + RETERR(gettoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); + if (token.value.as_ulong > 0xff) + return (DNS_R_RANGE); + c = token.value.as_ulong; + RETERR(mem_tobuffer(target, &c, 1)); + + /* original ttl */ + RETERR(gettoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); + RETERR(uint32_tobuffer(token.value.as_ulong, target)); + + /* signature expiration */ + RETERR(gettoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); + return (DNS_R_NOTIMPLEMENTED); + + /* time signed */ + RETERR(gettoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); + return (DNS_R_NOTIMPLEMENTED); + + /* key footprint */ + RETERR(gettoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); + RETERR(uint16_tobuffer(token.value.as_ulong, target)); + + /* signer */ + RETERR(gettoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); + dns_name_init(&name, NULL); + buffer_fromregion(&buffer, &token.value.as_region, + ISC_BUFFERTYPE_TEXT); + origin = (origin != NULL) ? origin : dns_rootname; + RETERR(dns_name_fromtext(&name, &buffer, origin, downcase, target)); + + /* sig */ + return (base64_tobuffer(lexer, target)); +} + +static dns_result_t +totext_sig(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target) { + isc_region_t sr; + char buf[sizeof "4294967295"]; + dns_rdatatype_t covered; + unsigned long ttl; + unsigned long when; + unsigned long exp; + unsigned long foot; + dns_name_t name; + dns_name_t prefix; + isc_boolean_t sub; + + REQUIRE(rdata->type == 24); + + origin = origin; /*unused*/ + + dns_rdata_toregion(rdata, &sr); + + /* type covered */ + covered = uint16_fromregion(&sr); + isc_region_consume(&sr, 2); + RETERR(dns_rdatatype_totext(covered, target)); + RETERR(str_totext(" ", target)); + + /* algorithm */ + sprintf(buf, "%u", sr.base[0]); + isc_region_consume(&sr, 1); + RETERR(str_totext(buf, target)); + RETERR(str_totext(" ", target)); + + /* labels */ + sprintf(buf, "%u", sr.base[0]); + isc_region_consume(&sr, 1); + RETERR(str_totext(buf, target)); + RETERR(str_totext(" ", target)); + + /* ttl */ + ttl = uint32_fromregion(&sr); + isc_region_consume(&sr, 4); + sprintf(buf, "%lu", ttl); + RETERR(str_totext(buf, target)); + RETERR(str_totext(" ", target)); + + /* sig exp */ + exp = uint32_fromregion(&sr); + isc_region_consume(&sr, 4); + RETERR(time_totext(exp, target)); + RETERR(str_totext(" ", target)); + + /* time signed */ + when = uint32_fromregion(&sr); + isc_region_consume(&sr, 4); + RETERR(time_totext(when, target)); + RETERR(str_totext(" ", target)); + + /* footprint */ + foot = uint16_fromregion(&sr); + isc_region_consume(&sr, 2); + sprintf(buf, "%lu", ttl); + RETERR(str_totext(buf, target)); + RETERR(str_totext(" ", target)); + + /* signer */ + dns_name_init(&name, NULL); + dns_name_init(&prefix, NULL); + dns_name_fromregion(&name, &sr); + sub = name_prefix(&name, origin, &prefix); + RETERR(dns_name_totext(&prefix, sub, target)); + RETERR(str_totext(" ", target)); + + /* sig */ + return (base64_totext(&sr, target)); +} + +static dns_result_t +fromwire_sig(dns_rdataclass_t class, dns_rdatatype_t type, + isc_buffer_t *source, dns_decompress_t *dctx, + isc_boolean_t downcase, isc_buffer_t *target) { + isc_region_t sr; + dns_name_t name; + + REQUIRE(type == 24); + + class = class; /*unused*/ + + isc_buffer_active(source, &sr); + /* + * type covered: 2 + * algorithm: 1 + * labels: 1 + * original ttl: 4 + * signature expiration: 4 + * time signed: 4 + * key footprint: 2 + */ + if (sr.length < 18) + return (DNS_R_UNEXPECTEDEND); + + isc_buffer_forward(source, 18); + RETERR(mem_tobuffer(target, sr.base, sr.length)); + + /* signer */ + dns_name_init(&name, NULL); + RETERR(dns_name_fromwire(&name, source, dctx, downcase, target)); + + /* sig */ + isc_buffer_active(source, &sr); + return(mem_tobuffer(target, sr.base, sr.length)); +} + +static dns_result_t +towire_sig(dns_rdata_t *rdata, dns_compress_t *cctx, isc_buffer_t *target) { + isc_region_t sr; + dns_name_t name; + + REQUIRE(rdata->type == 24); + + dns_rdata_toregion(rdata, &sr); + /* + * type covered: 2 + * algorithm: 1 + * labels: 1 + * original ttl: 4 + * signature expiration: 4 + * time signed: 4 + * key footprint: 2 + */ + RETERR(mem_tobuffer(target, sr.base, 18)); + isc_region_consume(&sr, 18); + + /* signer */ + dns_name_init(&name, NULL); + dns_name_fromregion(&name, &sr); + isc_region_consume(&sr, name_length(&name)); + RETERR(dns_name_towire(&name, cctx, target)); + + /* signature */ + return (mem_tobuffer(target, sr.base, sr.length)); +} + +static int +compare_sig(dns_rdata_t *rdata1, dns_rdata_t *rdata2) { + isc_region_t r1; + isc_region_t r2; + dns_name_t name1; + dns_name_t name2; + int result; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->class == rdata2->class); + REQUIRE(rdata1->type == 24); + + dns_rdata_toregion(rdata1, &r1); + dns_rdata_toregion(rdata2, &r2); + + INSIST(r1.length > 18); + INSIST(r2.length > 18); + r1.length = 18; + r2.length = 18; + result = compare_region(&r1, &r2); + if (result != 0) + return (result); + + dns_name_init(&name1, NULL); + dns_name_init(&name2, NULL); + dns_rdata_toregion(rdata1, &r1); + dns_rdata_toregion(rdata2, &r2); + isc_region_consume(&r1, 18); + isc_region_consume(&r2, 18); + dns_name_fromregion(&name1, &r1); + dns_name_fromregion(&name2, &r2); + result = dns_name_compare(&name1, &name2); + if (result != 0) + return (result); + isc_region_consume(&r1, name_length(&name1)); + isc_region_consume(&r2, name_length(&name2)); + + return (compare_region(&r1, &r2)); +} + +static dns_result_t +fromstruct_sig(dns_rdataclass_t class, dns_rdatatype_t type, void *source, + isc_buffer_t *target) { + + REQUIRE(type == 24); + + class = class; /*unused*/ + + source = source; + target = target; + + return (DNS_R_NOTIMPLEMENTED); +} + +static dns_result_t +tostruct_sig(dns_rdata_t *rdata, void *target) { + + REQUIRE(rdata->type == 24); + + target = target; + + return (DNS_R_NOTIMPLEMENTED); +} +#endif /* RDATA_GENERIC_SIG_24_H */ diff --git a/lib/dns/rdata/in_1/nsap_22.c b/lib/dns/rdata/in_1/nsap_22.c new file mode 100644 index 0000000000..a7f2daa85b --- /dev/null +++ b/lib/dns/rdata/in_1/nsap_22.c @@ -0,0 +1,164 @@ +/* + * Copyright (C) 1999 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + + /* $Id: nsap_22.c,v 1.1 1999/01/27 13:38:21 marka Exp $ */ + + /* RFC 1706 */ + +#ifndef RDATA_IN_1_NSAP_22_H +#define RDATA_IN_1_NSAP_22_H + +#include + +static dns_result_t +fromtext_in_nsap(dns_rdataclass_t class, dns_rdatatype_t type, + isc_lex_t *lexer, dns_name_t *origin, + isc_boolean_t downcase, isc_buffer_t *target) { + isc_token_t token; + isc_textregion_t *sr; + int n; + int digits; + unsigned char c; + + REQUIRE(type == 22); + REQUIRE(class == 1); + + origin = origin; /*unused*/ + downcase = downcase; /*unused*/ + + /* 0x */ + RETERR(gettoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); + sr = &token.value.as_textregion; + if (sr->length < 2) + return (DNS_R_UNEXPECTEDEND); + if (sr->base[0] != '0' || (sr->base[1] != 'x' && sr->base[1] != 'X')) + return (DNS_R_SYNTAX); + isc_textregion_consume(sr, 2); + digits = 0; + n = 0; + while (sr->length > 1) { + if (sr->base[0] == '.') { + isc_textregion_consume(sr, 1); + continue; + } + if ((n = hexvalue(sr->base[0])) == -1) + return (DNS_R_SYNTAX); + c <<= 4; + c += n; + if (++digits == 2) { + RETERR(mem_tobuffer(target, &n, 1)); + digits = 0; + } + } + if (digits) { + c <<= 4; + return (mem_tobuffer(target, &c, 1)); + } + return (DNS_R_SUCCESS); +} + +static dns_result_t +totext_in_nsap(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target) { + isc_region_t region; + char buf[sizeof "xx"]; + + REQUIRE(rdata->type == 22); + REQUIRE(rdata->class == 1); + REQUIRE(rdata->length == 4); + + origin = origin; /* unused */ + + dns_rdata_toregion(rdata, ®ion); + RETERR(str_totext("0x", target)); + while (region.length) { + sprintf(buf, "%02x", region.base[0]); + isc_region_consume(®ion, 1); + RETERR(str_totext(buf, target)); + } + return (DNS_R_SUCCESS); +} + +static dns_result_t +fromwire_in_nsap(dns_rdataclass_t class, dns_rdatatype_t type, + isc_buffer_t *source, dns_decompress_t *dctx, + isc_boolean_t downcase, isc_buffer_t *target) { + isc_region_t region; + + REQUIRE(type == 22); + REQUIRE(class == 1); + + dctx = dctx; /* unused */ + downcase = downcase; /* unused */ + + + isc_buffer_active(source, ®ion); + if (region.length < 1) + return (DNS_R_UNEXPECTEDEND); + + return (mem_tobuffer(target, region.base, region.length)); +} + +static dns_result_t +towire_in_nsap(dns_rdata_t *rdata, dns_compress_t *cctx, isc_buffer_t *target) { + + REQUIRE(rdata->type == 22); + REQUIRE(rdata->class == 1); + + cctx = cctx; /*unused*/ + + return (mem_tobuffer(target, rdata->data, rdata->length)); +} + +static int +compare_in_nsap(dns_rdata_t *rdata1, dns_rdata_t *rdata2) { + isc_region_t r1; + isc_region_t r2; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->class == rdata2->type); + REQUIRE(rdata1->type == 22); + REQUIRE(rdata1->class == 1); + + dns_rdata_toregion(rdata1, &r1); + dns_rdata_toregion(rdata2, &r2); + return (compare_region(&r1, &r2)); +} + +static dns_result_t +fromstruct_in_nsap(dns_rdataclass_t class, dns_rdatatype_t type, void *source, + isc_buffer_t *target) { + + REQUIRE(type == 22); + REQUIRE(class == 1); + + source = source; + target = target; + + return (DNS_R_NOTIMPLEMENTED); +} + +static dns_result_t +tostruct_in_nsap(dns_rdata_t *rdata, void *target) { + + REQUIRE(rdata->type == 22); + REQUIRE(rdata->class == 1); + + target = target; + + return (DNS_R_NOTIMPLEMENTED); +} +#endif /* RDATA_IN_1_NSAP_22_H */ diff --git a/lib/dns/rdata/in_1/nsap_22.h b/lib/dns/rdata/in_1/nsap_22.h new file mode 100644 index 0000000000..2b43423d61 --- /dev/null +++ b/lib/dns/rdata/in_1/nsap_22.h @@ -0,0 +1,164 @@ +/* + * Copyright (C) 1999 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + + /* $Id: nsap_22.h,v 1.1 1999/01/27 13:38:21 marka Exp $ */ + + /* RFC 1706 */ + +#ifndef RDATA_IN_1_NSAP_22_H +#define RDATA_IN_1_NSAP_22_H + +#include + +static dns_result_t +fromtext_in_nsap(dns_rdataclass_t class, dns_rdatatype_t type, + isc_lex_t *lexer, dns_name_t *origin, + isc_boolean_t downcase, isc_buffer_t *target) { + isc_token_t token; + isc_textregion_t *sr; + int n; + int digits; + unsigned char c; + + REQUIRE(type == 22); + REQUIRE(class == 1); + + origin = origin; /*unused*/ + downcase = downcase; /*unused*/ + + /* 0x */ + RETERR(gettoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); + sr = &token.value.as_textregion; + if (sr->length < 2) + return (DNS_R_UNEXPECTEDEND); + if (sr->base[0] != '0' || (sr->base[1] != 'x' && sr->base[1] != 'X')) + return (DNS_R_SYNTAX); + isc_textregion_consume(sr, 2); + digits = 0; + n = 0; + while (sr->length > 1) { + if (sr->base[0] == '.') { + isc_textregion_consume(sr, 1); + continue; + } + if ((n = hexvalue(sr->base[0])) == -1) + return (DNS_R_SYNTAX); + c <<= 4; + c += n; + if (++digits == 2) { + RETERR(mem_tobuffer(target, &n, 1)); + digits = 0; + } + } + if (digits) { + c <<= 4; + return (mem_tobuffer(target, &c, 1)); + } + return (DNS_R_SUCCESS); +} + +static dns_result_t +totext_in_nsap(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target) { + isc_region_t region; + char buf[sizeof "xx"]; + + REQUIRE(rdata->type == 22); + REQUIRE(rdata->class == 1); + REQUIRE(rdata->length == 4); + + origin = origin; /* unused */ + + dns_rdata_toregion(rdata, ®ion); + RETERR(str_totext("0x", target)); + while (region.length) { + sprintf(buf, "%02x", region.base[0]); + isc_region_consume(®ion, 1); + RETERR(str_totext(buf, target)); + } + return (DNS_R_SUCCESS); +} + +static dns_result_t +fromwire_in_nsap(dns_rdataclass_t class, dns_rdatatype_t type, + isc_buffer_t *source, dns_decompress_t *dctx, + isc_boolean_t downcase, isc_buffer_t *target) { + isc_region_t region; + + REQUIRE(type == 22); + REQUIRE(class == 1); + + dctx = dctx; /* unused */ + downcase = downcase; /* unused */ + + + isc_buffer_active(source, ®ion); + if (region.length < 1) + return (DNS_R_UNEXPECTEDEND); + + return (mem_tobuffer(target, region.base, region.length)); +} + +static dns_result_t +towire_in_nsap(dns_rdata_t *rdata, dns_compress_t *cctx, isc_buffer_t *target) { + + REQUIRE(rdata->type == 22); + REQUIRE(rdata->class == 1); + + cctx = cctx; /*unused*/ + + return (mem_tobuffer(target, rdata->data, rdata->length)); +} + +static int +compare_in_nsap(dns_rdata_t *rdata1, dns_rdata_t *rdata2) { + isc_region_t r1; + isc_region_t r2; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->class == rdata2->type); + REQUIRE(rdata1->type == 22); + REQUIRE(rdata1->class == 1); + + dns_rdata_toregion(rdata1, &r1); + dns_rdata_toregion(rdata2, &r2); + return (compare_region(&r1, &r2)); +} + +static dns_result_t +fromstruct_in_nsap(dns_rdataclass_t class, dns_rdatatype_t type, void *source, + isc_buffer_t *target) { + + REQUIRE(type == 22); + REQUIRE(class == 1); + + source = source; + target = target; + + return (DNS_R_NOTIMPLEMENTED); +} + +static dns_result_t +tostruct_in_nsap(dns_rdata_t *rdata, void *target) { + + REQUIRE(rdata->type == 22); + REQUIRE(rdata->class == 1); + + target = target; + + return (DNS_R_NOTIMPLEMENTED); +} +#endif /* RDATA_IN_1_NSAP_22_H */ diff --git a/lib/dns/result.c b/lib/dns/result.c index 7efc1db220..4fb616d1db 100644 --- a/lib/dns/result.c +++ b/lib/dns/result.c @@ -43,6 +43,7 @@ static char *text_table[DNS_R_LASTENTRY + 1] = { "out of range", /* 20 */ "already exists", /* 21 */ "not found", /* 22 */ + "syntax error", /* 23 */ }; char *