Commit c9c18bc0 authored by Lubos Slovak's avatar Lubos Slovak

Checking previous time signed.

refs #1461 @30m
parent 88bda9b1
......@@ -389,7 +389,7 @@ static int xfr_check_tsig(knot_ns_xfr_t *xfr, knot_rcode_t *rcode)
*rcode = KNOT_RCODE_NOTAUTH;
xfr->tsig_key = NULL;
xfr->tsig_rcode = KNOT_TSIG_RCODE_BADKEY;
xfr->tsig_req_time_signed =
xfr->tsig_prev_time_signed =
tsig_rdata_time_signed(tsig_rr);
return KNOT_TSIG_EBADKEY;
}
......@@ -467,7 +467,7 @@ static int xfr_check_tsig(knot_ns_xfr_t *xfr, knot_rcode_t *rcode)
xfr->tsig_rcode = KNOT_TSIG_RCODE_BADTIME;
// store the time signed from the query
assert(tsig_rr != NULL);
xfr->tsig_req_time_signed =
xfr->tsig_prev_time_signed =
tsig_rdata_time_signed(tsig_rr);
*rcode = KNOT_RCODE_NOTAUTH;
break;
......
......@@ -2022,7 +2022,7 @@ static int ns_xfr_send_and_clear(knot_ns_xfr_t *xfr, int add_tsig)
xfr->digest_size, xfr->digest,
&digest_real_size,
xfr->tsig_key, xfr->tsig_rcode,
xfr->tsig_req_time_signed);
xfr->tsig_prev_time_signed);
} else {
/* Add key, digest and digest length. */
dbg_ns_detail("Calling tsig_sign_next()\n");
......
......@@ -120,7 +120,7 @@ typedef struct knot_ns_xfr {
size_t digest_max_size; /*!< Size of the buffer. */
uint16_t tsig_rcode;
uint64_t tsig_req_time_signed;
uint64_t tsig_prev_time_signed;
/*! \brief Previous digest or request digest.
*
......
......@@ -144,7 +144,8 @@ static int knot_tsig_compute_digest(const uint8_t *wire, size_t wire_len,
return KNOT_EOK;
}
static int knot_tsig_check_time_signed(const knot_rrset_t *tsig_rr)
static int knot_tsig_check_time_signed(const knot_rrset_t *tsig_rr,
uint64_t prev_time_signed)
{
if (!tsig_rr) {
return KNOT_EBADARG;
......@@ -164,7 +165,15 @@ static int knot_tsig_check_time_signed(const knot_rrset_t *tsig_rr)
time_t curr_time = time(NULL);
/*!< \todo bleeding eyes. */
if (difftime(curr_time, (time_t)time_signed) > fudge) {
double diff = difftime(curr_time, (time_t)time_signed);
if (diff > fudge || diff < -fudge) {
return KNOT_TSIG_EBADTIME;
}
diff = difftime((time_t)time_signed, prev_time_signed);
if (diff < 0) {
return KNOT_TSIG_EBADTIME;
}
......@@ -668,6 +677,7 @@ static int knot_tsig_check_digest(const knot_rrset_t *tsig_rr,
const uint8_t *request_mac,
size_t request_mac_len,
const knot_key_t *tsig_key,
uint64_t prev_time_signed,
int use_times)
{
if (!tsig_rr || !wire || !tsig_key) {
......@@ -675,7 +685,7 @@ static int knot_tsig_check_digest(const knot_rrset_t *tsig_rr,
}
/* Check time signed. */
int ret = knot_tsig_check_time_signed(tsig_rr);
int ret = knot_tsig_check_time_signed(tsig_rr, prev_time_signed);
if (ret != KNOT_EOK) {
return ret;
}
......@@ -797,30 +807,35 @@ int knot_tsig_server_check(const knot_rrset_t *tsig_rr,
const knot_key_t *tsig_key)
{
dbg_tsig_verb("tsig_server_check()\n");
return knot_tsig_check_digest(tsig_rr, wire, size, NULL, 0, tsig_key, 0);
return knot_tsig_check_digest(tsig_rr, wire, size, NULL, 0, tsig_key,
0, 0);
}
int knot_tsig_client_check(const knot_rrset_t *tsig_rr,
const uint8_t *wire, size_t size,
const uint8_t *request_mac, size_t request_mac_len,
const knot_key_t *tsig_key)
const knot_key_t *tsig_key,
uint64_t prev_time_signed)
{
dbg_tsig_verb("tsig_client_check()\n");
return knot_tsig_check_digest(tsig_rr, wire, size, request_mac,
request_mac_len, tsig_key, 0);
request_mac_len, tsig_key,
prev_time_signed, 0);
}
int knot_tsig_client_check_next(const knot_rrset_t *tsig_rr,
const uint8_t *wire, size_t size,
const uint8_t *prev_digest,
size_t prev_digest_len,
const knot_key_t *tsig_key)
const knot_key_t *tsig_key,
uint64_t prev_time_signed)
{
// return knot_tsig_client_check(tsig_rr, wire, size, prev_digest,
// prev_digest_len, tsig_key);
dbg_tsig_verb("tsig_client_check_next()\n");
return knot_tsig_check_digest(tsig_rr, wire, size, prev_digest,
prev_digest_len, tsig_key, 1);
prev_digest_len, tsig_key,
prev_time_signed, 1);
return KNOT_ENOTSUP;
}
......@@ -845,7 +860,7 @@ int knot_tsig_add(uint8_t *msg, size_t *msg_len, size_t msg_max_len,
KNOT_RRTYPE_TSIG, KNOT_CLASS_ANY, 0);
if (!tmp_tsig) {
dbg_tsig_detail("TSIG: tmp_tsig = NULL\n");
knot_dname_free(key_name);
knot_dname_free(&key_name);
return KNOT_ENOMEM;
}
......
......@@ -134,7 +134,8 @@ int knot_tsig_server_check(const knot_rrset_t *tsig_rr,
int knot_tsig_client_check(const knot_rrset_t *tsig_rr,
const uint8_t *wire, size_t size,
const uint8_t *request_mac, size_t request_mac_len,
const knot_key_t *key);
const knot_key_t *key,
uint64_t prev_time_signed);
/*!
* \brief Checks signature of 2nd or next packet in a TCP session.
......@@ -155,7 +156,8 @@ int knot_tsig_client_check_next(const knot_rrset_t *tsig_rr,
const uint8_t *wire, size_t size,
const uint8_t *prev_digest,
size_t prev_digest_len,
const knot_key_t *key);
const knot_key_t *key,
uint64_t prev_time_signed);
int knot_tsig_add(uint8_t *msg, size_t *msg_len, size_t msg_max_len,
uint16_t tsig_rcode);
......
......@@ -368,12 +368,14 @@ static int xfrin_check_tsig(knot_packet_t *packet, knot_ns_xfr_t *xfr,
ret = knot_tsig_client_check(tsig,
xfr->wire, xfr->wire_size,
xfr->digest, xfr->digest_size,
xfr->tsig_key);
xfr->tsig_key,
xfr->tsig_prev_time_signed);
} else {
ret = knot_tsig_client_check_next(tsig,
xfr->wire, xfr->wire_size,
xfr->digest, xfr->digest_size,
xfr->tsig_key);
xfr->tsig_key,
xfr->tsig_prev_time_signed);
}
if (ret != KNOT_EOK) {
......@@ -393,6 +395,12 @@ static int xfrin_check_tsig(knot_packet_t *packet, knot_ns_xfr_t *xfr,
memcpy(xfr->digest, tsig_rdata_mac(tsig),
tsig_rdata_mac_length(tsig));
xfr->digest_size = tsig_rdata_mac_length(tsig);
// Extract the time signed from the TSIG and store it
// We may rewrite the tsig_req_time_signed field
xfr->tsig_prev_time_signed =
tsig_rdata_time_signed(tsig);
} else { // TSIG not required and not there
// just append the wireformat to the TSIG data
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment