From 2d93f57db58f2631017714c4e28bf72c2c52c036 Mon Sep 17 00:00:00 2001 From: LeOtaku Date: Thu, 2 May 2019 00:08:56 +0200 Subject: [PATCH] nixos/geoclue2: make configurable, can whitelist applications All options within geoclue.conf[0] have been made configurable. Additonally, we can now specify whether or not GeoClue should ask the agent to authorize an application like so: ``` services.geoclue2.appConfig."redshift" = { isAllowed = true; isSystem = true; }; ``` [0]: https://gitlab.freedesktop.org/geoclue/geoclue/blob/2.5.2/data/geoclue.conf.in Co-authored-by: worldofpeace --- nixos/modules/services/desktops/geoclue2.nix | 188 ++++++++++++++++++- 1 file changed, 183 insertions(+), 5 deletions(-) diff --git a/nixos/modules/services/desktops/geoclue2.nix b/nixos/modules/services/desktops/geoclue2.nix index 840aa5294ed0..a16dbc04a5f7 100644 --- a/nixos/modules/services/desktops/geoclue2.nix +++ b/nixos/modules/services/desktops/geoclue2.nix @@ -7,6 +7,56 @@ with lib; let # the demo agent isn't built by default, but we need it here package = pkgs.geoclue2.override { withDemoAgent = config.services.geoclue2.enableDemoAgent; }; + + cfg = config.services.geoclue2; + + defaultWhitelist = [ "gnome-shell" "io.elementary.desktop.agent-geoclue2" ]; + + appConfigModule = types.submodule ({ name, ... }: { + options = { + desktopID = mkOption { + type = types.str; + description = "Desktop ID of the application."; + }; + + isAllowed = mkOption { + type = types.bool; + default = null; + description = '' + Whether the application will be allowed access to location information. + ''; + }; + + isSystem = mkOption { + type = types.bool; + default = null; + description = '' + Whether the application is a system component or not. + ''; + }; + + users = mkOption { + type = types.listOf types.str; + default = []; + description = '' + List of UIDs of all users for which this application is allowed location + info access, Defaults to an empty string to allow it for all users. + ''; + }; + }; + + config.desktopID = mkDefault name; + }); + + appConfigToINICompatible = _: { desktopID, isAllowed, isSystem, users, ... }: { + name = desktopID; + value = { + allowed = isAllowed; + system = isSystem; + users = concatStringsSep ";" users; + }; + }; + in { @@ -35,23 +85,117 @@ in ''; }; + enableNmea = mkOption { + type = types.bool; + default = true; + description = '' + Whether to fetch location from NMEA sources on local network. + ''; + }; + + enable3G = mkOption { + type = types.bool; + default = true; + description = '' + Whether to enable 3G source. + ''; + }; + + enableCDMA = mkOption { + type = types.bool; + default = true; + description = '' + Whether to enable CDMA source. + ''; + }; + + enableModemGPS = mkOption { + type = types.bool; + default = true; + description = '' + Whether to enable Modem-GPS source. + ''; + }; + + enableWifi = mkOption { + type = types.bool; + default = true; + description = '' + Whether to enable WiFi source. + ''; + }; + + geoProviderUrl = mkOption { + type = types.str; + default = "https://location.services.mozilla.com/v1/geolocate?key=geoclue"; + example = "https://www.googleapis.com/geolocation/v1/geolocate?key=YOUR_KEY"; + description = '' + The url to the wifi GeoLocation Service. + ''; + }; + + submitData = mkOption { + type = types.bool; + default = false; + description = '' + Whether to submit data to a GeoLocation Service. + ''; + }; + + submissionUrl = mkOption { + type = types.str; + default = "https://location.services.mozilla.com/v1/submit?key=geoclue"; + description = '' + The url to submit data to a GeoLocation Service. + ''; + }; + + submissionNick = mkOption { + type = types.str; + default = "geoclue"; + description = '' + A nickname to submit network data with. + Must be 2-32 characters long. + ''; + }; + + appConfig = mkOption { + type = types.loaOf appConfigModule; + default = {}; + example = literalExample '' + "com.github.app" = { + isAllowed = true; + isSystem = true; + users = [ "300" ]; + }; + ''; + description = '' + Specify extra settings per application. + ''; + }; + }; }; ###### implementation - config = mkIf config.services.geoclue2.enable { + config = mkIf cfg.enable { environment.systemPackages = [ package ]; services.dbus.packages = [ package ]; systemd.packages = [ package ]; - + + # restart geoclue service when the configuration changes + systemd.services."geoclue".restartTriggers = [ + config.environment.etc."geoclue/geoclue.conf".source + ]; + # this needs to run as a user service, since it's associated with the # user who is making the requests - systemd.user.services = mkIf config.services.geoclue2.enableDemoAgent { + systemd.user.services = mkIf cfg.enableDemoAgent { "geoclue-agent" = { description = "Geoclue agent"; script = "${package}/libexec/geoclue-2.0/demos/agent"; @@ -62,7 +206,41 @@ in }; }; - environment.etc."geoclue/geoclue.conf".source = "${package}/etc/geoclue/geoclue.conf"; - }; + services.geoclue2.appConfig."epiphany" = { + isAllowed = true; + isSystem = false; + }; + services.geoclue2.appConfig."firefox" = { + isAllowed = true; + isSystem = false; + }; + + environment.etc."geoclue/geoclue.conf".text = + generators.toINI {} ({ + agent = { + whitelist = concatStringsSep ";" + (optional cfg.enableDemoAgent "geoclue-demo-agent" ++ defaultWhitelist); + }; + network-nmea = { + enable = cfg.enableNmea; + }; + "3g" = { + enable = cfg.enable3G; + }; + cdma = { + enable = cfg.enableCDMA; + }; + modem-gps = { + enable = cfg.enableModemGPS; + }; + wifi = { + enable = cfg.enableWifi; + url = cfg.geoProviderUrl; + submit-data = boolToString cfg.submitData; + submission-url = cfg.submissionUrl; + submission-nick = cfg.submissionNick; + }; + } // mapAttrs' appConfigToINICompatible cfg.appConfig); + }; }