systemd-resolve: allow keys to be dumped in binary form

$ systemd-resolve --raw --openpgp zbyszek@fedoraproject.org | pgpdump /dev/stdin
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2016-02-16 19:24:07 -05:00
parent 1ace2438c6
commit 2e74028a5c
3 changed files with 73 additions and 7 deletions
+33 -7
View File
@@ -43,6 +43,7 @@ static uint16_t arg_type = 0;
static uint16_t arg_class = 0;
static bool arg_legend = true;
static uint64_t arg_flags = 0;
static bool arg_raw = false;
static enum {
MODE_RESOLVE_HOST,
@@ -379,7 +380,6 @@ static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_
while ((r = sd_bus_message_enter_container(reply, 'r', "iqqay")) > 0) {
_cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
_cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
const char *s;
uint16_t c, t;
int ifindex;
const void *d;
@@ -413,13 +413,27 @@ static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_
if (r < 0)
return log_error_errno(r, "Failed to parse RR: %m");
s = dns_resource_record_to_string(rr);
if (!s)
return log_oom();
if (arg_raw) {
void *data;
ssize_t k;
ifname[0] = 0;
if (ifindex > 0 && !if_indextoname(ifindex, ifname))
log_warning_errno(errno, "Failed to resolve interface name for index %i: %m", ifindex);
k = dns_resource_record_payload(rr, &data);
if (k < 0)
return log_error_errno(k, "Cannot dump RR: %m");
fwrite(data, 1, k, stdout);
} else {
const char *s;
s = dns_resource_record_to_string(rr);
if (!s)
return log_oom();
ifname[0] = 0;
if (ifindex > 0 && !if_indextoname(ifindex, ifname))
log_warning_errno(errno, "Failed to resolve interface name for index %i: %m", ifindex);
printf("%s%s%s\n", s, isempty(ifname) ? "" : " # interface ", ifname);
}
printf("%s%s%s\n", s, isempty(ifname) ? "" : " # interface ", ifname);
@@ -1013,6 +1027,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_SERVICE_ADDRESS,
ARG_SERVICE_TXT,
ARG_OPENPGP,
ARG_RAW,
ARG_SEARCH,
ARG_STATISTICS,
ARG_RESET_STATISTICS,
@@ -1031,6 +1046,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "service-address", required_argument, NULL, ARG_SERVICE_ADDRESS },
{ "service-txt", required_argument, NULL, ARG_SERVICE_TXT },
{ "openpgp", no_argument, NULL, ARG_OPENPGP },
{ "raw", no_argument, NULL, ARG_RAW },
{ "search", required_argument, NULL, ARG_SEARCH },
{ "statistics", no_argument, NULL, ARG_STATISTICS, },
{ "reset-statistics", no_argument, NULL, ARG_RESET_STATISTICS },
@@ -1144,6 +1160,16 @@ static int parse_argv(int argc, char *argv[]) {
arg_mode = MODE_RESOLVE_OPENPGP;
break;
case ARG_RAW:
if (on_tty()) {
log_error("Refusing to write binary data to tty.");
return -ENOTTY;
}
arg_raw = true;
arg_legend = false;
break;
case ARG_CNAME:
r = parse_boolean(optarg);
if (r < 0)
+38
View File
@@ -1204,6 +1204,44 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
return s;
}
ssize_t dns_resource_record_payload(DnsResourceRecord *rr, void **out) {
assert(rr);
assert(out);
switch(rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
case DNS_TYPE_SRV:
case DNS_TYPE_PTR:
case DNS_TYPE_NS:
case DNS_TYPE_CNAME:
case DNS_TYPE_DNAME:
case DNS_TYPE_HINFO:
case DNS_TYPE_SPF:
case DNS_TYPE_TXT:
case DNS_TYPE_A:
case DNS_TYPE_AAAA:
case DNS_TYPE_SOA:
case DNS_TYPE_MX:
case DNS_TYPE_LOC:
case DNS_TYPE_DS:
case DNS_TYPE_SSHFP:
case DNS_TYPE_DNSKEY:
case DNS_TYPE_RRSIG:
case DNS_TYPE_NSEC:
case DNS_TYPE_NSEC3:
return -EINVAL;
case DNS_TYPE_TLSA:
*out = rr->tlsa.data;
return rr->tlsa.data_size;
case DNS_TYPE_OPENPGPKEY:
default:
*out = rr->generic.data;
return rr->generic.data_size;
}
}
int dns_resource_record_to_wire_format(DnsResourceRecord *rr, bool canonical) {
DnsPacket packet = {
+2
View File
@@ -303,6 +303,8 @@ int dns_resource_key_match_rr(const DnsResourceKey *key, DnsResourceRecord *rr,
int dns_resource_key_match_cname_or_dname(const DnsResourceKey *key, const DnsResourceKey *cname, const char *search_domain);
int dns_resource_key_match_soa(const DnsResourceKey *key, const DnsResourceKey *soa);
int dns_resource_key_to_string(const DnsResourceKey *key, char **ret);
ssize_t dns_resource_record_payload(DnsResourceRecord *rr, void **out);
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceKey*, dns_resource_key_unref);
static inline bool dns_key_is_shared(const DnsResourceKey *key) {