summary refs log tree commit diff
diff options
context:
space:
mode:
authorvolth <volth@webmaster.ms>2017-01-05 23:14:35 +0000
committerVolth <volth@webmaster.ms>2017-04-29 17:23:35 +0000
commitdad760061eebae26c33415a1b38704ff1b1a88d2 (patch)
tree7b038bac5bfd734e6c485accaf97f05f30c559a0
parent63433537ce3f52f9bc460961b2b73e40db027447 (diff)
downloadnixpkgs-dad760061eebae26c33415a1b38704ff1b1a88d2.tar
nixpkgs-dad760061eebae26c33415a1b38704ff1b1a88d2.tar.gz
nixpkgs-dad760061eebae26c33415a1b38704ff1b1a88d2.tar.bz2
nixpkgs-dad760061eebae26c33415a1b38704ff1b1a88d2.tar.lz
nixpkgs-dad760061eebae26c33415a1b38704ff1b1a88d2.tar.xz
nixpkgs-dad760061eebae26c33415a1b38704ff1b1a88d2.tar.zst
nixpkgs-dad760061eebae26c33415a1b38704ff1b1a88d2.zip
xrdp: init at 0.9.1
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/services/networking/xrdp.nix150
-rw-r--r--nixos/tests/xrdp.nix45
-rw-r--r--pkgs/applications/networking/remote/xrdp/default.nix111
-rw-r--r--pkgs/top-level/all-packages.nix2
5 files changed, 309 insertions, 0 deletions
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 4ff069f48ab..59fd7325095 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -504,6 +504,7 @@
   ./services/networking/wpa_supplicant.nix
   ./services/networking/xinetd.nix
   ./services/networking/xl2tpd.nix
+  ./services/networking/xrdp.nix
   ./services/networking/zerobin.nix
   ./services/networking/zerotierone.nix
   ./services/networking/znc.nix
