mirror of https://github.com/getdnsapi/getdns.git
TSIG and TKEY parsing by gldns
This commit is contained in:
parent
1e44ea7bd8
commit
dab93cd197
|
@ -469,6 +469,30 @@ gldns_buffer_write_at(gldns_buffer *buffer, size_t at, const void *data, size_t
|
|||
memcpy(buffer->_data + at, data, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* set the given byte to the buffer at the specified position
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] at the position (in number of bytes) to write the data at
|
||||
* \param[in] c the byte to set to the buffer
|
||||
* \param[in] count the number of bytes of bytes to write
|
||||
*/
|
||||
|
||||
INLINE void
|
||||
gldns_buffer_set_at(gldns_buffer *buffer, size_t at, int c, size_t count)
|
||||
{
|
||||
if (!buffer->_vfixed)
|
||||
assert(gldns_buffer_available_at(buffer, at, count));
|
||||
else if (gldns_buffer_remaining_at(buffer, at) == 0)
|
||||
return;
|
||||
else if (count > gldns_buffer_remaining_at(buffer, at)) {
|
||||
memset(buffer->_data + at, c,
|
||||
gldns_buffer_remaining_at(buffer, at));
|
||||
return;
|
||||
}
|
||||
memset(buffer->_data + at, c, count);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* writes count bytes of data to the current position of the buffer
|
||||
* \param[in] buffer the buffer
|
||||
|
|
|
@ -120,6 +120,10 @@ gldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *l
|
|||
if (line_nr) {
|
||||
*line_nr = *line_nr + 1;
|
||||
}
|
||||
if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
|
||||
*t = '\0';
|
||||
return -1;
|
||||
}
|
||||
*t++ = ' ';
|
||||
prev_c = c;
|
||||
continue;
|
||||
|
|
|
@ -175,7 +175,7 @@ static const gldns_rdf_type type_tkey_wireformat[] = {
|
|||
GLDNS_RDF_TYPE_TIME,
|
||||
GLDNS_RDF_TYPE_TIME,
|
||||
GLDNS_RDF_TYPE_INT16,
|
||||
GLDNS_RDF_TYPE_INT16,
|
||||
GLDNS_RDF_TYPE_TSIGERROR,
|
||||
GLDNS_RDF_TYPE_INT16_DATA,
|
||||
GLDNS_RDF_TYPE_INT16_DATA,
|
||||
};
|
||||
|
@ -185,7 +185,7 @@ static const gldns_rdf_type type_tsig_wireformat[] = {
|
|||
GLDNS_RDF_TYPE_INT16,
|
||||
GLDNS_RDF_TYPE_INT16_DATA,
|
||||
GLDNS_RDF_TYPE_INT16,
|
||||
GLDNS_RDF_TYPE_INT16,
|
||||
GLDNS_RDF_TYPE_TSIGERROR,
|
||||
GLDNS_RDF_TYPE_INT16_DATA
|
||||
};
|
||||
static const gldns_rdf_type type_tlsa_wireformat[] = {
|
||||
|
@ -606,7 +606,7 @@ static gldns_rr_descriptor rdata_field_descriptors[] = {
|
|||
{GLDNS_RR_TYPE_CAA, "CAA", 3, 3, type_caa_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||
#ifdef DRAFT_RRTYPES
|
||||
/* 258 */
|
||||
{GLDNS_RR_TYPE_AVC, "AVC", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||
{GLDNS_RR_TYPE_TXT, "AVC", 1, 0, NULL, GLDNS_RDF_TYPE_STR, GLDNS_RR_NO_COMPRESS, 0 },
|
||||
#else
|
||||
{GLDNS_RR_TYPE_NULL, "TYPE258", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||
#endif
|
||||
|
|
|
@ -351,6 +351,9 @@ enum gldns_enum_rdf_type
|
|||
*/
|
||||
GLDNS_RDF_TYPE_LONG_STR,
|
||||
|
||||
/** TSIG extended 16bit error value */
|
||||
GLDNS_RDF_TYPE_TSIGERROR,
|
||||
|
||||
/* Aliases */
|
||||
GLDNS_RDF_TYPE_BITMAP = GLDNS_RDF_TYPE_NSEC
|
||||
};
|
||||
|
@ -423,7 +426,7 @@ enum gldns_enum_edns_option
|
|||
GLDNS_EDNS_DAU = 5, /* RFC6975 */
|
||||
GLDNS_EDNS_DHU = 6, /* RFC6975 */
|
||||
GLDNS_EDNS_N3U = 7, /* RFC6975 */
|
||||
GLDNS_EDNS_CLIENT_SUBNET = 8, /* draft-vandergaast-edns-client-subnet */
|
||||
GLDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */
|
||||
GLDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/
|
||||
GLDNS_EDNS_PADDING = 12 /* RFC7830 */
|
||||
};
|
||||
|
@ -431,6 +434,15 @@ typedef enum gldns_enum_edns_option gldns_edns_option;
|
|||
|
||||
#define GLDNS_EDNS_MASK_DO_BIT 0x8000
|
||||
|
||||
/** TSIG and TKEY extended rcodes (16bit), 0-15 are the normal rcodes. */
|
||||
#define GLDNS_TSIG_ERROR_NOERROR 0
|
||||
#define GLDNS_TSIG_ERROR_BADSIG 16
|
||||
#define GLDNS_TSIG_ERROR_BADKEY 17
|
||||
#define GLDNS_TSIG_ERROR_BADTIME 18
|
||||
#define GLDNS_TSIG_ERROR_BADMODE 19
|
||||
#define GLDNS_TSIG_ERROR_BADNAME 20
|
||||
#define GLDNS_TSIG_ERROR_BADALG 21
|
||||
|
||||
/**
|
||||
* Contains all information about resource record types.
|
||||
*
|
||||
|
|
|
@ -664,6 +664,14 @@ rrinternal_parse_rdata(gldns_buffer* strbuf, char* token, size_t token_len,
|
|||
&pre_data_pos, delimiters,
|
||||
rdftype, &token_strlen))
|
||||
break;
|
||||
} else if(rdftype == GLDNS_RDF_TYPE_INT16_DATA &&
|
||||
strcmp(token, "0")!=0) {
|
||||
/* affix len and b64 fields */
|
||||
if(!gldns_affix_token(strbuf, token,
|
||||
&token_len, "ed, &parens,
|
||||
&pre_data_pos, delimiters,
|
||||
rdftype, &token_strlen))
|
||||
break;
|
||||
}
|
||||
|
||||
/* normal RR */
|
||||
|
@ -940,6 +948,8 @@ int gldns_str2wire_rdf_buf(const char* str, uint8_t* rd, size_t* len,
|
|||
return gldns_str2wire_time_buf(str, rd, len);
|
||||
case GLDNS_RDF_TYPE_PERIOD:
|
||||
return gldns_str2wire_period_buf(str, rd, len);
|
||||
case GLDNS_RDF_TYPE_TSIGTIME:
|
||||
return gldns_str2wire_tsigtime_buf(str, rd, len);
|
||||
case GLDNS_RDF_TYPE_LOC:
|
||||
return gldns_str2wire_loc_buf(str, rd, len);
|
||||
case GLDNS_RDF_TYPE_WKS:
|
||||
|
@ -964,6 +974,8 @@ int gldns_str2wire_rdf_buf(const char* str, uint8_t* rd, size_t* len,
|
|||
return gldns_str2wire_tag_buf(str, rd, len);
|
||||
case GLDNS_RDF_TYPE_LONG_STR:
|
||||
return gldns_str2wire_long_str_buf(str, rd, len);
|
||||
case GLDNS_RDF_TYPE_TSIGERROR:
|
||||
return gldns_str2wire_tsigerror_buf(str, rd, len);
|
||||
case GLDNS_RDF_TYPE_HIP:
|
||||
return gldns_str2wire_hip_buf(str, rd, len);
|
||||
case GLDNS_RDF_TYPE_INT16_DATA:
|
||||
|
@ -1341,6 +1353,21 @@ int gldns_str2wire_alg_buf(const char* str, uint8_t* rd, size_t* len)
|
|||
return GLDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
|
||||
int gldns_str2wire_tsigerror_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
{
|
||||
gldns_lookup_table *lt = gldns_lookup_by_name(gldns_tsig_errors, str);
|
||||
if(*len < 2)
|
||||
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||
if(lt) {
|
||||
gldns_write_uint16(rd, (uint16_t)lt->id);
|
||||
*len = 2;
|
||||
} else {
|
||||
/* try as-is (a number) */
|
||||
return gldns_str2wire_int16_buf(str, rd, len);
|
||||
}
|
||||
return GLDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
|
||||
int gldns_str2wire_time_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
{
|
||||
/* convert a time YYYYDDMMHHMMSS to wireformat */
|
||||
|
@ -1383,6 +1410,24 @@ int gldns_str2wire_time_buf(const char* str, uint8_t* rd, size_t* len)
|
|||
return GLDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
|
||||
int gldns_str2wire_tsigtime_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
{
|
||||
char* end;
|
||||
uint64_t t = (uint64_t)strtol((char*)str, &end, 10);
|
||||
uint16_t high;
|
||||
uint32_t low;
|
||||
if(*end != 0)
|
||||
return RET_ERR(GLDNS_WIREPARSE_ERR_SYNTAX_TIME, end-str);
|
||||
if(*len < 6)
|
||||
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||
high = (uint16_t)(t>>32);
|
||||
low = (uint32_t)(t);
|
||||
gldns_write_uint16(rd, high);
|
||||
gldns_write_uint32(rd+2, low);
|
||||
*len = 6;
|
||||
return GLDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
|
||||
int gldns_str2wire_period_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
{
|
||||
const char* end;
|
||||
|
@ -2008,13 +2053,26 @@ int gldns_str2wire_hip_buf(const char* str, uint8_t* rd, size_t* len)
|
|||
|
||||
int gldns_str2wire_int16_data_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
{
|
||||
size_t sz = gldns_b64_pton_calculate_size(strlen(str));
|
||||
char* s;
|
||||
int n;
|
||||
if(*len < sz+2)
|
||||
n = strtol(str, &s, 10);
|
||||
if(*len < ((size_t)n)+2)
|
||||
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||
if(sz > 65535)
|
||||
if(n > 65535)
|
||||
return GLDNS_WIREPARSE_ERR_LABEL_OVERFLOW;
|
||||
n = gldns_b64_pton(str, rd+2, (*len)-2);
|
||||
|
||||
if(n == 0) {
|
||||
gldns_write_uint16(rd, 0);
|
||||
*len = 2;
|
||||
return GLDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
if(*s != ' ')
|
||||
return RET_ERR(GLDNS_WIREPARSE_ERR_SYNTAX_INT, s-(char*)str);
|
||||
s++;
|
||||
while(*s == ' ')
|
||||
s++;
|
||||
|
||||
n = gldns_b64_pton(s, rd+2, (*len)-2);
|
||||
if(n < 0)
|
||||
return GLDNS_WIREPARSE_ERR_SYNTAX_B64;
|
||||
gldns_write_uint16(rd, (uint16_t)n);
|
||||
|
|
|
@ -417,6 +417,24 @@ int gldns_str2wire_time_buf(const char* str, uint8_t* rd, size_t* len);
|
|||
*/
|
||||
int gldns_str2wire_period_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type GLDNS_RDF_TYPE_TSIGTIME from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int gldns_str2wire_tsigtime_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type GLDNS_RDF_TYPE_TSIGERROR from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
* @param rd: rdata buffer for the wireformat.
|
||||
* @param len: length of rd buffer on input, used length on output.
|
||||
* @return 0 on success, error on failure.
|
||||
*/
|
||||
int gldns_str2wire_tsigerror_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Convert rdf of type GLDNS_RDF_TYPE_LOC from string to wireformat.
|
||||
* @param str: the text to convert for this rdata element.
|
||||
|
|
|
@ -173,6 +173,28 @@ static gldns_lookup_table gldns_edns_options_data[] = {
|
|||
};
|
||||
gldns_lookup_table* gldns_edns_options = gldns_edns_options_data;
|
||||
|
||||
static gldns_lookup_table gldns_tsig_errors_data[] = {
|
||||
{ GLDNS_TSIG_ERROR_NOERROR, "NOERROR" },
|
||||
{ GLDNS_RCODE_FORMERR, "FORMERR" },
|
||||
{ GLDNS_RCODE_SERVFAIL, "SERVFAIL" },
|
||||
{ GLDNS_RCODE_NXDOMAIN, "NXDOMAIN" },
|
||||
{ GLDNS_RCODE_NOTIMPL, "NOTIMPL" },
|
||||
{ GLDNS_RCODE_REFUSED, "REFUSED" },
|
||||
{ GLDNS_RCODE_YXDOMAIN, "YXDOMAIN" },
|
||||
{ GLDNS_RCODE_YXRRSET, "YXRRSET" },
|
||||
{ GLDNS_RCODE_NXRRSET, "NXRRSET" },
|
||||
{ GLDNS_RCODE_NOTAUTH, "NOTAUTH" },
|
||||
{ GLDNS_RCODE_NOTZONE, "NOTZONE" },
|
||||
{ GLDNS_TSIG_ERROR_BADSIG, "BADSIG" },
|
||||
{ GLDNS_TSIG_ERROR_BADKEY, "BADKEY" },
|
||||
{ GLDNS_TSIG_ERROR_BADTIME, "BADTIME" },
|
||||
{ GLDNS_TSIG_ERROR_BADMODE, "BADMODE" },
|
||||
{ GLDNS_TSIG_ERROR_BADNAME, "BADNAME" },
|
||||
{ GLDNS_TSIG_ERROR_BADALG, "BADALG" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
gldns_lookup_table* gldns_tsig_errors = gldns_tsig_errors_data;
|
||||
|
||||
char* gldns_wire2str_pkt(uint8_t* data, size_t len)
|
||||
{
|
||||
size_t slen = (size_t)gldns_wire2str_pkt_buf(data, len, NULL, 0);
|
||||
|
@ -285,6 +307,12 @@ int gldns_wire2str_rcode_buf(int rcode, char* s, size_t slen)
|
|||
return gldns_wire2str_rcode_print(&s, &slen, rcode);
|
||||
}
|
||||
|
||||
int gldns_wire2str_opcode_buf(int opcode, char* s, size_t slen)
|
||||
{
|
||||
/* use arguments as temporary variables */
|
||||
return gldns_wire2str_opcode_print(&s, &slen, opcode);
|
||||
}
|
||||
|
||||
int gldns_wire2str_dname_buf(uint8_t* d, size_t dlen, char* s, size_t slen)
|
||||
{
|
||||
/* use arguments as temporary variables */
|
||||
|
@ -982,6 +1010,8 @@ int gldns_wire2str_rdf_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
|
|||
return gldns_wire2str_tag_scan(d, dlen, s, slen);
|
||||
case GLDNS_RDF_TYPE_LONG_STR:
|
||||
return gldns_wire2str_long_str_scan(d, dlen, s, slen);
|
||||
case GLDNS_RDF_TYPE_TSIGERROR:
|
||||
return gldns_wire2str_tsigerror_scan(d, dlen, s, slen);
|
||||
}
|
||||
/* unknown rdf type */
|
||||
return -1;
|
||||
|
@ -1580,6 +1610,7 @@ int gldns_wire2str_hip_scan(uint8_t** d, size_t* dl, char** s, size_t* sl)
|
|||
|
||||
int gldns_wire2str_int16_data_scan(uint8_t** d, size_t* dl, char** s, size_t* sl)
|
||||
{
|
||||
int w;
|
||||
uint16_t n;
|
||||
if(*dl < 2)
|
||||
return -1;
|
||||
|
@ -1588,7 +1619,12 @@ int gldns_wire2str_int16_data_scan(uint8_t** d, size_t* dl, char** s, size_t* sl
|
|||
return -1;
|
||||
(*d)+=2;
|
||||
(*dl)-=2;
|
||||
return gldns_wire2str_b64_scan_num(d, dl, s, sl, n);
|
||||
if(n == 0) {
|
||||
return gldns_str_print(s, sl, "0");
|
||||
}
|
||||
w = gldns_str_print(s, sl, "%u ", (unsigned)n);
|
||||
w += gldns_wire2str_b64_scan_num(d, dl, s, sl, n);
|
||||
return w;
|
||||
}
|
||||
|
||||
int gldns_wire2str_nsec3_next_owner_scan(uint8_t** d, size_t* dl, char** s,
|
||||
|
@ -1645,10 +1681,10 @@ int gldns_wire2str_tag_scan(uint8_t** d, size_t* dl, char** s, size_t* sl)
|
|||
if(*dl < 1+n)
|
||||
return -1;
|
||||
for(i=0; i<n; i++)
|
||||
if(!isalnum((unsigned char)(*d)[1+i]))
|
||||
if(!isalnum((unsigned char)(*d)[i+1]))
|
||||
return -1;
|
||||
for(i=0; i<n; i++)
|
||||
w += gldns_str_print(s, sl, "%c", (char)(*d)[1+i]);
|
||||
w += gldns_str_print(s, sl, "%c", (char)(*d)[i+1]);
|
||||
(*d)+=n+1;
|
||||
(*dl)-=(n+1);
|
||||
return w;
|
||||
|
@ -1667,6 +1703,21 @@ int gldns_wire2str_long_str_scan(uint8_t** d, size_t* dl, char** s, size_t* sl)
|
|||
return w;
|
||||
}
|
||||
|
||||
int gldns_wire2str_tsigerror_scan(uint8_t** d, size_t* dl, char** s, size_t* sl)
|
||||
{
|
||||
gldns_lookup_table *lt;
|
||||
int data, w;
|
||||
if(*dl < 2) return -1;
|
||||
data = (int)gldns_read_uint16(*d);
|
||||
lt = gldns_lookup_by_id(gldns_tsig_errors, data);
|
||||
if(lt && lt->name)
|
||||
w = gldns_str_print(s, sl, "%s", lt->name);
|
||||
else w = gldns_str_print(s, sl, "%d", data);
|
||||
(*dl)-=2;
|
||||
(*d)+=2;
|
||||
return w;
|
||||
}
|
||||
|
||||
int gldns_wire2str_edns_llq_print(char** s, size_t* sl, uint8_t* data,
|
||||
size_t len)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,8 @@ extern struct gldns_struct_lookup_table* gldns_edns_flags;
|
|||
extern struct gldns_struct_lookup_table* gldns_edns_options;
|
||||
/** error string from wireparse */
|
||||
extern struct gldns_struct_lookup_table* gldns_wireparse_errors;
|
||||
/** tsig errors are the rcodes with extra (higher) values */
|
||||
extern struct gldns_struct_lookup_table* gldns_tsig_errors;
|
||||
|
||||
/**
|
||||
* Convert wireformat packet to a string representation
|
||||
|
@ -441,6 +443,17 @@ int gldns_wire2str_class_buf(uint16_t rrclass, char* str, size_t len);
|
|||
*/
|
||||
int gldns_wire2str_rcode_buf(int rcode, char* str, size_t len);
|
||||
|
||||
/**
|
||||
* Convert host format opcode to a string. 'QUERY', 'NOTIFY', 'UPDATE'.
|
||||
* With user buffer.
|
||||
* @param opcode: opcode as integer in host order
|
||||
* @param str: the string to write to.
|
||||
* @param len: length of str.
|
||||
* @return the number of characters for this element, excluding zerobyte.
|
||||
* Is larger or equal than str_len if output was truncated.
|
||||
*/
|
||||
int gldns_wire2str_opcode_buf(int opcode, char* str, size_t len);
|
||||
|
||||
/**
|
||||
* Convert wire dname to a string, "example.com.". With user buffer.
|
||||
* @param dname: the dname in uncompressed wireformat.
|
||||
|
@ -796,6 +809,19 @@ int gldns_wire2str_hip_scan(uint8_t** data, size_t* data_len, char** str,
|
|||
int gldns_wire2str_int16_data_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat tsigerror field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see gldns_wire2str_pkt_scan).
|
||||
* @param data: wireformat data.
|
||||
* @param data_len: length of data buffer.
|
||||
* @param str: string buffer.
|
||||
* @param str_len: length of string buffer.
|
||||
* @return number of characters (except null) needed to print.
|
||||
* Can return -1 on failure.
|
||||
*/
|
||||
int gldns_wire2str_tsigerror_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
size_t* str_len);
|
||||
|
||||
/**
|
||||
* Scan wireformat nsec3_next_owner field to string, with user buffers.
|
||||
* It shifts the arguments to move along (see gldns_wire2str_pkt_scan).
|
||||
|
|
Loading…
Reference in New Issue