]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
systemd-resolve: allow keys to be dumped in binary form
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 28 Jan 2016 23:24:28 +0000 (18:24 -0500)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 17 Feb 2016 00:24:07 +0000 (19:24 -0500)
$ systemd-resolve --raw --openpgp zbyszek@fedoraproject.org | pgpdump /dev/stdin

src/resolve/resolve-tool.c
src/resolve/resolved-dns-rr.c
src/resolve/resolved-dns-rr.h

index ed9b0353cc9543e434ad547cdbfe8e7f4f5e7727..a24bb546d4fef11ae7bf15a0eac45db02a10866a 100644 (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)
index 6397005a684e3930e620b1a3fd759b14a4b64f9b..919a0d3c2c726d683f8a61c27fd3a35c5f77fa0d 100644 (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 = {
index 23749790b4b0995b06311b78711d8a85ff840ceb..964bf7e77a0e047b24a7db3ff5855434b556dd15 100644 (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) {