vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / services / hardware / sane.nix
blob98207ada78c393c44ed4c594035f3a70841d8d02
1 { config, lib, pkgs, ... }:
2 let
4   pkg = config.hardware.sane.backends-package.override {
5     scanSnapDriversUnfree = config.hardware.sane.drivers.scanSnap.enable;
6     scanSnapDriversPackage = config.hardware.sane.drivers.scanSnap.package;
7   };
9   sanedConf = pkgs.writeTextFile {
10     name = "saned.conf";
11     destination = "/etc/sane.d/saned.conf";
12     text = ''
13       localhost
14       ${config.services.saned.extraConfig}
15     '';
16   };
18   netConf = pkgs.writeTextFile {
19     name = "net.conf";
20     destination = "/etc/sane.d/net.conf";
21     text = ''
22       ${lib.optionalString config.services.saned.enable "localhost"}
23       ${config.hardware.sane.netConf}
24     '';
25   };
27   env = {
28     SANE_CONFIG_DIR = "/etc/sane-config";
29     LD_LIBRARY_PATH = [ "/etc/sane-libs" ];
30   };
32   backends = [ pkg netConf ] ++ lib.optional config.services.saned.enable sanedConf ++ config.hardware.sane.extraBackends;
33   saneConfig = pkgs.mkSaneConfig { paths = backends; inherit (config.hardware.sane) disabledDefaultBackends; };
35   enabled = config.hardware.sane.enable || config.services.saned.enable;
41   ###### interface
43   options = {
45     hardware.sane.enable = lib.mkOption {
46       type = lib.types.bool;
47       default = false;
48       description = ''
49         Enable support for SANE scanners.
51         ::: {.note}
52         Users in the "scanner" group will gain access to the scanner, or the "lp" group if it's also a printer.
53         :::
54       '';
55     };
57     hardware.sane.backends-package = lib.mkOption {
58       type = lib.types.package;
59       default = pkgs.sane-backends;
60       defaultText = lib.literalExpression "pkgs.sane-backends";
61       description = "Backends driver package to use.";
62     };
64     hardware.sane.snapshot = lib.mkOption {
65       type = lib.types.bool;
66       default = false;
67       description = "Use a development snapshot of SANE scanner drivers.";
68     };
70     hardware.sane.extraBackends = lib.mkOption {
71       type = lib.types.listOf lib.types.path;
72       default = [];
73       description = ''
74         Packages providing extra SANE backends to enable.
76         ::: {.note}
77         The example contains the package for HP scanners, and the package for
78         Apple AirScan and Microsoft WSD support (supports many
79         vendors/devices).
80         :::
81       '';
82       example = lib.literalExpression "[ pkgs.hplipWithPlugin pkgs.sane-airscan ]";
83     };
85     hardware.sane.disabledDefaultBackends = lib.mkOption {
86       type = lib.types.listOf lib.types.str;
87       default = [];
88       example = [ "v4l" ];
89       description = ''
90         Names of backends which are enabled by default but should be disabled.
91         See `$SANE_CONFIG_DIR/dll.conf` for the list of possible names.
92       '';
93     };
95     hardware.sane.configDir = lib.mkOption {
96       type = lib.types.str;
97       internal = true;
98       description = "The value of SANE_CONFIG_DIR.";
99     };
101     hardware.sane.netConf = lib.mkOption {
102       type = lib.types.lines;
103       default = "";
104       example = "192.168.0.16";
105       description = ''
106         Network hosts that should be probed for remote scanners.
107       '';
108     };
110     hardware.sane.drivers.scanSnap.enable = lib.mkOption {
111       type = lib.types.bool;
112       default = false;
113       example = true;
114       description = ''
115         Whether to enable drivers for the Fujitsu ScanSnap scanners.
117         The driver files are unfree and extracted from the Windows driver image.
118       '';
119     };
121     hardware.sane.drivers.scanSnap.package = lib.mkPackageOption pkgs [ "sane-drivers" "epjitsu" ] {
122       extraDescription = ''
123         Useful if you want to extract the driver files yourself.
125         The process is described in the {file}`/etc/sane.d/epjitsu.conf` file in
126         the `sane-backends` package.
127       '';
128     };
130     hardware.sane.openFirewall = lib.mkOption {
131       type = lib.types.bool;
132       default = false;
133       description = ''
134         Open ports needed for discovery of scanners on the local network, e.g.
135         needed for Canon scanners (BJNP protocol).
136       '';
137     };
139     services.saned.enable = lib.mkOption {
140       type = lib.types.bool;
141       default = false;
142       description = ''
143         Enable saned network daemon for remote connection to scanners.
145         saned would be run from `scanner` user; to allow
146         access to hardware that doesn't have `scanner` group
147         you should add needed groups to this user.
148       '';
149     };
151     services.saned.extraConfig = lib.mkOption {
152       type = lib.types.lines;
153       default = "";
154       example = "192.168.0.0/24";
155       description = ''
156         Extra saned configuration lines.
157       '';
158     };
160   };
163   ###### implementation
165   config = lib.mkMerge [
166     (lib.mkIf enabled {
167       hardware.sane.configDir = lib.mkDefault "${saneConfig}/etc/sane.d";
169       environment.systemPackages = backends;
170       environment.sessionVariables = env;
171       environment.etc."sane-config".source = config.hardware.sane.configDir;
172       environment.etc."sane-libs".source = "${saneConfig}/lib/sane";
173       services.udev.packages = backends;
175       users.groups.scanner.gid = config.ids.gids.scanner;
176       networking.firewall.allowedUDPPorts = lib.mkIf config.hardware.sane.openFirewall [ 8612 ];
178       systemd.tmpfiles.rules = [
179         "d /var/lock/sane 0770 root scanner - -"
180       ];
181     })
183     (lib.mkIf config.services.saned.enable {
184       networking.firewall.connectionTrackingModules = [ "sane" ];
186       systemd.services."saned@" = {
187         description = "Scanner Service";
188         environment = lib.mapAttrs (name: val: toString val) env;
189         serviceConfig = {
190           User = "scanner";
191           Group = "scanner";
192           ExecStart = "${pkg}/bin/saned";
193         };
194       };
196       systemd.sockets.saned = {
197         description = "saned incoming socket";
198         wantedBy = [ "sockets.target" ];
199         listenStreams = [ "0.0.0.0:6566" "[::]:6566" ];
200         socketConfig = {
201           # saned needs to distinguish between IPv4 and IPv6 to open matching data sockets.
202           BindIPv6Only = "ipv6-only";
203           Accept = true;
204           MaxConnections = 64;
205         };
206       };
208       users.users.scanner = {
209         uid = config.ids.uids.scanner;
210         group = "scanner";
211         extraGroups = [ "lp" ] ++ lib.optionals config.services.avahi.enable [ "avahi" ];
212       };
213     })
214   ];