mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2025-01-03 10:32:33 +01:00
main: add SystemdEncrypt option, and initialize key
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.
This commit is contained in:
parent
64f225df6e
commit
e8e9c68dea
76
src/main.c
76
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,71 @@ done:
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a systemd encryption key for encrypting/decrypting credentials.
|
||||
*/
|
||||
static bool 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;
|
||||
bool r = false;
|
||||
|
||||
key_id = l_settings_get_string(iwd_config, "General",
|
||||
"SystemdEncrypt");
|
||||
if (!key_id)
|
||||
return true;
|
||||
|
||||
cred_dir = getenv("CREDENTIALS_DIRECTORY");
|
||||
if (!cred_dir) {
|
||||
l_warn("SystemdEncrypt enabled but CREDENTIALS_DIRECTORY not "
|
||||
"set, check iwd.service file");
|
||||
return false;
|
||||
}
|
||||
|
||||
path = l_strdup_printf("%s/%s", cred_dir, key_id);
|
||||
|
||||
if (stat(path, &st) < 0) {
|
||||
l_warn("SystemdEncrypt: Could not stat %s", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
fd = open(path, O_RDONLY, 0);
|
||||
if (fd < 0) {
|
||||
l_warn("SystemdEncrypt: Cannot open secret: %s (%d)",
|
||||
strerror(errno), errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fstat(fd, &st) < 0 || st.st_size == 0)
|
||||
goto close_fd;
|
||||
|
||||
key = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (key == MAP_FAILED) {
|
||||
l_warn("SystemdEncrypt: can't mmap secret: %s (%d)",
|
||||
strerror(errno), errno);
|
||||
goto close_fd;
|
||||
}
|
||||
|
||||
if (mlock(key, st.st_size) < 0) {
|
||||
l_warn("SystemdEncrypt: Failed to mlock secrets file");
|
||||
goto unmap;
|
||||
}
|
||||
|
||||
r = storage_init(key, st.st_size);
|
||||
munlock(key, st.st_size);
|
||||
|
||||
unmap:
|
||||
munmap(key, st.st_size);
|
||||
close_fd:
|
||||
close(fd);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int exit_status;
|
||||
@ -529,9 +599,15 @@ int main(int argc, char *argv[])
|
||||
l_dbus_set_disconnect_handler(dbus, dbus_disconnected, NULL, NULL);
|
||||
dbus_init(dbus);
|
||||
|
||||
if (!setup_system_key())
|
||||
goto failed_storage;
|
||||
|
||||
exit_status = l_main_run_with_signal(signal_handler, NULL);
|
||||
|
||||
iwd_modules_exit();
|
||||
storage_exit();
|
||||
|
||||
failed_storage:
|
||||
dbus_exit();
|
||||
l_dbus_destroy(dbus);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user