resolve: introduce DNSSEC_UPSTREAM_FAILURE

and include EDE code and message in the error messages.

This replaces 9ca133e97a, and implements
originally suggested at
https://github.com/systemd/systemd/pull/30513#discussion_r1433823737
This commit is contained in:
Yu Watanabe
2024-01-10 11:34:44 +09:00
parent 0c61995d80
commit a72cf22d06
6 changed files with 50 additions and 10 deletions

View File

@@ -145,8 +145,13 @@ static int reply_query_state(DnsQuery *q) {
return reply_method_errorf(q, BUS_ERROR_ABORTED, "Query aborted");
case DNS_TRANSACTION_DNSSEC_FAILED:
return reply_method_errorf(q, BUS_ERROR_DNSSEC_FAILED, "DNSSEC validation failed: %s",
dnssec_result_to_string(q->answer_dnssec_result));
return reply_method_errorf(q, BUS_ERROR_DNSSEC_FAILED, "DNSSEC validation failed: %s%s%s%s%s%s",
dnssec_result_to_string(q->answer_dnssec_result),
q->answer_ede_rcode >= 0 ? " (" : "",
q->answer_ede_rcode >= 0 ? FORMAT_DNS_EDE_RCODE(q->answer_ede_rcode) : "",
(q->answer_ede_rcode >= 0 && !isempty(q->answer_ede_msg)) ? ": " : "",
q->answer_ede_rcode >= 0 ? strempty(q->answer_ede_msg) : "",
q->answer_ede_rcode >= 0 ? ")" : "");
case DNS_TRANSACTION_NO_TRUST_ANCHOR:
return reply_method_errorf(q, BUS_ERROR_NO_TRUST_ANCHOR, "No suitable trust anchor known");
@@ -183,7 +188,13 @@ static int reply_query_state(DnsQuery *q) {
rc = FORMAT_DNS_RCODE(q->answer_rcode);
n = strjoina(_BUS_ERROR_DNS, rc);
sd_bus_error_setf(&error, n, "Could not resolve '%s', server or network returned error %s", dns_query_string(q), rc);
sd_bus_error_setf(&error, n, "Could not resolve '%s', server or network returned error: %s%s%s%s%s%s",
dns_query_string(q), rc,
q->answer_ede_rcode >= 0 ? " (" : "",
q->answer_ede_rcode >= 0 ? FORMAT_DNS_EDE_RCODE(q->answer_ede_rcode) : "",
(q->answer_ede_rcode >= 0 && !isempty(q->answer_ede_msg)) ? ": " : "",
q->answer_ede_rcode >= 0 ? strempty(q->answer_ede_msg) : "",
q->answer_ede_rcode >= 0 ? ")" : "");
}
return sd_bus_reply_method_error(req, &error);

View File

@@ -2564,6 +2564,7 @@ static const char* const dnssec_result_table[_DNSSEC_RESULT_MAX] = {
[DNSSEC_FAILED_AUXILIARY] = "failed-auxiliary",
[DNSSEC_NSEC_MISMATCH] = "nsec-mismatch",
[DNSSEC_INCOMPATIBLE_SERVER] = "incompatible-server",
[DNSSEC_UPSTREAM_FAILURE] = "upstream-failure",
};
DEFINE_STRING_TABLE_LOOKUP(dnssec_result, DnssecResult);

View File

@@ -20,11 +20,12 @@ enum DnssecResult {
DNSSEC_NO_SIGNATURE,
DNSSEC_MISSING_KEY,
/* These two are added by the DnsTransaction logic */
/* These five are added by the DnsTransaction logic */
DNSSEC_UNSIGNED,
DNSSEC_FAILED_AUXILIARY,
DNSSEC_NSEC_MISMATCH,
DNSSEC_INCOMPATIBLE_SERVER,
DNSSEC_UPSTREAM_FAILURE,
_DNSSEC_RESULT_MAX,
_DNSSEC_RESULT_INVALID = -EINVAL,

View File

@@ -888,8 +888,21 @@ static int dns_transaction_dnssec_ready(DnsTransaction *t) {
/* We handle DNSSEC failures different from other errors, as we care about the DNSSEC
* validation result */
log_debug("Auxiliary DNSSEC RR query failed validation: %s", dnssec_result_to_string(dt->answer_dnssec_result));
t->answer_dnssec_result = dt->answer_dnssec_result; /* Copy error code over */
log_debug("Auxiliary DNSSEC RR query failed validation: %s%s%s%s%s%s",
dnssec_result_to_string(dt->answer_dnssec_result),
dt->answer_ede_rcode >= 0 ? " (" : "",
dt->answer_ede_rcode >= 0 ? FORMAT_DNS_EDE_RCODE(dt->answer_ede_rcode) : "",
(dt->answer_ede_rcode >= 0 && !isempty(dt->answer_ede_msg)) ? ": " : "",
dt->answer_ede_rcode >= 0 ? strempty(dt->answer_ede_msg) : "",
dt->answer_ede_rcode >= 0 ? ")" : "");
/* Copy error code over */
t->answer_dnssec_result = dt->answer_dnssec_result;
t->answer_ede_rcode = dt->answer_ede_rcode;
r = free_and_strdup(&t->answer_ede_msg, dt->answer_ede_msg);
if (r < 0)
log_oom_debug();
dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
return 0;
@@ -1226,6 +1239,8 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p, bool encrypt
FORMAT_DNS_EDE_RCODE(t->answer_ede_rcode),
isempty(t->answer_ede_msg) ? "" : ": ",
strempty(t->answer_ede_msg));
t->answer_dnssec_result = DNSSEC_UPSTREAM_FAILURE;
dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
return;
}

View File

@@ -49,7 +49,11 @@ static int reply_query_state(DnsQuery *q) {
case DNS_TRANSACTION_DNSSEC_FAILED:
return varlink_errorb(q->varlink_request, "io.systemd.Resolve.DNSSECValidationFailed",
JSON_BUILD_OBJECT(JSON_BUILD_PAIR("result", JSON_BUILD_STRING(dnssec_result_to_string(q->answer_dnssec_result)))));
JSON_BUILD_OBJECT(JSON_BUILD_PAIR("result", JSON_BUILD_STRING(dnssec_result_to_string(q->answer_dnssec_result))),
JSON_BUILD_PAIR_CONDITION(q->answer_ede_rcode >= 0,
"extendedDNSErrorCode", JSON_BUILD_INTEGER(q->answer_ede_rcode)),
JSON_BUILD_PAIR_CONDITION(q->answer_ede_rcode >= 0 && !isempty(q->answer_ede_msg),
"extendedDNSErrorMessage", JSON_BUILD_STRING(q->answer_ede_msg))));
case DNS_TRANSACTION_NO_TRUST_ANCHOR:
return varlink_error(q->varlink_request, "io.systemd.Resolve.NoTrustAnchor", NULL);
@@ -74,7 +78,11 @@ static int reply_query_state(DnsQuery *q) {
case DNS_TRANSACTION_RCODE_FAILURE:
return varlink_errorb(q->varlink_request, "io.systemd.Resolve.DNSError",
JSON_BUILD_OBJECT(JSON_BUILD_PAIR("rcode", JSON_BUILD_INTEGER(q->answer_rcode))));
JSON_BUILD_OBJECT(JSON_BUILD_PAIR("rcode", JSON_BUILD_INTEGER(q->answer_rcode)),
JSON_BUILD_PAIR_CONDITION(q->answer_ede_rcode >= 0,
"extendedDNSErrorCode", JSON_BUILD_INTEGER(q->answer_ede_rcode)),
JSON_BUILD_PAIR_CONDITION(q->answer_ede_rcode >= 0 && !isempty(q->answer_ede_msg),
"extendedDNSErrorMessage", JSON_BUILD_STRING(q->answer_ede_msg))));
case DNS_TRANSACTION_NULL:
case DNS_TRANSACTION_PENDING:

View File

@@ -40,7 +40,9 @@ static VARLINK_DEFINE_ERROR(InvalidReply);
static VARLINK_DEFINE_ERROR(QueryAborted);
static VARLINK_DEFINE_ERROR(
DNSSECValidationFailed,
VARLINK_DEFINE_FIELD(result, VARLINK_STRING, 0));
VARLINK_DEFINE_FIELD(result, VARLINK_STRING, 0),
VARLINK_DEFINE_FIELD(extendedDNSErrorCode, VARLINK_INT, VARLINK_NULLABLE),
VARLINK_DEFINE_FIELD(extendedDNSErrorMessage, VARLINK_STRING, VARLINK_NULLABLE));
static VARLINK_DEFINE_ERROR(NoTrustAnchor);
static VARLINK_DEFINE_ERROR(ResourceRecordTypeUnsupported);
static VARLINK_DEFINE_ERROR(NetworkDown);
@@ -48,7 +50,9 @@ static VARLINK_DEFINE_ERROR(NoSource);
static VARLINK_DEFINE_ERROR(StubLoop);
static VARLINK_DEFINE_ERROR(
DNSError,
VARLINK_DEFINE_FIELD(rcode, VARLINK_INT, 0));
VARLINK_DEFINE_FIELD(rcode, VARLINK_INT, 0),
VARLINK_DEFINE_FIELD(extendedDNSErrorCode, VARLINK_INT, VARLINK_NULLABLE),
VARLINK_DEFINE_FIELD(extendedDNSErrorMessage, VARLINK_STRING, VARLINK_NULLABLE));
static VARLINK_DEFINE_ERROR(CNAMELoop);
static VARLINK_DEFINE_ERROR(BadAddressSize);