From: W.C.A. Wijngaards Date: Tue, 24 Jun 2025 14:51:41 +0000 (+0200) Subject: - xfr-tsig, tsig_find_rr function. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b5beb800c869b9f1eded4a0476c76036b2fcefc6;p=thirdparty%2Funbound.git - xfr-tsig, tsig_find_rr function. --- diff --git a/testcode/unittsig.c b/testcode/unittsig.c index 9b4c05393..7fb090758 100644 --- a/testcode/unittsig.c +++ b/testcode/unittsig.c @@ -525,10 +525,16 @@ handle_tsig_verify_query(char* line, struct tsig_key_table* key_table, fatal_exit("expected int argument for %s", expected_other_str); if(vtest) - printf("tsig-sign-query with %s %d %d\n", keyname, + printf("tsig-verify-query with %s %d %d\n", keyname, (int)timepoint, expected_rcode); /* Put position before TSIG */ + if(!tsig_find_rr(pkt)) { + if(vtest) + printf("tsig-verify-query found no TSIG RR\n"); + unit_assert(0); + return; + } ret = tsig_parse_verify_query(key_table, pkt, &tsig, NULL, timepoint); if(vtest) { diff --git a/testdata/tsig_test.1 b/testdata/tsig_test.1 index c636a8639..ba4075923 100644 --- a/testdata/tsig_test.1 +++ b/testdata/tsig_test.1 @@ -53,3 +53,5 @@ endpacket #packet #e7078400000100010000000203777777076578616d706c65036e65740000010001c00c0001000100000e1000040a141e2800002904d00000000000000474657374036b65790000fa00ff00000000003a08686d61632d6d6435077369672d616c670372656703696e740000006855490d012c0010dc3c138476fcb04cc138aa5c59647b86e70700000000 #endpacket +# +#tsig-verify-query test.key 1750419725 0 0 0 diff --git a/util/tsig.c b/util/tsig.c index 41037fd2a..e9d913f83 100644 --- a/util/tsig.c +++ b/util/tsig.c @@ -1382,3 +1382,57 @@ tsig_parse_verify_query(struct tsig_key_table* key_table, lock_rw_unlock(&key_table->lock); return ret; } + +int +tsig_find_rr(struct sldns_buffer* pkt) +{ + size_t end_pos, n_rrs; + if(sldns_buffer_limit(pkt) < LDNS_HEADER_SIZE) { + verbose(VERB_ALGO, "No TSIG, packet too short"); + return 0; + } + if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) < 1) { + verbose(VERB_ALGO, "No TSIG found, ARCOUNT == 0"); + return 0; + } + n_rrs = LDNS_ANCOUNT(sldns_buffer_begin(pkt)) + + LDNS_NSCOUNT(sldns_buffer_begin(pkt)) + + LDNS_ARCOUNT(sldns_buffer_begin(pkt)) + - 1; + + sldns_buffer_rewind(pkt); + sldns_buffer_skip(pkt, LDNS_HEADER_SIZE); + + /* Skip qnames. */ + if(!skip_pkt_query_rrs(pkt, LDNS_QDCOUNT(sldns_buffer_begin(pkt)))) { + verbose(VERB_ALGO, "No TSIG, query section RRs malformed"); + return 0; + } + /* Skip all rrs. */ + if(!skip_pkt_rrs(pkt, n_rrs)) { + verbose(VERB_ALGO, "No TSIG, packet RRs are malformed"); + return 0; + } + end_pos = sldns_buffer_position(pkt); + + /* The tsig owner name, the key name */ + if(sldns_buffer_remaining(pkt) < 1) { + verbose(VERB_ALGO, "No TSIG, packet too short"); + return 0; + } + if(!pkt_dname_len(pkt)) { + verbose(VERB_ALGO, "No TSIG, dname malformed"); + return 0; + } + if(sldns_buffer_remaining(pkt) < 2+2+4+2) { + verbose(VERB_ALGO, "No TSIG, packet too short"); + return 0; + } + if(sldns_buffer_read_u16(pkt) != LDNS_RR_TYPE_TSIG) { + verbose(VERB_ALGO, "No TSIG, last RR not type TSIG"); + return 0; + } + + sldns_buffer_set_position(pkt, end_pos); + return 1; +} diff --git a/util/tsig.h b/util/tsig.h index 4776f728b..0808c0604 100644 --- a/util/tsig.h +++ b/util/tsig.h @@ -363,4 +363,12 @@ int tsig_verify_reply(struct tsig_data* tsig, struct sldns_buffer* pkt); */ size_t tsig_reserved_space(struct tsig_data* tsig); +/** + * See if the packet has a TSIG record, or not. + * @param pkt: the packet. + * @return false if malformed or no tsig. If found, the position is + * just before the TSIG record. So it can be parsed. + */ +int tsig_find_rr(struct sldns_buffer* pkt); + #endif /* UTIL_TSIG_H */