]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- xfr-tsig, tsig_find_rr function.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Tue, 24 Jun 2025 14:51:41 +0000 (16:51 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Tue, 24 Jun 2025 14:51:41 +0000 (16:51 +0200)
testcode/unittsig.c
testdata/tsig_test.1
util/tsig.c
util/tsig.h

index 9b4c0539339302d203af3bb4c7cfd7a11434b934..7fb090758aa918258f1e93bd440552cc91ee07d6 100644 (file)
@@ -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) {
index c636a8639c8aebd133cca39ad6f93840fb5789bd..ba40759230d6fdf76201df28a48333153eb672a3 100644 (file)
@@ -53,3 +53,5 @@ endpacket
 #packet
 #e7078400000100010000000203777777076578616d706c65036e65740000010001c00c0001000100000e1000040a141e2800002904d00000000000000474657374036b65790000fa00ff00000000003a08686d61632d6d6435077369672d616c670372656703696e740000006855490d012c0010dc3c138476fcb04cc138aa5c59647b86e70700000000
 #endpacket
+#
+#tsig-verify-query test.key 1750419725 0 0 0
index 41037fd2acda34945600f0c053391eab3b2bd4cd..e9d913f838e7044c620e0889ba709037b3a4fcd0 100644 (file)
@@ -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;
+}
index 4776f728b2eb94ccec6586c105ed178008fbf720..0808c06040ed30d5909e3071bcbe135d9856b301 100644 (file)
@@ -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 */