From 61ecb465b1c803316cb55bae0c2d7cf3c0008589 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 15 Feb 2016 18:40:02 +0100
Subject: resolved: turn on DNSSEC by default, unless configured otherwise

Let's make sure DNSSEC gets more testing, by defaulting DNSSEC to
"allow-downgrade" mode. Since distros should probably not ship DNSSEC enabled
by default add a configure switch to disable this again.

DNSSEC in "allow-downgrade" mode should mostly work without affecting user
experience. There's one exception: some captive portal systems rewrite DNS in
order to redirect HTTP traffic to the captive portal. If these systems
implement DNS servers that are otherwise DNSSEC-capable (which in fact is
pretty unlikely, but still...), then this will result in the captive portal
being inaccessible. To fix this support in NetworkManager (or any other network
management solution that does captive portal detection) is required, which
simply turns off DNSSEC during the captive portal detection, and resets it back
to the default (i.e. on) after captive portal authentication is complete.
---
 src/resolve/resolved-manager.c | 2 +-
 src/resolve/resolved.conf.in   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'src')

diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
index bf5efe4cfa..09e15fa230 100644
--- a/src/resolve/resolved-manager.c
+++ b/src/resolve/resolved-manager.c
@@ -485,7 +485,7 @@ int manager_new(Manager **ret) {
 
         m->llmnr_support = RESOLVE_SUPPORT_YES;
         m->mdns_support = RESOLVE_SUPPORT_NO;
-        m->dnssec_mode = DNSSEC_NO;
+        m->dnssec_mode = DEFAULT_DNSSEC_MODE;
         m->read_resolv_conf = true;
         m->need_builtin_fallbacks = true;
         m->etc_hosts_last = m->etc_hosts_mtime = USEC_INFINITY;
diff --git a/src/resolve/resolved.conf.in b/src/resolve/resolved.conf.in
index efc9c6733a..a288588924 100644
--- a/src/resolve/resolved.conf.in
+++ b/src/resolve/resolved.conf.in
@@ -16,4 +16,4 @@
 #FallbackDNS=@DNS_SERVERS@
 #Domains=
 #LLMNR=yes
-#DNSSEC=no
+#DNSSEC=@DEFAULT_DNSSEC_MODE@
-- 
cgit v1.2.3-54-g00ecf


From de085700502b372767fa4c83b91a02522e198897 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 15 Feb 2016 19:06:01 +0100
Subject: build-sys: fix type detection

Before this patch existence of char16_t, char32_t, key_serial_t was checked
with AC_CHECK_DECLS() which doesn't actually work for types. Correct this to
use AC_CHECK_TYPES() instead.

Also, while we are at it, change the check for memfd_create() to use
AC_CHECK_DECLS() instead of AC_CHECK_FUNCS(). This is a better choice, since a
couple of syscalls are defined by glibc but not exported in the header files
(pivot_root() for example), and we hence should probably be more picky with
memfd_create() too, which glibc might decide to expose one day, but not
necessarily in the headers too.
---
 configure.ac        | 9 ++++++---
 src/basic/missing.h | 8 ++++----
 2 files changed, 10 insertions(+), 7 deletions(-)

(limited to 'src')

diff --git a/configure.ac b/configure.ac
index e72470a199..614f0553b8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -295,10 +295,8 @@ CAP_LIBS="$LIBS"
 LIBS="$save_LIBS"
 AC_SUBST(CAP_LIBS)
 
-AC_CHECK_FUNCS([memfd_create])
 AC_CHECK_FUNCS([__secure_getenv secure_getenv])
-AC_CHECK_DECLS([gettid, pivot_root, name_to_handle_at, setns, getrandom, renameat2,
-                kcmp, keyctl, key_serial_t, char16_t, char32_t, LO_FLAGS_PARTSCAN],
+AC_CHECK_DECLS([memfd_create, gettid, pivot_root, name_to_handle_at, setns, getrandom, renameat2, kcmp, keyctl, LO_FLAGS_PARTSCAN],
                [], [], [[
 #include <sys/types.h>
 #include <unistd.h>
@@ -309,6 +307,11 @@ AC_CHECK_DECLS([gettid, pivot_root, name_to_handle_at, setns, getrandom, renamea
 #include <linux/random.h>
 ]])
 
+AC_CHECK_TYPES([char16_t, char32_t, key_serial_t],
+               [], [], [[
+#include <uchar.h>
+]])
+
 AC_CHECK_DECLS([IFLA_INET6_ADDR_GEN_MODE,
                 IFLA_MACVLAN_FLAGS,
                 IFLA_IPVLAN_MODE,
diff --git a/src/basic/missing.h b/src/basic/missing.h
index 4d3764c022..f3d32362bd 100644
--- a/src/basic/missing.h
+++ b/src/basic/missing.h
@@ -167,7 +167,7 @@ static inline int pivot_root(const char *new_root, const char *put_old) {
 #  endif
 #endif
 
-#ifndef HAVE_MEMFD_CREATE
+#if !HAVE_DECL_MEMFD_CREATE
 static inline int memfd_create(const char *name, unsigned int flags) {
         return syscall(__NR_memfd_create, name, flags);
 }
@@ -1089,7 +1089,7 @@ static inline int kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, uns
 #define INPUT_PROP_ACCELEROMETER  0x06
 #endif
 
-#if !HAVE_DECL_KEY_SERIAL_T
+#ifndef HAVE_KEY_SERIAL_T
 typedef int32_t key_serial_t;
 #endif
 
@@ -1160,11 +1160,11 @@ static inline key_serial_t request_key(const char *type, const char *description
 #ifndef IF_OPER_UP
 #define IF_OPER_UP 6
 
-#ifndef HAVE_DECL_CHAR32_T
+#ifndef HAVE_CHAR32_T
 #define char32_t uint32_t
 #endif
 
-#ifndef HAVE_DECL_CHAR16_T
+#ifndef HAVE_CHAR16_T
 #define char16_t uint16_t
 #endif
 
-- 
cgit v1.2.3-54-g00ecf


From 9dc907f9c93636cb63ca90300fa3b8c03812701f Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 15 Feb 2016 19:11:18 +0100
Subject: networkd: rework idle detection logic of networkd

This patch makes networkd stay around as long as there is more than just a
loopback interface around, or the loopback device isn't fully probed yet, or
the loopback device has a .network file attached.

In essence, this means networkd stays around now continously as it should,
unless it is running in some (container?) environment that really has no
interface except a loopback device.

Fixes #2577.
---
 src/network/networkd-manager.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

(limited to 'src')

diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index b527191a5a..b8cb7f875d 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -1091,22 +1091,19 @@ static bool manager_check_idle(void *userdata) {
 
         assert(m);
 
+        /* Check whether we are idle now. The only case when we decide to be idle is when there's only a loopback
+         * device around, for which we have no configuration, and which already left the PENDING state. In all other
+         * cases we are not idle. */
+
         HASHMAP_FOREACH(link, m->links, i) {
-                /* we are not woken on udev activity, so let's just wait for the
-                 * pending udev event */
+                /* We are not woken on udev activity, so let's just wait for the pending udev event */
                 if (link->state == LINK_STATE_PENDING)
                         return false;
 
-                if (!link->network)
-                        continue;
+                if ((link->flags & IFF_LOOPBACK) == 0)
+                        return false;
 
-                /* we are not woken on netork activity, so let's stay around */
-                if (link_lldp_enabled(link) ||
-                    link_ipv4ll_enabled(link) ||
-                    link_dhcp4_server_enabled(link) ||
-                    link_dhcp4_enabled(link) ||
-                    link_dhcp6_enabled(link) ||
-                    link_ipv6_accept_ra_enabled(link))
+                if (link->network)
                         return false;
         }
 
-- 
cgit v1.2.3-54-g00ecf


From 41815a4aa66c59070dc86aa99eebfa720e8a263e Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 15 Feb 2016 21:25:33 +0100
Subject: resolve: print a noisy warning if we show crypto keys that could not
 be authenticated

Doing DNS retrieval on non-authenticated crypt keys is useless, hence warn
loudly about it.
---
 src/resolve/dns-type.c     | 17 +++++++++++++++++
 src/resolve/dns-type.h     |  1 +
 src/resolve/resolve-tool.c | 17 +++++++++++++++++
 3 files changed, 35 insertions(+)

(limited to 'src')

diff --git a/src/resolve/dns-type.c b/src/resolve/dns-type.c
index b2f479cae5..78d9d5733f 100644
--- a/src/resolve/dns-type.c
+++ b/src/resolve/dns-type.c
@@ -193,6 +193,23 @@ bool dns_type_is_obsolete(uint16_t type) {
                       DNS_TYPE_NULL);
 }
 
+bool dns_type_needs_authentication(uint16_t type) {
+
+        /* Returns true for all (non-obsolete) RR types where records are not useful if they aren't
+         * authenticated. I.e. everything that contains crypto keys. */
+
+        return IN_SET(type,
+                      DNS_TYPE_CERT,
+                      DNS_TYPE_SSHFP,
+                      DNS_TYPE_IPSECKEY,
+                      DNS_TYPE_DS,
+                      DNS_TYPE_DNSKEY,
+                      DNS_TYPE_TLSA,
+                      DNS_TYPE_CDNSKEY,
+                      DNS_TYPE_OPENPGPKEY,
+                      DNS_TYPE_CAA);
+}
+
 int dns_type_to_af(uint16_t t) {
         switch (t) {
 
diff --git a/src/resolve/dns-type.h b/src/resolve/dns-type.h
index f18ac6eef3..fb7babf12a 100644
--- a/src/resolve/dns-type.h
+++ b/src/resolve/dns-type.h
@@ -132,6 +132,7 @@ bool dns_type_is_dnssec(uint16_t type);
 bool dns_type_is_obsolete(uint16_t type);
 bool dns_type_may_wildcard(uint16_t type);
 bool dns_type_apex_only(uint16_t type);
+bool dns_type_needs_authentication(uint16_t type);
 int dns_type_to_af(uint16_t t);
 
 bool dns_class_is_pseudo(uint16_t class);
diff --git a/src/resolve/resolve-tool.c b/src/resolve/resolve-tool.c
index 9aade8e490..c1be03fbb2 100644
--- a/src/resolve/resolve-tool.c
+++ b/src/resolve/resolve-tool.c
@@ -339,6 +339,7 @@ static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_
         uint64_t flags;
         int r;
         usec_t ts;
+        bool needs_authentication = false;
 
         assert(name);
 
@@ -421,6 +422,10 @@ static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_
                         log_warning_errno(errno, "Failed to resolve interface name for index %i: %m", ifindex);
 
                 printf("%s%s%s\n", s, isempty(ifname) ? "" : " # interface ", ifname);
+
+                if (dns_type_needs_authentication(t))
+                        needs_authentication = true;
+
                 n++;
         }
         if (r < 0)
@@ -441,6 +446,18 @@ static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_
 
         print_source(flags, ts);
 
+        if ((flags & SD_RESOLVED_AUTHENTICATED) == 0 && needs_authentication) {
+                fflush(stdout);
+
+                fprintf(stderr, "\n%s"
+                       "WARNING: The resources shown contain cryptographic key data which could not be\n"
+                       "         authenticated. It is not suitable to authenticate any communication.\n"
+                       "         This is usually indication that DNSSEC authentication was not enabled\n"
+                       "         or is not available for the selected protocol or DNS servers.%s\n",
+                       ansi_highlight_red(),
+                       ansi_normal());
+        }
+
         return 0;
 }
 
-- 
cgit v1.2.3-54-g00ecf


From 3f51aec8647fe13f4b1e46b2f75ff635403adf91 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 16 Feb 2016 13:18:36 +0100
Subject: core: fix assertion check

Fixes: #2632
---
 src/core/timer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src')

diff --git a/src/core/timer.c b/src/core/timer.c
index 6f3e6a8db3..3d0bae16e5 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -334,7 +334,7 @@ static void add_random(Timer *t, usec_t *v) {
         usec_t add;
 
         assert(t);
-        assert(*v);
+        assert(v);
 
         if (t->random_usec == 0)
                 return;
-- 
cgit v1.2.3-54-g00ecf


From 6d2353394fc33e923d1ab464c8f88df2a5105ffb Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 16 Feb 2016 14:03:47 +0100
Subject: udev: fix cg_unified() return code checking

Fixes fall-out from 8b3aa503c171acdb9ec63484a8c50e2680d31e79.

Fixes: #2635
---
 src/udev/udevd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src')

diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 2c1c4a967b..bb92f16352 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -1715,7 +1715,7 @@ int main(int argc, char *argv[]) {
                    by PID1. otherwise we are not guaranteed to have a dedicated cgroup */
                 r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &cgroup);
                 if (r < 0) {
-                        if (r == -ENOENT || r == -ENOEXEC)
+                        if (r == -ENOENT || r == -ENOMEDIUM)
                                 log_debug_errno(r, "did not find dedicated cgroup: %m");
                         else
                                 log_warning_errno(r, "failed to get cgroup: %m");
-- 
cgit v1.2.3-54-g00ecf


From c77d26122a35a8555953bbe71e4a4ff664f3462c Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 16 Feb 2016 14:17:53 +0100
Subject: resolved: make sure to normalize all domain names returned via the
 bus

Most domain names we deal with are normalized anyway (since we read them that
way from DNS packets), but some might not (because they are synthesized from
unnormalized configuration or so), hence make sure to normalize all names
before passing them out to clients, to be fully deterministic.

Note that internally we are process normalized and non-normalized names the
same way, and while comparing them ignore the differences due to unnormalized
names. However, that internal implementation detail really shouldn't spill out
the clients, hence make sure to clean it all up.
---
 src/resolve/resolved-bus.c | 34 ++++++++++++++++++++++++++++++----
 1 file changed, 30 insertions(+), 4 deletions(-)

(limited to 'src')

diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
index 6f08c43327..2d94baeb7e 100644
--- a/src/resolve/resolved-bus.c
+++ b/src/resolve/resolved-bus.c
@@ -140,6 +140,7 @@ static int append_address(sd_bus_message *reply, DnsResourceRecord *rr, int ifin
 static void bus_method_resolve_hostname_complete(DnsQuery *q) {
         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+        _cleanup_free_ char *normalized = NULL;
         DnsResourceRecord *rr;
         unsigned added = 0;
         int ifindex, r;
@@ -199,11 +200,17 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) {
         if (r < 0)
                 goto finish;
 
+        /* The key names are not necessarily normalized, make sure that they are when we return them to our bus
+         * clients. */
+        r = dns_name_normalize(DNS_RESOURCE_KEY_NAME(canonical->key), &normalized);
+        if (r < 0)
+                goto finish;
+
         /* Return the precise spelling and uppercasing and CNAME target reported by the server */
         assert(canonical);
         r = sd_bus_message_append(
                         reply, "st",
-                        DNS_RESOURCE_KEY_NAME(canonical->key),
+                        normalized,
                         SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, q->answer_authenticated));
         if (r < 0)
                 goto finish;
@@ -395,13 +402,19 @@ static void bus_method_resolve_address_complete(DnsQuery *q) {
         question = dns_query_question_for_protocol(q, q->answer_protocol);
 
         DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
+                _cleanup_free_ char *normalized = NULL;
+
                 r = dns_question_matches_rr(question, rr, NULL);
                 if (r < 0)
                         goto finish;
                 if (r == 0)
                         continue;
 
-                r = sd_bus_message_append(reply, "(is)", ifindex, rr->ptr.name);
+                r = dns_name_normalize(rr->ptr.name, &normalized);
+                if (r < 0)
+                        goto finish;
+
+                r = sd_bus_message_append(reply, "(is)", ifindex, normalized);
                 if (r < 0)
                         goto finish;
 
@@ -671,6 +684,7 @@ fail:
 
 static int append_srv(DnsQuery *q, sd_bus_message *reply, DnsResourceRecord *rr) {
         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
+        _cleanup_free_ char *normalized = NULL;
         DnsQuery *aux;
         int r;
 
@@ -727,10 +741,14 @@ static int append_srv(DnsQuery *q, sd_bus_message *reply, DnsResourceRecord *rr)
         if (r < 0)
                 return r;
 
+        r = dns_name_normalize(rr->srv.name, &normalized);
+        if (r < 0)
+                return r;
+
         r = sd_bus_message_append(
                         reply,
                         "qqqs",
-                        rr->srv.priority, rr->srv.weight, rr->srv.port, rr->srv.name);
+                        rr->srv.priority, rr->srv.weight, rr->srv.port, normalized);
         if (r < 0)
                 return r;
 
@@ -776,9 +794,17 @@ static int append_srv(DnsQuery *q, sd_bus_message *reply, DnsResourceRecord *rr)
         if (r < 0)
                 return r;
 
+        if (canonical) {
+                normalized = mfree(normalized);
+
+                r = dns_name_normalize(DNS_RESOURCE_KEY_NAME(canonical->key), &normalized);
+                if (r < 0)
+                        return r;
+        }
+
         /* Note that above we appended the hostname as encoded in the
          * SRV, and here the canonical hostname this maps to. */
-        r = sd_bus_message_append(reply, "s", canonical ? DNS_RESOURCE_KEY_NAME(canonical->key) : rr->srv.name);
+        r = sd_bus_message_append(reply, "s", normalized);
         if (r < 0)
                 return r;
 
-- 
cgit v1.2.3-54-g00ecf