All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 3/6] main: add SystemdEncrypt option, and initialize key
@ 2022-02-04 21:33 James Prestwood
  0 siblings, 0 replies; only message in thread
From: James Prestwood @ 2022-02-04 21:33 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 3210 bytes --]

Recently systemd added the ability to pass secret credentials to
services via LoadCredentialEncrypted/SetCredentialEncrypted. Once
set up the service is able to read the decrypted credentials from
a file. The file path is found in the environment variable
CREDENTIALS_DIRECTORY + an identifier. The value of SystemdEncrypt
should be set to the systemd key ID used when the credential was
created.

When SystemdEncrypt is set IWD will attempt to read the decrypted
secret from systemd. If at any point this fails warnings will be
printed but IWD will continue normally. Its expected that any failures
will result in the inability to connect to any networks which have
previously encrypted the passphrase/PSK without re-entering
the passphrase manually. This could happen, for example, if the
systemd secret was changed.

Once the secret is read in it is set into storage to be used for
profile encryption/decryption.
---
 src/main.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/src/main.c b/src/main.c
index d0dbedc8..a345c950 100644
--- a/src/main.c
+++ b/src/main.c
@@ -29,6 +29,10 @@
 #include <errno.h>
 #include <getopt.h>
 #include <signal.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
 #include <ell/ell.h>
 
 #include <ell/useful.h>
@@ -45,6 +49,7 @@
 #include "src/storage.h"
 #include "src/anqp.h"
 #include "src/netconfig.h"
+#include "src/crypto.h"
 
 #include "src/backtrace.h"
 
@@ -397,6 +402,63 @@ done:
 	return r;
 }
 
+/*
+ * Initialize a systemd encryption key for encrypting/decrypting credentials.
+ */
+static void setup_system_key(void)
+{
+	int fd;
+	struct stat st;
+	const char *cred_dir;
+	void *key = NULL;
+	_auto_(l_free) char *path = NULL;
+	_auto_(l_free) char *key_id = NULL;
+
+	key_id = l_settings_get_string(iwd_config, "General", "SystemdEncrypt");
+	if (!key_id)
+		return;
+
+	cred_dir = getenv("CREDENTIALS_DIRECTORY");
+	if (!cred_dir) {
+		l_warn("SystemdEncrypt enabled but CREDENTIALS_DIRECTORY not "
+			"set, check iwd.service file");
+		return;
+	}
+
+	path = l_strdup_printf("%s/%s", cred_dir, key_id);
+
+	if (stat(path, &st) < 0) {
+		l_warn("SystemdEncrypt enabled but could not stat %s",
+			path);
+		return;
+	}
+
+	fd = open(path, O_RDONLY, 0);
+	if (fd < 0) {
+		l_warn("SystemdEncrypt enabled but cannot open secret (%d)",
+				fd);
+		return;
+	}
+
+	if (fstat(fd, &st) < 0 || st.st_size == 0) {
+		close(fd);
+		return;
+	}
+
+	key = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+	if (key == MAP_FAILED) {
+		l_warn("SystemdEncrypt enabled but can't mmap secret");
+		close(fd);
+		return;
+	}
+
+	close(fd);
+
+	__storage_set_encryption_key(key, st.st_size);
+
+	munmap(key, st.st_size);
+}
+
 int main(int argc, char *argv[])
 {
 	int exit_status;
@@ -529,6 +591,8 @@ int main(int argc, char *argv[])
 	l_dbus_set_disconnect_handler(dbus, dbus_disconnected, NULL, NULL);
 	dbus_init(dbus);
 
+	setup_system_key();
+
 	exit_status = l_main_run_with_signal(signal_handler, NULL);
 
 	iwd_modules_exit();
-- 
2.31.1

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2022-02-04 21:33 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-04 21:33 [PATCH v5 3/6] main: add SystemdEncrypt option, and initialize key James Prestwood

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.