diff --git a/nixos/modules/services/networking/xrdp.nix b/nixos/modules/services/networking/xrdp.nix
new file mode 100644
index 00000000000..5923e436d64
--- /dev/null
+++ b/nixos/modules/services/networking/xrdp.nix
@@ -0,0 +1,150 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xrdp;
+  confDir = pkgs.runCommand "xrdp.conf" { } ''
+    mkdir $out
+
+    cp ${cfg.package}/etc/xrdp/{km-*,xrdp,sesman,xrdp_keyboard}.ini $out
+
+    ${cfg.package}/bin/xrdp-keygen xrdp $out/rsakeys.ini
+
+    cat > $out/startwm.sh <<EOF
+    #!/bin/sh
+    . /etc/profile
+    ${cfg.defaultWindowManager}
+    EOF
+    chmod +x $out/startwm.sh
+    
+    substituteInPlace $out/xrdp.ini \
+      --replace "certificate=" "certificate=${cfg.sslCert}" \
+      --replace "key_file=" "key_file=${cfg.sslKey}" \
+      --replace LogFile=xrdp.log LogFile=/dev/null \
+      --replace EnableSyslog=true EnableSyslog=false
+
+    substituteInPlace $out/sesman.ini \
+      --replace LogFile=xrdp-sesman.log LogFile=/dev/null \
+      --replace EnableSyslog=1 EnableSyslog=0
+  '';
+in
+{
+
+  ###### interface
+
+  options = {
+
+    services.xrdp = {
+
+      enable = mkEnableOption "Whether xrdp should be run on startup.";
+
+      package = mkOption {
+        type = types.package;
+        default = pkgs.xrdp;
+        defaultText = "pkgs.xrdp";
+        description = ''
+          The package to use for the xrdp daemon's binary.
+        '';
+      };
+
+      port = mkOption {
+        type = types.int;
+        default = 3389;
+        description = ''
+          Specifies on which port the xrdp daemon listens.
+        '';
+      };
+
+      sslKey = mkOption {
+        type = types.str;
+        default = "/etc/xrdp/key.pem";
+        example = "/path/to/your/key.pem";
+        description = ''
+          ssl private key path
+          A self-signed certificate will be generated if file not exists.
+        '';
+      };
+
+      sslCert = mkOption {
+        type = types.str;
+        default = "/etc/xrdp/cert.pem";
+        example = "/path/to/your/cert.pem";
+        description = ''
+          ssl certificate path
+          A self-signed certificate will be generated if file not exists.
+        '';
+      };
+
+      defaultWindowManager = mkOption {
+        type = types.str;
+        default = "xterm";
+        example = "xfce4-session";
+        description = ''
+          The script to run when user log in, usually a window manager, e.g. "icewm", "xfce4-session"
+          This is per-user overridable, if file ~/startwm.sh exists it will be used instead.
+        '';
+      };
+
+    };
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    systemd = {
+      services.xrdp = {
+        wantedBy = [ "multi-user.target" ];
+        after = [ "network.target" ];
+        description = "xrdp daemon";
+        requires = [ "xrdp-sesman.service" ];
+        preStart = ''
+          # prepare directory for unix sockets (the sockets will be owned by loggedinuser:xrdp)
+          mkdir -p /tmp/.xrdp || true
+          chown xrdp:xrdp /tmp/.xrdp
+          chmod 3777 /tmp/.xrdp
+
+          # generate a self-signed certificate
+          if [ ! -s ${cfg.sslCert} -o ! -s ${cfg.sslKey} ]; then
+            mkdir -p $(dirname ${cfg.sslCert}) || true
+            mkdir -p $(dirname ${cfg.sslKey}) || true
+            ${pkgs.openssl.bin}/bin/openssl req -x509 -newkey rsa:2048 -sha256 -nodes -days 365 \
+              -subj /C=US/ST=CA/L=Sunnyvale/O=xrdp/CN=www.xrdp.org \
+              -config ${cfg.package}/share/xrdp/openssl.conf \
+              -keyout ${cfg.sslKey} -out ${cfg.sslCert}
+            chown root:xrdp ${cfg.sslKey} ${cfg.sslCert}
+            chmod 440 ${cfg.sslKey} ${cfg.sslCert}
+          fi
+        '';
+        serviceConfig = {
+          User = "xrdp";
+          Group = "xrdp";
+          PermissionsStartOnly = true;
+          ExecStart = "${cfg.package}/bin/xrdp --nodaemon --port ${toString cfg.port} --config ${confDir}/xrdp.ini";
+        };
+      };
+
+      services.xrdp-sesman = {
+        wantedBy = [ "multi-user.target" ];
+        after = [ "network.target" ];
+        description = "xrdp session manager";
+        serviceConfig = {
+          ExecStart = "${cfg.package}/bin/xrdp-sesman --nodaemon --config ${confDir}/sesman.ini";
+        };
+      };
+
+    };
+
+    users.users.xrdp = {
+      description   = "xrdp daemon user";
+      isSystemUser  = true;
+      group         = "xrdp";
+    };
+    users.groups.xrdp = {};
+
+    security.pam.services.xrdp-sesman = { allowNullPassword = true; startSession = true; };
+  };
+
+}
diff --git a/nixos/tests/xrdp.nix b/nixos/tests/xrdp.nix
new file mode 100644
index 00000000000..c997e36cc44
--- /dev/null
+++ b/nixos/tests/xrdp.nix
@@ -0,0 +1,45 @@
+import ./make-test.nix ({ pkgs, ...} : {
+  name = "xrdp";
+  meta = with pkgs.stdenv.lib.maintainers; {
+    maintainers = [ volth ];
+  };
+
+  nodes = {
+    server = { lib, pkgs, ... }: {
+      imports = [ ./common/user-account.nix ];
+      services.xrdp.enable = true;
+      services.xrdp.defaultWindowManager = "${pkgs.xterm}/bin/xterm";
+      networking.firewall.allowedTCPPorts = [ 3389 ];
+    };
+
+    client = { lib, pkgs, ... }: {
+      imports = [ ./common/x11.nix ./common/user-account.nix ];
+      services.xserver.displayManager.auto.user = "alice";
+      environment.systemPackages = [ pkgs.freerdp ];
+      services.xrdp.enable = true;
+      services.xrdp.defaultWindowManager = "${pkgs.icewm}/bin/icewm";
+    };
+  };
+
+  testScript = { nodes, ... }: ''
+    startAll;
+
+    $client->waitForX;
+    $client->waitForFile("/home/alice/.Xauthority");
+    $client->succeed("xauth merge ~alice/.Xauthority");
+
+    $client->sleep(5);
+
+    $client->execute("xterm &");
+    $client->sleep(1);
+    $client->sendChars("xfreerdp /cert-tofu /w:640 /h:480 /v:127.0.0.1 /u:alice /p:foobar\n");
+    $client->sleep(5);
+    $client->screenshot("localrdp");
+
+    $client->execute("xterm &");
+    $client->sleep(1);
+    $client->sendChars("xfreerdp /cert-tofu /w:640 /h:480 /v:server /u:alice /p:foobar\n");
+    $client->sleep(5);
+    $client->screenshot("remoterdp");
+  '';
+})
diff --git a/pkgs/applications/networking/remote/xrdp/default.nix b/pkgs/applications/networking/remote/xrdp/default.nix
new file mode 100644
index 00000000000..647e6b6dcb9
--- /dev/null
+++ b/pkgs/applications/networking/remote/xrdp/default.nix
@@ -0,0 +1,111 @@
+{ stdenv, fetchFromGitHub, fetchpatch, pkgconfig, which, perl, autoconf, automake, libtool, openssl, systemd, pam, fuse, libjpeg, libopus, nasm, xorg }:
+
+let
+  xorgxrdp = stdenv.mkDerivation rec {
+    name = "xorgxrdp-${version}";
+    version = "0.2.0";
+  
+    src = fetchFromGitHub {
+      owner = "neutrinolabs";
+      repo = "xorgxrdp";
+      rev = "v${version}";
+      sha256 = "125mv7lm2ns1gdgz6zf647d3pay8if8506rclb3312wwa5qfd2hn";
+    };
+
+    nativeBuildInputs = [ pkgconfig autoconf automake which libtool nasm ];
+
+    buildInputs = [ xorg.xorgserver ];
+
+    postPatch = ''
+      # patch from Debian, allows to run xrdp daemon under unprivileged user
+      substituteInPlace module/rdpClientCon.c \
+        --replace 'g_sck_listen(dev->listen_sck);' 'g_sck_listen(dev->listen_sck); g_chmod_hex(dev->uds_data, 0x0660);'
+
+      substituteInPlace configure.ac \
+        --replace 'moduledir=`pkg-config xorg-server --variable=moduledir`' "moduledir=$out/lib/xorg/modules" \
+        --replace 'sysconfdir="/etc"' "sysconfdir=$out/etc"
+    '';
+
+    preConfigure = "./bootstrap";
+
+    configureFlags = [ "XRDP_CFLAGS=-I${xrdp.src}/common"  ];
+
+    enableParallelBuilding = true;
+  };
+
+  xrdp = stdenv.mkDerivation rec {
+    version = "0.9.1";
+    rev = "0920933"; # Fixes https://github.com/neutrinolabs/xrdp/issues/609; not a patch on top of the official repo because "xorgxrdp.configureFlags" above includes "xrdp.src" which must be fixed already
+    name = "xrdp-${version}.${rev}";
+  
+    src = fetchFromGitHub {
+      owner = "volth";
+      repo = "xrdp";
+      rev = rev;
+      fetchSubmodules = true;
+      sha256 = "0a000h82728vp0abvjk2m03nqqiw2lky7kqk41b70cyd3bp0vdnz";
+    };
+
+    nativeBuildInputs = [ pkgconfig autoconf automake which libtool nasm ];
+
+    buildInputs = [ openssl systemd pam fuse libjpeg libopus xorg.libX11 xorg.libXfixes xorg.libXrandr ];
+
+    postPatch = ''
+      substituteInPlace sesman/xauth.c --replace "xauth -q" "${xorg.xauth}/bin/xauth -q"
+      substituteInPlace common/file_loc.h --replace /etc/xrdp $out/etc/xrdp --replace /usr/local $out
+      substituteInPlace instfiles/xrdp.sh --replace /etc/xrdp $out/etc/xrdp --replace /usr/local $out
+    '';
+
+    preConfigure = ''
+      (cd librfxcodec && ./bootstrap && ./configure --prefix=$out --enable-static --disable-shared)
+      ./bootstrap
+    '';
+    dontDisableStatic = true;
+    configureFlags = [ "--with-systemdsystemunitdir=./do-not-install" "--enable-ipv6" "--enable-jpeg" "--enable-fuse" "--enable-rfxcodec" "--enable-opus" ];
+
+    installFlags = [ "DESTDIR=$(out)" "prefix=" ];
+
+    postInstall = ''
+      # remove generated keys as non-determenistic
+      rm $out/etc/xrdp/{rsakeys.ini,key.pem,cert.pem}
+
+      cp $src/keygen/openssl.conf $out/share/xrdp/openssl.conf
+
+      substituteInPlace $out/etc/xrdp/sesman.ini --replace /etc/xrdp/pulse $out/etc/xrdp/pulse
+
+      # remove all session types except Xorg (they are not supported by this setup)
+      ${perl}/bin/perl -i -ne 'print unless /\[(X11rdp|Xvnc|console|vnc-any|sesman-any|rdp-any|neutrinordp-any)\]/ .. /^$/' $out/etc/xrdp/xrdp.ini
+   
+      # remove all session types and then add Xorg
+      ${perl}/bin/perl -i -ne 'print unless /\[(X11rdp|Xvnc|Xorg)\]/ .. /^$/' $out/etc/xrdp/sesman.ini
+   
+      cat >> $out/etc/xrdp/sesman.ini <<EOF
+   
+      [Xorg]
+      param=${xorg.xorgserver}/bin/Xorg
+      param=-modulepath
+      param=${xorgxrdp}/lib/xorg/modules,${xorg.xorgserver}/lib/xorg/modules
+      ; the following two lines are needless after https://github.com/NixOS/nixpkgs/pull/21653
+      param=-xkbdir
+      param=${xorg.xkeyboardconfig}/share/X11/xkb
+      param=-config
+      param=${xorgxrdp}/etc/X11/xrdp/xorg.conf
+      param=-noreset
+      param=-nolisten
+      param=tcp
+      param=-logfile
+      param=.xorgxrdp.%s.log
+      EOF
+    '';
+
+    enableParallelBuilding = true;
+
+    meta = with stdenv.lib; {
+      description = "An open source RDP server";
+      homepage = https://github.com/neutrinolabs/xrdp;
+      license = licenses.asl20;
+      maintainers = [ maintainers.volth ];
+      platforms = platforms.linux;
+    };
+  };
+in xrdp
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 1a3c72c79cc..26db51fef84 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -13854,6 +13854,8 @@ with pkgs;
   xfontsel = callPackage ../applications/misc/xfontsel { };
   inherit (xorg) xlsfonts;
 
+  xrdp = callPackage ../applications/networking/remote/xrdp { };
+
   freerdp = callPackage ../applications/networking/remote/freerdp {
     inherit libpulseaudio;
     inherit (gst_all_1) gstreamer gst-plugins-base gst-plugins-good;