#define DNS_MESSAGERENDER_PARTIAL 0x0002 /*%< allow a partial rdataset */
#define DNS_MESSAGERENDER_OMITDNSSEC 0x0004 /*%< omit DNSSEC records */
#define DNS_MESSAGERENDER_PREFER_A 0x0008 /*%< prefer A records in
- additional section. */
+ additional section. */
#define DNS_MESSAGERENDER_PREFER_AAAA 0x0010 /*%< prefer AAAA records in
- additional section. */
+ additional section. */
/* Obsolete: DNS_MESSAGERENDER_FILTER_AAAA 0x0020 */
typedef struct dns_msgblock dns_msgblock_t;
unsigned int cc_bad : 1;
unsigned int tkey : 1;
unsigned int rdclass_set : 1;
+ unsigned int new_tsigkey : 1;
unsigned int opt_reserved;
unsigned int sig_reserved;
m->tkey = 0;
m->rdclass_set = 0;
m->querytsig = NULL;
+ m->new_tsigkey = 0;
}
static inline void
*/
REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(msg->state == DNS_SECTION_ANY);
+ REQUIRE(msg->state == DNS_SECTION_ANY || msg->new_tsigkey == 1);
if (key == NULL && msg->tsigkey != NULL) {
if (msg->sig_reserved != 0) {
tkey_log("process_gsstkey(): dns_tsigerror_noerror"); /* XXXSRA */
/*
- * [#821] WMM: So we found a TKEY to respond with. We don't know if
- * the request is TSIG signed, but if it is not we need to make an
- * effort so that the response is signed, as described in the except
- * case in RFC 2845 Section 2.2:
- *
- * The server MUST not generate a signed response to an unsigned
- * request, except in case of response to client's unsigned TKEY
- * query if secret key is established on server side after server
- * processed client's query. Signing responses to unsigned TKEY
- * queries MUST be explicitly specified in the description of an
- * individual secret key establishment algorithm.
- *
- * In dns_message_reply() it is checked whether to TSIG sign the
- * response by checking if msg->tsigkey is non-NULL. A first naive
- * attempt to set the tsigkey here with:
- *
- * RETERR(dns_message_settsigkey(msg, tsigkey));
- *
- * is not the right approach, but captures the idea of what needs
- * to be done: signal that the msg needs to be TSIG signed.
+ * We found a TKEY to respond with. We don't know if
+ * the request is TSIG signed, but if it is not we need to make
+ * sure the response is signed (RFC 2845 secton 2.2).
*/
+ if (tsigkey != NULL) {
+ /*
+ * First, we have to set the message to accept a new
+ * TSIG key; normally they can only be set during parsing.
+ */
+ msg->new_tsigkey = 1;
+ dns_message_settsigkey(msg, tsigkey);
+ }
+
return (ISC_R_SUCCESS);
failure:
* If this is a response, there should be a query tsig.
*/
response = is_response(msg);
- if (response && msg->querytsig == NULL)
+ if (response && (msg->querytsig == NULL && msg->new_tsigkey == 0)) {
return (DNS_R_EXPECTEDTSIG);
+ }
dynbuf = NULL;
isc_buffer_init(&databuf, data, sizeof(data));
- if (response)
+ if (response && msg->new_tsigkey == 0)
tsig.error = msg->querytsigstatus;
else
tsig.error = dns_rcode_noerror;
/*
* If this is a response, digest the request's MAC.
*/
- if (response) {
+ if (response && msg->new_tsigkey == 0) {
dns_rdata_t querytsigrdata = DNS_RDATA_INIT;
INSIST(msg->verified_sig);