diff options
author | Maximilian Bosch <maximilian@mbosch.me> | 2021-02-19 19:56:19 +0100 |
---|---|---|
committer | Maximilian Bosch <maximilian@mbosch.me> | 2021-04-16 13:18:25 +0200 |
commit | de0a39166b622f9d4526a920db835619e90522bf (patch) | |
tree | 4c1729a3b5b07cd52554339bb0bb7d10273904e2 /pkgs/os-specific/linux/wpa_supplicant | |
parent | 98d6b081d12ebe7e443e62c40ebaeeddbe5bb9fc (diff) | |
download | nixpkgs-de0a39166b622f9d4526a920db835619e90522bf.tar nixpkgs-de0a39166b622f9d4526a920db835619e90522bf.tar.gz nixpkgs-de0a39166b622f9d4526a920db835619e90522bf.tar.bz2 nixpkgs-de0a39166b622f9d4526a920db835619e90522bf.tar.lz nixpkgs-de0a39166b622f9d4526a920db835619e90522bf.tar.xz nixpkgs-de0a39166b622f9d4526a920db835619e90522bf.tar.zst nixpkgs-de0a39166b622f9d4526a920db835619e90522bf.zip |
wpa_supplicant: allow both imperative and declarative networks
For a while now it's possible to specify an additional config file in `wpa_supplicant`[1]. In contrast to the file specified via `-c` this was supposed to be used for immutable settings and not e.g. additional networks. However I'm a little bit unhappy about the fact that one has to choose between a fully imperative setup and a fully declarative one where the one would have to write credentials for e.g. WPA2-enterprise networks into the store. The primary problem with the current state of `wpa_supplicant` is that if the `SAVE_CONFIG` command is invoked (e.g. via `wpa_cli`), all known networks will be written to `/etc/wpa_supplicant.conf` and thus all declarative networks would get out of sync with the declarative settings. To work around this, I had to change the following things: * The `networking.wireless`-module now uses `-I` for declarative config, so the user-controlled mode can be used along with the `networks`-option. * I added an `ro`-field to the `ssid`-struct in the `wpa_supplicant`-sources. This will be set to `1` for each network specified in the config passed via `-I`. Whenever config is written to the disk, those networks will be skipped, so changes to declarative networks are only temporary. [1] https://w1.fi/cgit/hostap/commit/wpa_supplicant?id=e6304cad47251e88d073553042f1ea7805a858d1
Diffstat (limited to 'pkgs/os-specific/linux/wpa_supplicant')
-rw-r--r-- | pkgs/os-specific/linux/wpa_supplicant/0001-Implement-read-only-mode-for-ssids.patch | 130 | ||||
-rw-r--r-- | pkgs/os-specific/linux/wpa_supplicant/default.nix | 2 |
2 files changed, 132 insertions, 0 deletions
diff --git a/pkgs/os-specific/linux/wpa_supplicant/0001-Implement-read-only-mode-for-ssids.patch b/pkgs/os-specific/linux/wpa_supplicant/0001-Implement-read-only-mode-for-ssids.patch new file mode 100644 index 00000000000..c0480d62385 --- /dev/null +++ b/pkgs/os-specific/linux/wpa_supplicant/0001-Implement-read-only-mode-for-ssids.patch @@ -0,0 +1,130 @@ +From 99ae610f0ae3608a12c864caedf396f14e68327d Mon Sep 17 00:00:00 2001 +From: Maximilian Bosch <maximilian@mbosch.me> +Date: Fri, 19 Feb 2021 19:44:21 +0100 +Subject: [PATCH] Implement read-only mode for ssids + +With this change it's possible to define `network=`-sections in a second +config file specified via `-I` without having changes written to +`/etc/wpa_supplicant.conf`. + +This is helpful on e.g. NixOS to allow both declarative (i.e. read-only) +and imperative (i.e. mutable) networks. +--- + wpa_supplicant/config.h | 2 +- + wpa_supplicant/config_file.c | 5 +++-- + wpa_supplicant/config_none.c | 2 +- + wpa_supplicant/config_ssid.h | 2 ++ + wpa_supplicant/wpa_supplicant.c | 8 ++++---- + 5 files changed, 11 insertions(+), 8 deletions(-) + +diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h +index 6a297ecfe..adaf4d398 100644 +--- a/wpa_supplicant/config.h ++++ b/wpa_supplicant/config.h +@@ -1614,7 +1614,7 @@ const char * wpa_config_get_global_field_name(unsigned int i, int *no_var); + * + * Each configuration backend needs to implement this function. + */ +-struct wpa_config * wpa_config_read(const char *name, struct wpa_config *cfgp); ++struct wpa_config * wpa_config_read(const char *name, struct wpa_config *cfgp, int ro); + + /** + * wpa_config_write - Write or update configuration data +diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c +index 77c326df5..d5ed051b9 100644 +--- a/wpa_supplicant/config_file.c ++++ b/wpa_supplicant/config_file.c +@@ -373,7 +373,7 @@ static int wpa_config_process_blob(struct wpa_config *config, FILE *f, + #endif /* CONFIG_NO_CONFIG_BLOBS */ + + +-struct wpa_config * wpa_config_read(const char *name, struct wpa_config *cfgp) ++struct wpa_config * wpa_config_read(const char *name, struct wpa_config *cfgp, int ro) + { + FILE *f; + char buf[512], *pos; +@@ -415,6 +415,7 @@ struct wpa_config * wpa_config_read(const char *name, struct wpa_config *cfgp) + while (wpa_config_get_line(buf, sizeof(buf), f, &line, &pos)) { + if (os_strcmp(pos, "network={") == 0) { + ssid = wpa_config_read_network(f, &line, id++); ++ ssid->ro = ro; + if (ssid == NULL) { + wpa_printf(MSG_ERROR, "Line %d: failed to " + "parse network block.", line); +@@ -1591,7 +1592,7 @@ int wpa_config_write(const char *name, struct wpa_config *config) + } + + for (ssid = config->ssid; ssid; ssid = ssid->next) { +- if (ssid->key_mgmt == WPA_KEY_MGMT_WPS || ssid->temporary) ++ if (ssid->key_mgmt == WPA_KEY_MGMT_WPS || ssid->temporary || ssid->ro == 1) + continue; /* do not save temporary networks */ + if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set && + !ssid->passphrase) +diff --git a/wpa_supplicant/config_none.c b/wpa_supplicant/config_none.c +index 2aac28fa3..02191b425 100644 +--- a/wpa_supplicant/config_none.c ++++ b/wpa_supplicant/config_none.c +@@ -17,7 +17,7 @@ + #include "base64.h" + + +-struct wpa_config * wpa_config_read(const char *name, struct wpa_config *cfgp) ++struct wpa_config * wpa_config_read(const char *name, struct wpa_config *cfgp, int ro) + { + struct wpa_config *config; + +diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h +index d5c5c00a9..fd80c079c 100644 +--- a/wpa_supplicant/config_ssid.h ++++ b/wpa_supplicant/config_ssid.h +@@ -93,6 +93,8 @@ struct wpa_ssid { + */ + int id; + ++ int ro; ++ + /** + * priority - Priority group + * +diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c +index 911d79d17..cb0cb99b1 100644 +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -1052,14 +1052,14 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s) + + if (wpa_s->confname == NULL) + return -1; +- conf = wpa_config_read(wpa_s->confname, NULL); ++ conf = wpa_config_read(wpa_s->confname, NULL, 0); + if (conf == NULL) { + wpa_msg(wpa_s, MSG_ERROR, "Failed to parse the configuration " + "file '%s' - exiting", wpa_s->confname); + return -1; + } + if (wpa_s->confanother && +- !wpa_config_read(wpa_s->confanother, conf)) { ++ !wpa_config_read(wpa_s->confanother, conf, 1)) { + wpa_msg(wpa_s, MSG_ERROR, + "Failed to parse the configuration file '%s' - exiting", + wpa_s->confanother); +@@ -5638,7 +5638,7 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s, + #else /* CONFIG_BACKEND_FILE */ + wpa_s->confname = os_strdup(iface->confname); + #endif /* CONFIG_BACKEND_FILE */ +- wpa_s->conf = wpa_config_read(wpa_s->confname, NULL); ++ wpa_s->conf = wpa_config_read(wpa_s->confname, NULL, 0); + if (wpa_s->conf == NULL) { + wpa_printf(MSG_ERROR, "Failed to read or parse " + "configuration '%s'.", wpa_s->confname); +@@ -5646,7 +5646,7 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s, + } + wpa_s->confanother = os_rel2abs_path(iface->confanother); + if (wpa_s->confanother && +- !wpa_config_read(wpa_s->confanother, wpa_s->conf)) { ++ !wpa_config_read(wpa_s->confanother, wpa_s->conf, 1)) { + wpa_printf(MSG_ERROR, + "Failed to read or parse configuration '%s'.", + wpa_s->confanother); +-- +2.29.2 + diff --git a/pkgs/os-specific/linux/wpa_supplicant/default.nix b/pkgs/os-specific/linux/wpa_supplicant/default.nix index 80eaf04a114..8bfe947abb9 100644 --- a/pkgs/os-specific/linux/wpa_supplicant/default.nix +++ b/pkgs/os-specific/linux/wpa_supplicant/default.nix @@ -43,6 +43,8 @@ stdenv.mkDerivation rec { url = "https://w1.fi/cgit/hostap/patch/?id=a0541334a6394f8237a4393b7372693cd7e96f15"; sha256 = "1gbhlz41x1ar1hppnb76pqxj6vimiypy7c4kq6h658637s4am3xg"; }) + # Allow read-only networks + ./0001-Implement-read-only-mode-for-ssids.patch ]; # TODO: Patch epoll so that the dbus actually responds |