]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: make reading PrivateKeyFile= failure always fatal
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 5 Apr 2019 08:28:46 +0000 (17:28 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 9 Apr 2019 06:50:22 +0000 (15:50 +0900)
This also refactor wireguard_read_key_file().

man/systemd.netdev.xml
src/network/netdev/wireguard.c
test/test-network/conf/25-wireguard.netdev

index a44018cad6d6cb2104375883d72036a69331c5a4..10397402a4629af0e896db4d699bb9e86072c738 100644 (file)
         <term><varname>PrivateKeyFile=</varname></term>
         <listitem>
           <para>Takes a absolute path to a file which contains the Base64 encoded private key for the interface.
-          If both <varname>PrivateKey=</varname> and <varname>PrivateKeyFile=</varname> are specified, and if
-          the file specified in <varname>PrivateKeyFile=</varname> contains valid wireguard key, then
-          the key provided by <varname>PrivateKey=</varname> is ignored.
+          When this option is specified, then <varname>PrivateKey=</varname> is ignored.
           Note that the file must be readable by the user <literal>systemd-network</literal>, so it
           should be, e.g., owned by <literal>root:systemd-network</literal> with a
           <literal>0640</literal> file mode.</para>
index 61fbc24cfbe43040fb117d949fc9ff7874906518..d958a5f02f6908d6784b166f2406d783cfb91c76 100644 (file)
@@ -846,41 +846,29 @@ static void wireguard_done(NetDev *netdev) {
         set_free(w->peers_with_failed_endpoint);
 }
 
-static int wireguard_read_private_key_file(Wireguard *w, bool fatal) {
-        _cleanup_free_ char *contents = NULL;
-        _cleanup_free_ void *key = NULL;
-        size_t size, key_len;
-        NetDev *netdev;
-        int level, r;
-
-        assert(w);
-
-        netdev = NETDEV(w);
+static int wireguard_read_key_file(const char *filename, uint8_t dest[static WG_KEY_LEN]) {
+        _cleanup_free_ char *key = NULL;
+        size_t key_len;
+        int r;
 
-        if (!w->private_key_file)
+        if (!filename)
                 return 0;
 
-        level = fatal ? LOG_ERR : LOG_INFO;
-
-        r = read_full_file(w->private_key_file, &contents, &size);
+        r = read_full_file_full(filename, READ_FULL_FILE_SECURE | READ_FULL_FILE_UNBASE64, &key, &key_len);
         if (r < 0)
-                return log_netdev_full(netdev, level, r,
-                                       "Failed to read private key from '%s'%s: %m",
-                                       w->private_key_file, fatal ? "" : ", ignoring");
+                return r;
 
-        r = unbase64mem(contents, size, &key, &key_len);
-        if (r < 0)
-                return log_netdev_full(netdev, level, r,
-                                       "Failed to decode private key%s: %m",
-                                       fatal ? "" : ", ignoring");
+        if (key_len != WG_KEY_LEN) {
+                r = -EINVAL;
+                goto finalize;
+        }
 
-        if (key_len != WG_KEY_LEN)
-                return log_netdev_full(netdev, level, SYNTHETIC_ERRNO(EINVAL),
-                                       "Wireguard private key has invalid length (%zu bytes)%s: %m",
-                                       key_len, fatal ? "" : ", ignoring");
+        memcpy(dest, key, WG_KEY_LEN);
+        r = 0;
 
-        memcpy(w->private_key, key, WG_KEY_LEN);
-        return 0;
+finalize:
+        explicit_bzero_safe(key, key_len);
+        return r;
 }
 
 static int wireguard_peer_verify(WireguardPeer *peer) {
@@ -901,22 +889,23 @@ static int wireguard_peer_verify(WireguardPeer *peer) {
 static int wireguard_verify(NetDev *netdev, const char *filename) {
         WireguardPeer *peer, *peer_next;
         Wireguard *w;
-        bool empty;
         int r;
 
         assert(netdev);
         w = WIREGUARD(netdev);
         assert(w);
 
-        empty = eqzero(w->private_key);
-        if (empty && !w->private_key_file)
-                return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
-                                              "%s: Missing PrivateKey= or PrivateKeyFile=, ignoring.",
-                                              filename);
+        r = wireguard_read_key_file(w->private_key_file, w->private_key);
+        if (r < 0)
+                return log_netdev_error_errno(netdev, r,
+                                              "Failed to read private key from %s. Dropping network device %s.",
+                                              w->private_key_file, netdev->ifname);
 
-        r = wireguard_read_private_key_file(w, empty);
-        if (r < 0 && empty)
-                return r;
+        if (eqzero(w->private_key))
+                return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
+                                              "%s: Missing PrivateKey= or PrivateKeyFile=, "
+                                              "Dropping network device %s.",
+                                              filename, netdev->ifname);
 
         LIST_FOREACH_SAFE(peers, peer, peer_next, w->peers)
                 if (wireguard_peer_verify(peer) < 0)
index 61afd1f5e79d7e5009ad0ddf1122ca82185e8b62..4866c31ccac68b39837e86561e613631e634d4bd 100644 (file)
@@ -4,7 +4,6 @@ Kind=wireguard
 
 [WireGuard]
 PrivateKey=EEGlnEPYJV//kbvvIqxKkQwOiS+UENyPncC4bF46ong=
-PrivateKeyFile=/run/systemd/network/not-exist
 ListenPort=51820
 FwMark=1234