resolve: add RFC4501 URI support to systemd-resolve-host
This commit is contained in:
parent
8e54f5d90a
commit
c1dafe4f31
|
@ -328,8 +328,7 @@ static int parse_address(const char *s, int *family, union in_addr_union *addres
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int resolve_record(sd_bus *bus, const char *name) {
|
||||
|
||||
static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_t type) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL, *reply = NULL;
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
char ifname[IF_NAMESIZE] = "";
|
||||
|
@ -343,7 +342,7 @@ static int resolve_record(sd_bus *bus, const char *name) {
|
|||
if (arg_ifindex > 0 && !if_indextoname(arg_ifindex, ifname))
|
||||
return log_error_errno(errno, "Failed to resolve interface name for index %i: %m", arg_ifindex);
|
||||
|
||||
log_debug("Resolving %s %s %s (interface %s).", name, dns_class_to_string(arg_class), dns_type_to_string(arg_type), isempty(ifname) ? "*" : ifname);
|
||||
log_debug("Resolving %s %s %s (interface %s).", name, dns_class_to_string(class), dns_type_to_string(type), isempty(ifname) ? "*" : ifname);
|
||||
|
||||
r = sd_bus_message_new_method_call(
|
||||
bus,
|
||||
|
@ -355,7 +354,7 @@ static int resolve_record(sd_bus *bus, const char *name) {
|
|||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_message_append(req, "isqqt", arg_ifindex, name, arg_class, arg_type, arg_flags);
|
||||
r = sd_bus_message_append(req, "isqqt", arg_ifindex, name, class, type, arg_flags);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
|
@ -442,6 +441,127 @@ static int resolve_record(sd_bus *bus, const char *name) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int resolve_rfc4501(sd_bus *bus, const char *name) {
|
||||
uint16_t type = 0, class = 0;
|
||||
const char *p, *q, *n;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(name);
|
||||
assert(startswith(name, "dns:"));
|
||||
|
||||
/* Parse RFC 4501 dns: URIs */
|
||||
|
||||
p = name + 4;
|
||||
|
||||
if (p[0] == '/') {
|
||||
const char *e;
|
||||
|
||||
if (p[1] != '/')
|
||||
goto invalid;
|
||||
|
||||
e = strchr(p + 2, '/');
|
||||
if (!e)
|
||||
goto invalid;
|
||||
|
||||
if (e != p + 2)
|
||||
log_warning("DNS authority specification not supported; ignoring specified authority.");
|
||||
|
||||
p = e + 1;
|
||||
}
|
||||
|
||||
q = strchr(p, '?');
|
||||
if (q) {
|
||||
n = strndupa(p, q - p);
|
||||
q++;
|
||||
|
||||
for (;;) {
|
||||
const char *f;
|
||||
|
||||
f = startswith_no_case(q, "class=");
|
||||
if (f) {
|
||||
_cleanup_free_ char *t = NULL;
|
||||
const char *e;
|
||||
|
||||
if (class != 0) {
|
||||
log_error("DNS class specified twice.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
e = strchrnul(f, ';');
|
||||
t = strndup(f, e - f);
|
||||
if (!t)
|
||||
return log_oom();
|
||||
|
||||
r = dns_class_from_string(t);
|
||||
if (r < 0) {
|
||||
log_error("Unknown DNS class %s.", t);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
class = r;
|
||||
|
||||
if (*e == ';') {
|
||||
q = e + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
f = startswith_no_case(q, "type=");
|
||||
if (f) {
|
||||
_cleanup_free_ char *t = NULL;
|
||||
const char *e;
|
||||
|
||||
if (type != 0) {
|
||||
log_error("DNS type specified twice.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
e = strchrnul(f, ';');
|
||||
t = strndup(f, e - f);
|
||||
if (!t)
|
||||
return log_oom();
|
||||
|
||||
r = dns_type_from_string(t);
|
||||
if (r < 0) {
|
||||
log_error("Unknown DNS type %s.", t);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
type = r;
|
||||
|
||||
if (*e == ';') {
|
||||
q = e + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
goto invalid;
|
||||
}
|
||||
} else
|
||||
n = p;
|
||||
|
||||
if (type == 0)
|
||||
type = arg_type;
|
||||
if (type == 0)
|
||||
type = DNS_TYPE_A;
|
||||
|
||||
if (class == 0)
|
||||
class = arg_class;
|
||||
if (class == 0)
|
||||
class = DNS_CLASS_IN;
|
||||
|
||||
return resolve_record(bus, n, class, type);
|
||||
|
||||
invalid:
|
||||
log_error("Invalid DNS URI: %s", name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int resolve_service(sd_bus *bus, const char *name, const char *type, const char *domain) {
|
||||
const char *canonical_name, *canonical_type, *canonical_domain;
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL, *reply = NULL;
|
||||
|
@ -1009,6 +1129,9 @@ static int parse_argv(int argc, char *argv[]) {
|
|||
if (arg_type != 0 && arg_class == 0)
|
||||
arg_class = DNS_CLASS_IN;
|
||||
|
||||
if (arg_class != 0 && arg_type == 0)
|
||||
arg_type = DNS_TYPE_A;
|
||||
|
||||
return 1 /* work to do */;
|
||||
}
|
||||
|
||||
|
@ -1042,11 +1165,15 @@ int main(int argc, char **argv) {
|
|||
int family, ifindex, k;
|
||||
union in_addr_union a;
|
||||
|
||||
k = parse_address(argv[optind], &family, &a, &ifindex);
|
||||
if (k >= 0)
|
||||
k = resolve_address(bus, family, &a, ifindex);
|
||||
else
|
||||
k = resolve_host(bus, argv[optind]);
|
||||
if (startswith(argv[optind], "dns:"))
|
||||
k = resolve_rfc4501(bus, argv[optind]);
|
||||
else {
|
||||
k = parse_address(argv[optind], &family, &a, &ifindex);
|
||||
if (k >= 0)
|
||||
k = resolve_address(bus, family, &a, ifindex);
|
||||
else
|
||||
k = resolve_host(bus, argv[optind]);
|
||||
}
|
||||
|
||||
if (r == 0)
|
||||
r = k;
|
||||
|
@ -1065,7 +1192,7 @@ int main(int argc, char **argv) {
|
|||
while (argv[optind]) {
|
||||
int k;
|
||||
|
||||
k = resolve_record(bus, argv[optind]);
|
||||
k = resolve_record(bus, argv[optind], arg_class, arg_type);
|
||||
if (r == 0)
|
||||
r = k;
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ Y https://tools.ietf.org/html/rfc3597 → Handling of Unknown DNS Resource Recor
|
|||
Y https://tools.ietf.org/html/rfc4255 → Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints
|
||||
Y https://tools.ietf.org/html/rfc4343 → Domain Name System (DNS) Case Insensitivity Clarification
|
||||
~ https://tools.ietf.org/html/rfc4470 → Minimally Covering NSEC Records and DNSSEC On-line Signing
|
||||
https://tools.ietf.org/html/rfc4501 → Domain Name System Uniform Resource Identifiers
|
||||
Y https://tools.ietf.org/html/rfc4501 → Domain Name System Uniform Resource Identifiers
|
||||
Y https://tools.ietf.org/html/rfc4509 → Use of SHA-256 in DNSSEC Delegation Signer (DS) Resource Records (RRs)
|
||||
~ https://tools.ietf.org/html/rfc4592 → The Role of Wildcards in the Domain Name System
|
||||
~ https://tools.ietf.org/html/rfc4697 → Observed DNS Resolution Misbehavior
|
||||
|
|
Loading…
Reference in a new issue