python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / nixos / modules / services / networking / xrdp.nix
blobed7f1dadd3707a762af68b3de320d235f20d3c54
1 { config, lib, pkgs, ... }:
3 with lib;
5 let
6   cfg = config.services.xrdp;
7   confDir = pkgs.runCommand "xrdp.conf" { preferLocalBuild = true; } ''
8     mkdir $out
10     cp ${cfg.package}/etc/xrdp/{km-*,xrdp,sesman,xrdp_keyboard}.ini $out
12     cat > $out/startwm.sh <<EOF
13     #!/bin/sh
14     . /etc/profile
15     ${cfg.defaultWindowManager}
16     EOF
17     chmod +x $out/startwm.sh
19     substituteInPlace $out/xrdp.ini \
20       --replace "#rsakeys_ini=" "rsakeys_ini=/run/xrdp/rsakeys.ini" \
21       --replace "certificate=" "certificate=${cfg.sslCert}" \
22       --replace "key_file=" "key_file=${cfg.sslKey}" \
23       --replace LogFile=xrdp.log LogFile=/dev/null \
24       --replace EnableSyslog=true EnableSyslog=false
26     substituteInPlace $out/sesman.ini \
27       --replace LogFile=xrdp-sesman.log LogFile=/dev/null \
28       --replace EnableSyslog=1 EnableSyslog=0
30     # Ensure that clipboard works for non-ASCII characters
31     sed -i -e '/.*SessionVariables.*/ a\
32     LANG=${config.i18n.defaultLocale}\
33     LOCALE_ARCHIVE=${config.i18n.glibcLocales}/lib/locale/locale-archive
34     ' $out/sesman.ini
35   '';
39   ###### interface
41   options = {
43     services.xrdp = {
45       enable = mkEnableOption (lib.mdDoc "xrdp, the Remote Desktop Protocol server");
47       package = mkOption {
48         type = types.package;
49         default = pkgs.xrdp;
50         defaultText = literalExpression "pkgs.xrdp";
51         description = lib.mdDoc ''
52           The package to use for the xrdp daemon's binary.
53         '';
54       };
56       port = mkOption {
57         type = types.port;
58         default = 3389;
59         description = lib.mdDoc ''
60           Specifies on which port the xrdp daemon listens.
61         '';
62       };
64       openFirewall = mkOption {
65         default = false;
66         type = types.bool;
67         description = lib.mdDoc "Whether to open the firewall for the specified RDP port.";
68       };
70       sslKey = mkOption {
71         type = types.str;
72         default = "/etc/xrdp/key.pem";
73         example = "/path/to/your/key.pem";
74         description = lib.mdDoc ''
75           ssl private key path
76           A self-signed certificate will be generated if file not exists.
77         '';
78       };
80       sslCert = mkOption {
81         type = types.str;
82         default = "/etc/xrdp/cert.pem";
83         example = "/path/to/your/cert.pem";
84         description = lib.mdDoc ''
85           ssl certificate path
86           A self-signed certificate will be generated if file not exists.
87         '';
88       };
90       defaultWindowManager = mkOption {
91         type = types.str;
92         default = "xterm";
93         example = "xfce4-session";
94         description = lib.mdDoc ''
95           The script to run when user log in, usually a window manager, e.g. "icewm", "xfce4-session"
96           This is per-user overridable, if file ~/startwm.sh exists it will be used instead.
97         '';
98       };
100       confDir = mkOption {
101         type = types.path;
102         default = confDir;
103         defaultText = literalMD "generated from configuration";
104         description = lib.mdDoc "The location of the config files for xrdp.";
105       };
106     };
107   };
110   ###### implementation
112   config = mkIf cfg.enable {
114     networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ];
116     # xrdp can run X11 program even if "services.xserver.enable = false"
117     xdg = {
118       autostart.enable = true;
119       menus.enable = true;
120       mime.enable = true;
121       icons.enable = true;
122     };
124     fonts.enableDefaultFonts = mkDefault true;
126     systemd = {
127       services.xrdp = {
128         wantedBy = [ "multi-user.target" ];
129         after = [ "network.target" ];
130         description = "xrdp daemon";
131         requires = [ "xrdp-sesman.service" ];
132         preStart = ''
133           # prepare directory for unix sockets (the sockets will be owned by loggedinuser:xrdp)
134           mkdir -p /tmp/.xrdp || true
135           chown xrdp:xrdp /tmp/.xrdp
136           chmod 3777 /tmp/.xrdp
138           # generate a self-signed certificate
139           if [ ! -s ${cfg.sslCert} -o ! -s ${cfg.sslKey} ]; then
140             mkdir -p $(dirname ${cfg.sslCert}) || true
141             mkdir -p $(dirname ${cfg.sslKey}) || true
142             ${pkgs.openssl.bin}/bin/openssl req -x509 -newkey rsa:2048 -sha256 -nodes -days 365 \
143               -subj /C=US/ST=CA/L=Sunnyvale/O=xrdp/CN=www.xrdp.org \
144               -config ${cfg.package}/share/xrdp/openssl.conf \
145               -keyout ${cfg.sslKey} -out ${cfg.sslCert}
146             chown root:xrdp ${cfg.sslKey} ${cfg.sslCert}
147             chmod 440 ${cfg.sslKey} ${cfg.sslCert}
148           fi
149           if [ ! -s /run/xrdp/rsakeys.ini ]; then
150             mkdir -p /run/xrdp
151             ${cfg.package}/bin/xrdp-keygen xrdp /run/xrdp/rsakeys.ini
152           fi
153         '';
154         serviceConfig = {
155           User = "xrdp";
156           Group = "xrdp";
157           PermissionsStartOnly = true;
158           ExecStart = "${cfg.package}/bin/xrdp --nodaemon --port ${toString cfg.port} --config ${cfg.confDir}/xrdp.ini";
159         };
160       };
162       services.xrdp-sesman = {
163         wantedBy = [ "multi-user.target" ];
164         after = [ "network.target" ];
165         description = "xrdp session manager";
166         restartIfChanged = false; # do not restart on "nixos-rebuild switch". like "display-manager", it can have many interactive programs as children
167         serviceConfig = {
168           ExecStart = "${cfg.package}/bin/xrdp-sesman --nodaemon --config ${cfg.confDir}/sesman.ini";
169           ExecStop  = "${pkgs.coreutils}/bin/kill -INT $MAINPID";
170         };
171       };
173     };
175     users.users.xrdp = {
176       description   = "xrdp daemon user";
177       isSystemUser  = true;
178       group         = "xrdp";
179     };
180     users.groups.xrdp = {};
182     security.pam.services.xrdp-sesman = { allowNullPassword = true; startSession = true; };
183   };