diff --git a/modules/services/networking/wpa_supplicant.nix b/modules/services/networking/wpa_supplicant.nix
index d2b57fb97d54..338a801f701f 100644
--- a/modules/services/networking/wpa_supplicant.nix
+++ b/modules/services/networking/wpa_supplicant.nix
@@ -4,10 +4,11 @@ with pkgs.lib;
let
+ cfg = config.networking.wireless;
configFile = "/etc/wpa_supplicant.conf";
ifaces =
- config.networking.wireless.interfaces ++
+ cfg.interfaces ++
optional (config.networking.WLANInterface != "") config.networking.WLANInterface;
in
@@ -18,40 +19,69 @@ in
options = {
- networking.wireless.enable = mkOption {
- default = false;
- description = ''
- Whether to start wpa_supplicant to scan for
- and associate with wireless networks. Note: NixOS currently
- does not generate wpa_supplicant's
- configuration file, ${configFile}. You
- should edit this file yourself to define wireless networks,
- WPA keys and so on (see
- wpa_supplicant.conf
- 5).
- '';
- };
-
networking.WLANInterface = mkOption {
default = "";
description = "Obsolete. Use instead.";
};
- networking.wireless.interfaces = mkOption {
- default = [];
- example = [ "wlan0" "wlan1" ];
- description = ''
- The interfaces wpa_supplicant will use. If empty, it will
- automatically use all wireless interfaces.
- '';
- };
+ networking.wireless = {
+ enable = mkOption {
+ default = false;
+ description = ''
+ Whether to start wpa_supplicant to scan for
+ and associate with wireless networks. Note: NixOS currently
+ does not generate wpa_supplicant's
+ configuration file, ${configFile}. You
+ should edit this file yourself to define wireless networks,
+ WPA keys and so on (see
+ wpa_supplicant.conf
+ 5).
+ '';
+ };
+ interfaces = mkOption {
+ default = [];
+ example = [ "wlan0" "wlan1" ];
+ description = ''
+ The interfaces wpa_supplicant will use. If empty, it will
+ automatically use all wireless interfaces.
+ '';
+ };
+
+ driver = mkOption {
+ default = "";
+ example = "nl80211";
+ description = "force a specific wpa_supplicant driver";
+ };
+
+ userControlled = {
+ enable = mkOption {
+ default = false;
+ description = ''
+ Allow normal users to control wpa_supplicant through wpa_gui or wpa_cli.
+ This is useful for laptop users that switch networks a lot.
+
+ When you want to use this, make sure ${configFile} doesn't exist.
+ It will be created for you.
+
+ Currently it is also necesarry to explicitly specify networking.wireless.interfaces
+ '';
+ };
+
+ group = mkOption {
+ default = "wheel";
+ example = "network";
+ type = types.string;
+ description = "members of this group can control wpa_supplicant";
+ };
+ };
+ };
};
###### implementation
- config = mkIf config.networking.wireless.enable {
+ config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.wpa_supplicant ];
@@ -63,11 +93,15 @@ in
path = [ pkgs.wpa_supplicant ];
- preStart =
- ''
- touch -a ${configFile}
- chmod 600 ${configFile}
- '';
+ preStart = ''
+ touch -a ${configFile}
+ chmod 600 ${configFile}
+ '' + optionalString cfg.userControlled.enable ''
+ if [ ! -s ${configFile} ]; then
+ echo "ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=${cfg.userControlled.group}" >> ${configFile}
+ echo "update_config=1" >> ${configFile}
+ fi
+ '';
script =
''
@@ -80,7 +114,7 @@ in
'' else ''
ifaces="${concatStringsSep " -N " (map (i: "-i${i}") ifaces)}"
''}
- exec wpa_supplicant -s -u -c ${configFile} $ifaces
+ exec wpa_supplicant -s -u ${optionalString (cfg.driver != "") "-D${cfg.driver}"} -c ${configFile} $ifaces
'';
};
@@ -89,6 +123,10 @@ in
${config.system.build.upstart}/sbin/restart wpa_supplicant
'';
+ assertions = [{ assertion = !cfg.userControlled.enable || cfg.interfaces != [];
+ message = "user controlled wpa_supplicant needs explicit networking.wireless.interfaces";}];
+
+
};
}