diff --git a/src/libknot/tsig-op.c b/src/libknot/tsig-op.c index 55316a9a6bece9747f483b3efbf8a100e706180c..9a760505ed9b9da36dbe3d2e5bf7ea333cef2824 100644 --- a/src/libknot/tsig-op.c +++ b/src/libknot/tsig-op.c @@ -485,43 +485,7 @@ int knot_tsig_sign(uint8_t *msg, size_t *msg_len, } /* Create rdata for TSIG RR. */ - knot_rdata_t *rdata = knot_rdata_new(); - if (!rdata) { - dbg_tsig("TSIG: rdata = NULL\n"); - knot_rrset_free(&tmp_tsig); - return KNOT_ENOMEM; - } - - knot_rrset_add_rdata(tmp_tsig, rdata); - - /* Create items for TSIG RR. */ - knot_rrtype_descriptor_t *desc = - knot_rrtype_descriptor_by_type(KNOT_RRTYPE_TSIG); - assert(desc); - - knot_rdata_item_t *items = - malloc(sizeof(knot_rdata_item_t) * desc->length); - if (!items) { - dbg_tsig("TSIG: items = NULL\n"); - ERR_ALLOC_FAILED; - knot_rrset_free(&tmp_tsig); - knot_rdata_free(&rdata); - return KNOT_ENOMEM; - } - - memset(items, 0, sizeof(knot_rdata_item_t) * desc->length); - - int ret = knot_rdata_set_items(rdata, items, desc->length); - if (ret != KNOT_EOK) { - dbg_tsig("TSIG: rdata_set_items returned %s\n", - knot_strerror(ret)); - free(items); - knot_rrset_free(&tmp_tsig); - knot_rdata_free(&rdata); - return ret; - } - free(items); - + tsig_create_rdata(tmp_tsig, key->algorithm); tsig_rdata_set_alg(tmp_tsig, key->algorithm); /* Distinguish BADTIME response. */ @@ -556,8 +520,9 @@ int knot_tsig_sign(uint8_t *msg, size_t *msg_len, size_t digest_tmp_len = 0; dbg_tsig_detail("tmp_tsig before sign_wire():\n"); - knot_rrset_dump(tmp_tsig, 0); + knot_rrset_dump(tmp_tsig); + int ret = KNOT_ERROR; ret = knot_tsig_create_sign_wire(msg, *msg_len, /*msg_max_len,*/ request_mac, request_mac_len, digest_tmp, &digest_tmp_len, @@ -565,7 +530,7 @@ int knot_tsig_sign(uint8_t *msg, size_t *msg_len, if (ret != KNOT_EOK) { dbg_tsig("TSIG: could not create wire or sign wire: %s\n", knot_strerror(ret)); - knot_rrset_deep_free(&tmp_tsig, 1, 1, 1); + knot_rrset_deep_free(&tmp_tsig, 1, 1); return ret; } @@ -582,11 +547,11 @@ int knot_tsig_sign(uint8_t *msg, size_t *msg_len, if (ret != KNOT_EOK) { dbg_tsig("TSIG: rrset_to_wire = %s\n", knot_strerror(ret)); *digest_len = 0; - knot_rrset_deep_free(&tmp_tsig, 1, 1, 1); + knot_rrset_deep_free(&tmp_tsig, 1, 1); return ret; } - knot_rrset_deep_free(&tmp_tsig, 1, 1, 1); + knot_rrset_deep_free(&tmp_tsig, 1, 1); *msg_len += tsig_wire_len; @@ -621,51 +586,8 @@ int knot_tsig_sign_next(uint8_t *msg, size_t *msg_len, size_t msg_max_len, } /* Create rdata for TSIG RR. */ - knot_rdata_t *rdata = knot_rdata_new(); - if (!rdata) { - dbg_tsig("TSIG: rdata = NULL\n"); - knot_rrset_free(&tmp_tsig); - return KNOT_ENOMEM; - } - - int ret = 0; - - ret = knot_rrset_add_rdata(tmp_tsig, rdata); - if (ret != KNOT_EOK) { - dbg_tsig("TSIG: could not add rdata\n"); - knot_rrset_free(&tmp_tsig); - knot_rdata_free(&rdata); - return ret; - } - - /* Create items for TSIG RR. */ - knot_rrtype_descriptor_t *desc = - knot_rrtype_descriptor_by_type(KNOT_RRTYPE_TSIG); - assert(desc); - - knot_rdata_item_t *items = - malloc(sizeof(knot_rdata_item_t) * desc->length); - if (!items) { - dbg_tsig("TSIG: items = NULL\n"); - ERR_ALLOC_FAILED; - knot_rrset_free(&tmp_tsig); - knot_rdata_free(&rdata); - return KNOT_ENOMEM; - } - - memset(items, 0, sizeof(knot_rdata_item_t) * desc->length); - - ret = knot_rdata_set_items(rdata, items, desc->length); - if (ret != KNOT_EOK) { - dbg_tsig("TSIG: rdata_set_items returned %s\n", - knot_strerror(ret)); - knot_rrset_free(&tmp_tsig); - knot_rdata_free(&rdata); - free(items); - return ret; - } - free(items); - + tsig_create_rdata(tmp_tsig, key->algorithm); + tsig_rdata_set_alg(tmp_tsig, key->algorithm); tsig_rdata_store_current_time(tmp_tsig); tsig_rdata_set_fudge(tmp_tsig, KNOT_TSIG_FUDGE_DEFAULT); @@ -675,8 +597,7 @@ int knot_tsig_sign_next(uint8_t *msg, size_t *msg_len, size_t msg_max_len, uint8_t *wire = malloc(wire_len); if (!wire) { ERR_ALLOC_FAILED; - knot_rrset_free(&tmp_tsig); - knot_rdata_deep_free(&rdata, KNOT_RRTYPE_TSIG, 0); + knot_rrset_deep_free(&tmp_tsig, 1, 1); return KNOT_ENOMEM; } memset(wire, 0, wire_len); @@ -698,19 +619,20 @@ int knot_tsig_sign_next(uint8_t *msg, size_t *msg_len, size_t msg_max_len, dbg_tsig_hex_detail(wire + prev_digest_len + *msg_len, KNOT_TSIG_TIMERS_LENGTH); + int ret = KNOT_ERROR; ret = knot_tsig_compute_digest(wire, wire_len, digest_tmp, &digest_tmp_len, key); /* No matter how the function did, this data is no longer needed. */ free(wire); if (ret != KNOT_EOK) { - knot_rrset_deep_free(&tmp_tsig, 1, 1, 1); + knot_rrset_deep_free(&tmp_tsig, 1, 1); *digest_len = 0; return ret; } if (digest_tmp_len > *digest_len) { - knot_rrset_deep_free(&tmp_tsig, 1, 1, 1); + knot_rrset_deep_free(&tmp_tsig, 1, 1); *digest_len = 0; return KNOT_ESPACE; } @@ -738,18 +660,18 @@ int knot_tsig_sign_next(uint8_t *msg, size_t *msg_len, size_t msg_max_len, ret = knot_rrset_to_wire(tmp_tsig, msg + *msg_len, &tsig_wire_size, &rr_count); if (ret != KNOT_EOK) { - knot_rrset_deep_free(&tmp_tsig, 1, 1, 1); + knot_rrset_deep_free(&tmp_tsig, 1, 1); *digest_len = 0; return ret; } /* This should not happen, at least one rr has to be converted. */ if (rr_count == 0) { - knot_rrset_deep_free(&tmp_tsig, 1, 1, 1); + knot_rrset_deep_free(&tmp_tsig, 1, 1); return KNOT_EINVAL; } - knot_rrset_deep_free(&tmp_tsig, 1, 1, 1); + knot_rrset_deep_free(&tmp_tsig, 1, 1); *msg_len += tsig_wire_size; uint16_t arcount = knot_wire_get_arcount(msg); @@ -940,47 +862,24 @@ int knot_tsig_add(uint8_t *msg, size_t *msg_len, size_t msg_max_len, /* Already referenced in tmp_tsig, release. */ knot_dname_release(key_name); - /* Create rdata for TSIG RR. */ - knot_rdata_t *rdata = knot_rdata_new(); - if (!rdata) { - dbg_tsig("TSIG: rdata = NULL\n"); - knot_rrset_deep_free(&tmp_tsig, 1, 1, 1); - return KNOT_ENOMEM; - } - - knot_rrset_add_rdata(tmp_tsig, rdata); - - /* Create items for TSIG RR. */ - knot_rrtype_descriptor_t *desc = - knot_rrtype_descriptor_by_type(KNOT_RRTYPE_TSIG); - assert(desc); - - knot_rdata_item_t *items = - malloc(sizeof(knot_rdata_item_t) * desc->length); - if (items == NULL) { - dbg_tsig("TSIG: items = NULL\n"); - knot_rrset_deep_free(&tmp_tsig, 1, 1, 1); - return KNOT_ENOMEM; - } - - memset(items, 0, sizeof(knot_rdata_item_t) * desc->length); - - int ret = knot_rdata_set_items(rdata, items, desc->length); - free(items); - if (ret != KNOT_EOK) { - dbg_tsig("TSIG: rdata_set_items returned %s\n", - knot_strerror(ret)); - knot_rrset_deep_free(&tmp_tsig, 1, 1, 1); - return ret; - } - knot_dname_t *alg_name = knot_dname_deep_copy(tsig_rdata_alg_name(tsig_rr)); if (alg_name == NULL) { dbg_tsig("TSIG: failed to copy alg name\n"); - knot_rrset_deep_free(&tmp_tsig, 1, 1, 1); + knot_rrset_deep_free(&tmp_tsig, 1, 1); + return KNOT_ERROR; + } + + + /* Create rdata for TSIG RR. */ + tsig_algorithm_t alg = tsig_alg_from_name(alg_name); + if (alg == KNOT_TSIG_ALG_NULL) { + dbg_tsig("TSIG: refusing to use NULL algorithm\n"); + knot_rrset_deep_free(&tmp_tsig, 1, 1); + knot_dname_free(&alg_name); return KNOT_ERROR; } + tsig_create_rdata(tmp_tsig, alg); tsig_rdata_set_alg_name(tmp_tsig, alg_name); tsig_rdata_set_time_signed(tmp_tsig, tsig_rdata_time_signed(tsig_rr)); @@ -1006,16 +905,17 @@ int knot_tsig_add(uint8_t *msg, size_t *msg_len, size_t msg_max_len, int rr_count = 0; /* Write RRSet to wire */ + int ret = KNOT_ERROR; ret = knot_rrset_to_wire(tmp_tsig, msg + *msg_len, &tsig_wire_len, &rr_count); if (ret != KNOT_EOK) { dbg_tsig("TSIG: rrset_to_wire = %s\n", knot_strerror(ret)); - knot_rrset_deep_free(&tmp_tsig, 1, 1, 1); + knot_rrset_deep_free(&tmp_tsig, 1, 1); return ret; } /* key_name already referenced in RRSet, no need to free separately. */ - knot_rrset_deep_free(&tmp_tsig, 1, 1, 1); + knot_rrset_deep_free(&tmp_tsig, 1, 1); *msg_len += tsig_wire_len; diff --git a/src/libknot/tsig.c b/src/libknot/tsig.c index 1977384a11e88b76bbea5174482de73a09e98edd..e6ea268edb31db58400d26451c745ca1d5dc8a07 100644 --- a/src/libknot/tsig.c +++ b/src/libknot/tsig.c @@ -41,293 +41,206 @@ static knot_lookup_table_t tsig_alg_table[TSIG_ALG_TABLE_SIZE] = { { KNOT_TSIG_ALG_NULL, NULL } }; -int tsig_rdata_init(knot_rrset_t *tsig) +/*! \brief TSIG field offsets. */ +typedef enum tsig_off_t { + TSIG_ALGNAME_O = 0, + TSIG_TSIGNED_O, + TSIG_FUDGE_O, + TSIG_MACLEN_O, + TSIG_MAC_O, + TSIG_ORIGID_O, + TSIG_ERROR_O, + TSIG_OLEN_O, + TSIG_OTHER_O +} tsig_off_t; + +/* Helpers for r offset calculation. */ +#define TSIG_NAMELEN (sizeof(knot_dname_t*)) +#define TSIG_OTHER_MAXLEN (3 * sizeof(uint16_t)) +#define TSIG_OFF_MACLEN (TSIG_NAMELEN + 4 * sizeof(uint16_t)) +#define TSIG_FIXED_RDLEN (TSIG_NAMELEN + 11 * sizeof(uint16_t)) + +static uint8_t* tsig_rdata_seek(const knot_rrset_t *rr, tsig_off_t id, size_t nb) { - if (!tsig) { - return KNOT_EINVAL; + uint8_t *rd = knot_rrset_get_rdata(rr, 0); + if (rd == NULL) { + return NULL; } - - /* Initializes rdata. */ - tsig->rdata = knot_rdata_new(); - if (!tsig->rdata) { - return KNOT_ENOMEM; + + /* Check if fixed part is readable. */ + uint32_t lim = rrset_rdata_item_size(rr, 0); + if (lim < TSIG_NAMELEN + 5 * sizeof(uint16_t)) { + dbg_tsig("TSIG: rdata: not enough items.\n"); + return NULL; } - - tsig->rdata->items = - malloc(sizeof(knot_rdata_item_t) * KNOT_TSIG_ITEM_COUNT); - if (!tsig->rdata->items) { - return KNOT_ENOMEM; + + /* Not pretty, but fast. */ + uint8_t *bp = rd; + switch(id) { + case TSIG_ALGNAME_O: break; + case TSIG_TSIGNED_O: rd += TSIG_NAMELEN; break; + case TSIG_FUDGE_O: rd += TSIG_NAMELEN + 3 * sizeof(uint16_t); break; + case TSIG_MACLEN_O: rd += TSIG_NAMELEN + 4 * sizeof(uint16_t); break; + case TSIG_MAC_O: rd += TSIG_NAMELEN + 5 * sizeof(uint16_t); break; + case TSIG_ORIGID_O: + rd += TSIG_NAMELEN + 4 * sizeof(uint16_t); + rd += *((uint16_t*)rd) + sizeof(uint16_t); + break; + + case TSIG_ERROR_O: + rd += TSIG_NAMELEN + 4 * sizeof(uint16_t); + rd += *((uint16_t*)rd) + 2 * sizeof(uint16_t); + break; + case TSIG_OLEN_O: + rd += TSIG_NAMELEN + 4 * sizeof(uint16_t); + rd += *((uint16_t*)rd) + 3 * sizeof(uint16_t); + break; + case TSIG_OTHER_O: + rd += TSIG_NAMELEN + 4 * sizeof(uint16_t); + rd += *((uint16_t*)rd) + 4 * sizeof(uint16_t); + break; } - - memset(tsig->rdata->items, 0, - sizeof(knot_rdata_item_t) * KNOT_TSIG_ITEM_COUNT); - - return KNOT_EOK; + + /* Check remaining bytes. */ + if (rd + nb > bp + lim) { + dbg_tsig("TSIG: rdata: not enough items.\n"); + return NULL; + } + + return rd; } -int tsig_rdata_set_alg_name(knot_rrset_t *tsig, knot_dname_t *alg_name) +int tsig_create_rdata(knot_rrset_t *rr, tsig_algorithm_t alg) { - if (!tsig) { - return KNOT_EINVAL; - } - - knot_rdata_t *rdata = knot_rrset_get_rdata(tsig); - if (!rdata) { + if (!rr) { return KNOT_EINVAL; } - assert(knot_rdata_item_count(rdata) >= 1); - - knot_dname_t *alg_name_copy = knot_dname_deep_copy(alg_name); - if (!alg_name_copy) { - return KNOT_ENOMEM; - } - - knot_rdata_item_set_dname(rdata, 0, alg_name_copy); - /* Release the dname. We want it to have 1 reference only. */ - knot_dname_release(alg_name_copy); + /* We already checked rr and know rdlen > 0, no need to check rets. */ + uint16_t alen = tsig_alg_digest_length(alg); + size_t rdlen = TSIG_FIXED_RDLEN + alen; + uint8_t *rd = knot_rrset_create_rdata(rr, rdlen); + memset(rd, 0, rdlen); + + /* Set MAC variable length in advance. */ + rd += TSIG_OFF_MACLEN; + knot_wire_write_u16(rd, alen); return KNOT_EOK; } -void rrset_rdata_tsig_set_alg_name(knot_rrset_t *rrset, - const knot_dname_t *alg_name) +int tsig_rdata_set_alg_name(knot_rrset_t *tsig, knot_dname_t *alg_name) { - if (tsig == NULL) { - return; + uint8_t *rd = tsig_rdata_seek(tsig, TSIG_ALGNAME_O, TSIG_NAMELEN); + if (!rd) { + return KNOT_ERROR; } - uint8_t *rdata = rrset_rdata_pointer(rrset, 0); //tady by byla pozice v RR u normalni RRSetu - treba u NS - //alg name je prvni v "poli" a ma velikost sizeof(knot_dname_t *) - size_t offset = 0; - memcpy(rdata + offset, &alg_name, sizeof(knot_dname_t *)); + memcpy(rd, &alg_name, sizeof(knot_dname_t*)); + knot_dname_retain(alg_name); + return KNOT_EOK; } int tsig_rdata_set_alg(knot_rrset_t *tsig, tsig_algorithm_t alg) { - if (!tsig) { - return KNOT_EINVAL; - } - - knot_rdata_t *rdata = knot_rrset_get_rdata(tsig); - if (!rdata) { - return KNOT_EINVAL; - } - assert(knot_rdata_item_count(rdata) >= 1); - - const char *alg_str = tsig_alg_to_str(alg); - knot_dname_t *alg_name_copy = knot_dname_new_from_str(alg_str, - strlen(alg_str), - NULL); - if (!alg_name_copy) { - return KNOT_ENOMEM; - } - - knot_rdata_item_set_dname(rdata, 0, alg_name_copy); - - /* Release the dname. We want it to have 1 reference only. */ - knot_dname_release(alg_name_copy); - - return KNOT_EOK; + const char *s = tsig_alg_to_str(alg); + knot_dname_t *alg_name = knot_dname_new_from_str(s, strlen(s), NULL); + int ret = tsig_rdata_set_alg_name(tsig, alg_name); + knot_dname_release(alg_name); + return ret; } int tsig_rdata_set_time_signed(knot_rrset_t *tsig, uint64_t time) { - if (!tsig) { - return KNOT_EINVAL; - } - - knot_rdata_t *rdata = knot_rrset_get_rdata(tsig); - if (!rdata) { - return KNOT_EINVAL; - } - assert(knot_rdata_item_count(rdata) >= 2); - - /* Create the wire format. */ - uint16_t *wire = malloc(sizeof(uint8_t) * 6 + sizeof(uint16_t)); - if (!wire) { - ERR_ALLOC_FAILED; - return KNOT_ENOMEM; + uint8_t *rd = tsig_rdata_seek(tsig, TSIG_TSIGNED_O, 3*sizeof(uint16_t)); + if (!rd) { + return KNOT_ERROR; } - - /* Write the length - 6. */ - wire[0] = 6; - knot_wire_write_u48((uint8_t *)(wire + 1), time); - - knot_rdata_item_set_raw_data(rdata, 1, wire); - + + knot_wire_write_u48(rd, time); return KNOT_EOK; } int tsig_rdata_set_fudge(knot_rrset_t *tsig, uint16_t fudge) { - if (!tsig) { - return KNOT_EINVAL; - } - - knot_rdata_t *rdata = knot_rrset_get_rdata(tsig); - if (!rdata) { - return KNOT_EINVAL; - } - assert(knot_rdata_item_count(rdata) >= 3); - - /* Create the wire format. */ - uint16_t *wire = malloc(sizeof(uint8_t) * 2 + sizeof(uint16_t)); - if (!wire) { - ERR_ALLOC_FAILED; - return KNOT_ENOMEM; + uint8_t *rd = tsig_rdata_seek(tsig, TSIG_FUDGE_O, sizeof(uint16_t)); + if (!rd) { + return KNOT_ERROR; } - - /* Write the length - 2. */ - wire[0] = sizeof(uint16_t); - knot_wire_write_u16((uint8_t *)(wire + 1), fudge); - - knot_rdata_item_set_raw_data(rdata, 2, wire); - + + knot_wire_write_u16(rd, fudge); return KNOT_EOK; } int tsig_rdata_set_mac(knot_rrset_t *tsig, uint16_t length, const uint8_t *mac) { - if (!tsig) { - return KNOT_EINVAL; - } - - knot_rdata_t *rdata = knot_rrset_get_rdata(tsig); - if (!rdata) { - return KNOT_EINVAL; - } - assert(knot_rdata_item_count(rdata) >= 4); - - /* Create the wire format. */ - uint16_t *wire = malloc(sizeof(uint8_t) * length + 2 * sizeof(uint16_t)); - if (!wire) { - ERR_ALLOC_FAILED; - return KNOT_ENOMEM; + uint8_t *rd = tsig_rdata_seek(tsig, TSIG_MAC_O, length); + if (!rd) { + return KNOT_ERROR; } + + /*! \note Cannot change length, as rdata is already preallocd. */ - /* Write the length. */ - wire[0] = length + sizeof(uint16_t); - knot_wire_write_u16((uint8_t *)(wire + 1), length); /* Copy the actual MAC. */ - memcpy((uint8_t *)(wire + 2), mac, sizeof(uint8_t) * length); - knot_rdata_item_set_raw_data(rdata, 3, wire); - + memcpy(rd, mac, length); return KNOT_EOK; } int tsig_rdata_set_orig_id(knot_rrset_t *tsig, uint16_t id) { - if (!tsig) { - return KNOT_EINVAL; - } - - knot_rdata_t *rdata = knot_rrset_get_rdata(tsig); - if (!rdata) { - return KNOT_EINVAL; - } - assert(knot_rdata_item_count(rdata) >= 5); - - /* Create the wire format. */ - uint16_t *wire = malloc(sizeof(uint8_t) * 2 + sizeof(uint16_t)); - if (!wire) { - ERR_ALLOC_FAILED; - return KNOT_ENOMEM; + uint8_t *rd = tsig_rdata_seek(tsig, TSIG_ORIGID_O, sizeof(uint16_t)); + if (!rd) { + return KNOT_ERROR; } - + /* Write the length - 2. */ - wire[0] = sizeof(uint16_t); - knot_wire_write_u16((uint8_t *)(wire + 1), id); - - knot_rdata_item_set_raw_data(rdata, 4, wire); - + knot_wire_write_u16(rd, id); return KNOT_EOK; } int tsig_rdata_set_tsig_error(knot_rrset_t *tsig, uint16_t tsig_error) { - if (!tsig) { - return KNOT_EINVAL; - } - - knot_rdata_t *rdata = knot_rrset_get_rdata(tsig); - if (!rdata) { - return KNOT_EINVAL; - } - assert(knot_rdata_item_count(rdata) >= 6); - - /* Create the wire format. */ - uint16_t *wire = malloc(sizeof(uint8_t) * 2 + sizeof(uint16_t)); - if (!wire) { - ERR_ALLOC_FAILED; - return KNOT_ENOMEM; + uint8_t *rd = tsig_rdata_seek(tsig, TSIG_ERROR_O, sizeof(uint16_t)); + if (!rd) { + return KNOT_ERROR; } - - /* Write the length - 2. */ - wire[0] = sizeof(uint16_t); - knot_wire_write_u16((uint8_t *)(wire + 1), tsig_error); - - knot_rdata_item_set_raw_data(rdata, 5, wire); - + + knot_wire_write_u16(rd, tsig_error); return KNOT_EOK; } -int tsig_rdata_set_other_data(knot_rrset_t *tsig, uint16_t length, +int tsig_rdata_set_other_data(knot_rrset_t *tsig, uint16_t len, const uint8_t *other_data) { - if (!tsig) { - return KNOT_EINVAL; - } - - knot_rdata_t *rdata = knot_rrset_get_rdata(tsig); - if (!rdata) { + if (len > TSIG_OTHER_MAXLEN) { + dbg_tsig("TSIG: rdata: other len > %uB\n", TSIG_OTHER_MAXLEN); return KNOT_EINVAL; } - assert(knot_rdata_item_count(rdata) >= 6); - /* Create the wire format. */ - uint16_t *wire = malloc(sizeof(uint8_t) * length + 2 * sizeof(uint16_t)); - if (!wire) { - ERR_ALLOC_FAILED; - return KNOT_ENOMEM; + uint8_t *rd = tsig_rdata_seek(tsig, TSIG_OLEN_O, len+sizeof(uint16_t)); + if (!rd) { + return KNOT_ERROR; } - + /* Write the length. */ - wire[0] = length + 2; - knot_wire_write_u16((uint8_t *)(wire + 1), length); + knot_wire_write_u16(rd, len); + /* Copy the actual data. */ - memcpy(wire + 2, other_data, sizeof(uint8_t) * length); - knot_rdata_item_set_raw_data(rdata, 6, wire); - + memcpy(rd + sizeof(uint16_t), other_data, len); return KNOT_EOK; } const knot_dname_t *tsig_rdata_alg_name(const knot_rrset_t *tsig) { - if (!tsig) { - return NULL; - } - - const knot_rdata_t *rdata = knot_rrset_rdata(tsig); - if (!rdata) { - dbg_tsig("TSIG: rdata: alg name: no rdata.\n"); + uint8_t *rd = tsig_rdata_seek(tsig, TSIG_ALGNAME_O, TSIG_NAMELEN); + if (!rd) { return NULL; } - - if (knot_rdata_item_count(rdata) < 1) { - dbg_tsig("TSIG: rdata: alg name: not enough items.\n"); - return NULL; - } - - return knot_rdata_item(rdata, 0)->dname; + return *((knot_dname_t**)rd); } tsig_algorithm_t tsig_rdata_alg(const knot_rrset_t *tsig) { - if (!tsig) { - return KNOT_TSIG_ALG_NULL; - } - /* Get the algorithm name. */ const knot_dname_t *alg_name = tsig_rdata_alg_name(tsig); if (!alg_name) { @@ -348,177 +261,80 @@ tsig_algorithm_t tsig_rdata_alg(const knot_rrset_t *tsig) dbg_tsig("TSIG: rdata: unknown algorithm.\n"); return KNOT_TSIG_ALG_NULL; } - return item->id; } uint64_t tsig_rdata_time_signed(const knot_rrset_t *tsig) { - /*! \note How about assert. Or maybe change API??? */ - if (!tsig) { - return 0; - } - - const knot_rdata_t *rdata = knot_rrset_rdata(tsig); - if (!rdata) { - return 0; - } - - if (knot_rdata_item_count(rdata) < 2) { + /*! \todo How to return invalid value? */ + uint8_t *rd = tsig_rdata_seek(tsig, TSIG_TSIGNED_O, 3*sizeof(uint16_t)); + if (!rd) { return 0; } - - uint16_t *wire = knot_rdata_item(rdata, 1)->raw_data; - assert(wire[0] == 6); - /* Skip the size. */ - wire++; - - return knot_wire_read_u48((uint8_t *)wire); + return knot_wire_read_u48(rd); } uint16_t tsig_rdata_fudge(const knot_rrset_t *tsig) { - /*! \note How about assert. Or maybe change API??? */ - if (!tsig) { - return 0; - } - - const knot_rdata_t *rdata = knot_rrset_rdata(tsig); - if (!rdata) { - return 0; - } - - if (knot_rdata_item_count(rdata) < 3) { + uint8_t *rd = tsig_rdata_seek(tsig, TSIG_FUDGE_O, sizeof(uint16_t)); + if (!rd) { return 0; } - - uint16_t *wire = knot_rdata_item(rdata, 2)->raw_data; - assert(wire[0] == 2); - /* Skip the size. */ - wire++; - - return knot_wire_read_u16((uint8_t *)wire); + return knot_wire_read_u16(rd); } const uint8_t *tsig_rdata_mac(const knot_rrset_t *tsig) { - /*! \note How about assert. Or maybe change API??? */ - if (!tsig) { - return 0; - } - - const knot_rdata_t *rdata = knot_rrset_rdata(tsig); - if (!rdata) { - return 0; - } - - if (knot_rdata_item_count(rdata) < 4) { - return 0; + uint8_t *rd = tsig_rdata_seek(tsig, TSIG_MAC_O, 0); + if (!rd) { + return NULL; } - - return (uint8_t*)(knot_rdata_item(rdata, 3)->raw_data + 2); + return rd; } size_t tsig_rdata_mac_length(const knot_rrset_t *tsig) { - if (!tsig) { - return 0; - } - - const knot_rdata_t *rdata = knot_rrset_rdata(tsig); - if (!rdata || knot_rdata_item_count(rdata) < 4) { + uint8_t *rd = tsig_rdata_seek(tsig, TSIG_MACLEN_O, sizeof(uint16_t)); + if (!rd) { return 0; } - - return knot_wire_read_u16( - (uint8_t *)(knot_rdata_item(rdata, 3)->raw_data + 1)); + return knot_wire_read_u16(rd); } uint16_t tsig_rdata_orig_id(const knot_rrset_t *tsig) { - /*! \note How about assert. Or maybe change API??? */ - if (!tsig) { - return 0; - } - - const knot_rdata_t *rdata = knot_rrset_rdata(tsig); - if (!rdata) { - return 0; - } - - if (knot_rdata_item_count(rdata) < 5) { - return 0; + uint8_t *rd = tsig_rdata_seek(tsig, TSIG_ORIGID_O, sizeof(uint16_t)); + if (!rd) { + return KNOT_ERROR; } - - uint16_t *wire = knot_rdata_item(rdata, 4)->raw_data; - assert(wire[0] == 2); - /* Skip the size. */ - wire++; - - return knot_wire_read_u16((uint8_t *)wire); + return knot_wire_read_u16(rd); } uint16_t tsig_rdata_error(const knot_rrset_t *tsig) { - /*! \note How about assert. Or maybe change API??? */ - if (!tsig) { - return 0; - } - - const knot_rdata_t *rdata = knot_rrset_rdata(tsig); - if (!rdata) { - return 0; - } - - if (knot_rdata_item_count(rdata) < 6) { - return 0; + uint8_t *rd = tsig_rdata_seek(tsig, TSIG_ERROR_O, sizeof(uint16_t)); + if (!rd) { + return KNOT_ERROR; } - - uint16_t *wire = knot_rdata_item(rdata, 5)->raw_data; - assert(wire[0] == 2); - /* Skip the size. */ - wire++; - - return knot_wire_read_u16((uint8_t *)wire); + return knot_wire_read_u16(rd); } const uint8_t *tsig_rdata_other_data(const knot_rrset_t *tsig) { - /*! \note How about assert. Or maybe change API??? */ - if (!tsig) { - return 0; - } - - const knot_rdata_t *rdata = knot_rrset_rdata(tsig); - if (!rdata) { - return 0; - } - - if (knot_rdata_item_count(rdata) < 7) { - return 0; + uint8_t *rd = tsig_rdata_seek(tsig, TSIG_OTHER_O, 0); + if (!rd) { + return NULL; } - - return (uint8_t *)(knot_rdata_item(rdata, 6)->raw_data + 2); + return rd; } uint16_t tsig_rdata_other_data_length(const knot_rrset_t *tsig) { - /*! \note How about assert. Or maybe change API??? */ - if (!tsig) { - return 0; - } - - const knot_rdata_t *rdata = knot_rrset_rdata(tsig); - if (!rdata) { - return 0; + uint8_t *rd = tsig_rdata_seek(tsig, TSIG_OLEN_O, sizeof(uint16_t)); + if (!rd) { + return KNOT_ERROR; } - - if (knot_rdata_item_count(rdata) < 7) { - return 0; - } - - return knot_wire_read_u16((uint8_t *) - (knot_rdata_item(rdata, 6)->raw_data + 1)); + return knot_wire_read_u16(rd); } int tsig_alg_from_name(const knot_dname_t *alg_name) @@ -592,6 +408,7 @@ size_t tsig_rdata_tsig_variables_length(const knot_rrset_t *tsig) size_t tsig_rdata_tsig_timers_length() { + /*! \todo Cleanup */ return KNOT_TSIG_TIMERS_LENGTH; } @@ -615,6 +432,7 @@ const char* tsig_alg_to_str(tsig_algorithm_t alg) } } + /*! \todo Why not NULL? */ return ""; } @@ -626,6 +444,7 @@ size_t tsig_wire_maxsize(const knot_key_t* key) size_t alg_name_size = strlen(tsig_alg_to_str(key->algorithm)) + 1; + /*! \todo Used fixed size as a base. */ return knot_dname_size(key->name) + sizeof(uint16_t) + /* TYPE */ sizeof(uint16_t) + /* CLASS */ @@ -648,6 +467,7 @@ size_t tsig_wire_actsize(const knot_rrset_t *tsig) return 0; } + /*! \todo Used fixed size as a base. */ return knot_dname_size(knot_rrset_owner(tsig)) + sizeof(uint16_t) + /* TYPE */ sizeof(uint16_t) + /* CLASS */ @@ -666,10 +486,13 @@ size_t tsig_wire_actsize(const knot_rrset_t *tsig) int tsig_rdata_is_ok(const knot_rrset_t *tsig) { + /*! \todo Check size, needs to check variable-length fields. */ return (tsig - && knot_rrset_rdata(tsig) != NULL - && knot_rdata_item_count(knot_rrset_rdata(tsig)) >= 7 + && knot_rrset_get_rdata(tsig, 0) != NULL + && tsig_rdata_seek(tsig, TSIG_OTHER_O, 0) != NULL && tsig_rdata_alg_name(tsig) != NULL && tsig_rdata_time_signed(tsig) != 0); } + + diff --git a/src/libknot/tsig.h b/src/libknot/tsig.h index cd5910fc06f7bb3ce8caa73fc178a8dd7c1346cf..59c5785865ebb456eaa7257d63cd19536cb0601f 100644 --- a/src/libknot/tsig.h +++ b/src/libknot/tsig.h @@ -90,6 +90,7 @@ enum tsig_consts { /*! * \note Uses the given domain name, do not deallocate it! */ +int tsig_create_rdata(knot_rrset_t *rr, tsig_algorithm_t alg); int tsig_rdata_set_alg_name(knot_rrset_t *tsig, knot_dname_t *alg_name); int tsig_rdata_set_alg(knot_rrset_t *tsig, tsig_algorithm_t alg); int tsig_rdata_set_time_signed(knot_rrset_t *tsig, uint64_t time);