about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--nixos/modules/misc/ids.nix4
-rwxr-xr-xnixos/modules/module-list.nix1
-rw-r--r--nixos/modules/services/networking/prosody.nix275
-rw-r--r--pkgs/servers/xmpp/prosody/default.nix45
-rw-r--r--pkgs/top-level/all-packages.nix7
-rw-r--r--pkgs/top-level/lua-packages.nix55
6 files changed, 384 insertions, 3 deletions
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index fa51f831481a..8472821f7867 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -155,6 +155,8 @@
       consul = 145;
       mailpile = 146;
 
+      prosody = 148;
+
       # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
 
       nixbld = 30000; # start of range of uids
@@ -276,6 +278,8 @@
       uhub = 142;
       mailpile = 146;
 
+      prosody = 148;
+
       # When adding a gid, make sure it doesn't match an existing uid. And don't use gids above 399!
 
       users = 100;
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 3db44a4d8de5..ba30c61bb8dc 100755
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -250,6 +250,7 @@
   ./services/networking/polipo.nix
   ./services/networking/prayer.nix
   ./services/networking/privoxy.nix
+  ./services/networking/prosody.nix
   ./services/networking/quassel.nix
   ./services/networking/radicale.nix
   ./services/networking/radvd.nix
diff --git a/nixos/modules/services/networking/prosody.nix b/nixos/modules/services/networking/prosody.nix
new file mode 100644
index 000000000000..51089d00244c
--- /dev/null
+++ b/nixos/modules/services/networking/prosody.nix
@@ -0,0 +1,275 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.prosody;
+
+  sslOpts = { ... }: {
+
+    options = {
+
+      # TODO: require attribute
+      key = mkOption {
+        type = types.str;
+        description = "Path to the key file";
+      };
+
+      # TODO: require attribute
+      cert = mkOption {
+        type = types.str;
+        description = "Path to the certificate file";
+      };
+    };
+  };
+
+  moduleOpts = {
+
+    roster = mkOption {
+      default = true;
+      description = "Allow users to have a roster";
+    };
+
+    saslauth = mkOption {
+      default = true;
+      description = "Authentication for clients and servers. Recommended if you want to log in.";
+    };
+
+    tls = mkOption {
+      default = true;
+      description = "Add support for secure TLS on c2s/s2s connections";
+    };
+
+    dialback = mkOption {
+      default = true;
+      description = "s2s dialback support";
+    };
+
+    disco = mkOption {
+      default = true;
+      description = "Service discovery";
+    };
+
+    legacyauth = mkOption {
+      default = true;
+      description = "Legacy authentication. Only used by some old clients and bots";
+    };
+
+    version = mkOption {
+      default = true;
+      description = "Replies to server version requests";
+    };
+
+    uptime = mkOption {
+      default = true;
+      description = "Report how long server has been running";
+    };
+
+    time = mkOption {
+      default = true;
+      description = "Let others know the time here on this server";
+    };
+
+    ping = mkOption {
+      default = true;
+      description = "Replies to XMPP pings with pongs";
+    };
+
+    console = mkOption {
+      default = false;
+      description = "telnet to port 5582";
+    };
+
+    bosh = mkOption {
+      default = false;
+      description = "Enable BOSH clients, aka 'Jabber over HTTP'";
+    };
+
+    httpserver = mkOption {
+      default = false;
+      description = "Serve static files from a directory over HTTP";
+    };
+
+  };
+
+  createSSLOptsStr = o:
+    if o ? key && o ? cert then
+      ''ssl = { key = "${o.key}"; certificate = "${o.cert}"; };''
+    else "";
+
+  vHostOpts = { ... }: {
+
+    options = {
+
+      # TODO: require attribute
+      domain = mkOption {
+        type = types.str;
+        description = "Domain name";
+      };
+
+      enabled = mkOption {
+        default = false;
+        description = "Whether to enable the virtual host";
+      };
+
+      ssl = mkOption {
+        description = "Paths to SSL files";
+        default = null;
+        options = [ sslOpts ];
+      };
+
+      extraConfig = mkOption {
+        default = '''';
+        description = "Additional virtual host specific configuration";
+      };
+
+    };
+
+  };
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.prosody = {
+
+      enable = mkOption {
+        default = false;
+        description = "Whether to enable the prosody server";
+      };
+
+      allowRegistration = mkOption {
+        default = false;
+        description = "Allow account creation";
+      };
+
+      modules = moduleOpts;
+
+      extraModules = mkOption {
+        description = "Enable custom modules";
+        default = [];
+      };
+
+      virtualHosts = mkOption {
+
+        description = "Define the virtual hosts";
+
+        type = types.loaOf types.optionSet;
+
+        example = {
+          myhost = {
+            domain = "my-xmpp-example-host.org";
+            enabled = true;
+          };
+        };
+
+        default = {
+          localhost = {
+            domain = "localhost";
+            enabled = true;
+          };
+        };
+
+        options = [ vHostOpts ];
+      };
+
+      ssl = mkOption {
+        description = "Paths to SSL files";
+        default = null;
+        options = [ sslOpts ];
+      };
+
+      admins = mkOption {
+        description = "List of administrators of the current host";
+        example = [ "admin1@example.com" "admin2@example.com" ];
+        default = [];
+      };
+
+      extraConfig = mkOption {
+        default = '''';
+        description = "Additional prosody configuration";
+      };
+
+    };
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    environment.systemPackages = [ pkgs.prosody ];
+
+    environment.etc."prosody/prosody.cfg.lua".text = ''
+
+      pidfile = "/var/lib/prosody/prosody.pid"
+
+
+      log = "*syslog"
+
+      data_path = "/var/lib/prosody"
+
+      allow_registration = ${ if cfg.allowRegistration then "true" else "false" };
+
+      ${ optionalString cfg.modules.console "console_enabled = true;" }
+
+      ${ optionalString  (cfg.ssl != null) (createSSLOptsStr cfg.ssl) }
+
+      admins = { ${lib.concatStringsSep ", " (map (n: "\"${n}\"") cfg.admins) } };
+
+      modules_enabled = {
+
+        ${ lib.concatStringsSep "\n\ \ " (lib.mapAttrsToList
+          (name: val: optionalString val ''"${name}";'')
+        cfg.modules) }
+
+        ${ optionalString cfg.allowRegistration "\"register\"\;" }
+
+        ${ lib.concatStringsSep "\n" (map (x: "\"${x}\";") cfg.extraModules)}
+
+        "posix";
+      };
+
+      ${ cfg.extraConfig }
+
+      ${ lib.concatStringsSep "\n" (lib.mapAttrsToList (n: v: ''
+        VirtualHost "${v.domain}"
+          enabled = ${if v.enabled then "true" else "false"};
+          ${ optionalString (v.ssl != null) (createSSLOptsStr v.ssl) }
+          ${ v.extraConfig }
+        '') cfg.virtualHosts) }
+    '';
+
+    users.extraUsers.prosody = {
+      uid = config.ids.uids.prosody;
+      description = "Prosody user";
+      createHome = true;
+      group = "prosody";
+      home = "/var/lib/prosody";
+    };
+
+    users.extraGroups.prosody = {
+      gid = config.ids.gids.prosody;
+    };
+
+    systemd.services.prosody = {
+
+      description = "Prosody XMPP server";
+      after = [ "network.target" ];
+      wantedBy = [ "multi-user.target" ];
+      serviceConfig = {
+        User = "prosody";
+        PIDFile = "/var/lib/prosody/prosody.pid";
+        ExecStart = "${pkgs.prosody}/bin/prosodyctl start";
+      };
+
+    };
+
+  };
+
+}
diff --git a/pkgs/servers/xmpp/prosody/default.nix b/pkgs/servers/xmpp/prosody/default.nix
new file mode 100644
index 000000000000..4bd1b594c268
--- /dev/null
+++ b/pkgs/servers/xmpp/prosody/default.nix
@@ -0,0 +1,45 @@
+{ stdenv, fetchurl, lua5, luasocket, luasec, luaexpat, luafilesystem, libidn, openssl, makeWrapper }:
+
+let
+  libs        = [ luasocket luasec luaexpat luafilesystem ];
+  getPath     = lib : type : "${lib}/lib/lua/${lua5.luaversion}/?.${type};${lib}/share/lua/${lua5.luaversion}/?.${type}";
+  getLuaPath  = lib : getPath lib "lua";
+  getLuaCPath = lib : getPath lib "so";
+  luaPath     = stdenv.lib.concatStringsSep ";" (map getLuaPath  libs);
+  luaCPath    = stdenv.lib.concatStringsSep ";" (map getLuaCPath libs);
+in
+
+stdenv.mkDerivation rec {
+  version = "0.9.4";
+  name = "prosody-${version}";
+  src = fetchurl {
+    url = "http://prosody.im/downloads/source/${name}.tar.gz";
+    sha256 = "be87cf31901a25477869b4ebd52e298f63a5effacae526911a0be876cc82e1c6";
+  };
+
+  buildInputs = [ lua5 luasocket luasec luaexpat libidn openssl makeWrapper ];
+
+  configureFlags = [
+    "--ostype=linux"
+    "--with-lua-include=${lua5}/include"
+    "--with-lua=${lua5}"
+  ];
+
+  postInstall = ''
+      wrapProgram $out/bin/prosody \
+        --set LUA_PATH '"${luaPath};"' \
+        --set LUA_CPATH '"${luaCPath};"'
+      wrapProgram $out/bin/prosodyctl \
+        --add-flags '--config "/etc/prosody/prosody.cfg.lua"' \
+        --set LUA_PATH '"${luaPath};"' \
+        --set LUA_CPATH '"${luaCPath};"'
+    '';
+
+  meta = {
+    description = "Open-source XMPP application server written in Lua";
+    license = stdenv.lib.licenses.mit;
+    homepage = http://www.prosody.im;
+    platforms = stdenv.lib.platforms.linux;
+    maintainers = [ stdenv.lib.maintainers.flosse ];
+  };
+}
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index f8382928e0b9..593156215d29 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -3771,7 +3771,6 @@ let
   lua = lua5;
 
   lua51Packages = recurseIntoAttrs (callPackage ./lua-packages.nix { lua = lua5_1; });
-
   lua52Packages = recurseIntoAttrs (callPackage ./lua-packages.nix { lua = lua5_2; });
 
   luaPackages = lua52Packages;
@@ -7137,6 +7136,12 @@ let
     erlang = erlangR16;
   };
 
+  prosody = recurseIntoAttrs (
+    callPackage ../servers/xmpp/prosody {
+      lua5 = lua5_1;
+      inherit (lua51Packages) luasocket luasec luaexpat luafilesystem;
+  });
+
   elasticmq = callPackage ../servers/elasticmq { };
 
   etcdctl = callPackage ../development/tools/etcdctl { };
diff --git a/pkgs/top-level/lua-packages.nix b/pkgs/top-level/lua-packages.nix
index 8a44a997c071..a69009a34fe6 100644
--- a/pkgs/top-level/lua-packages.nix
+++ b/pkgs/top-level/lua-packages.nix
@@ -7,7 +7,7 @@
 
 { fetchurl, stdenv, lua, callPackage, unzip, zziplib,
 pcre, oniguruma, gnulib, tre, glibc,
-sqlite }:
+sqlite, openssl, expat }:
 
 let
  isLua51 = lua.luaversion == "5.1";
@@ -23,7 +23,32 @@ let
     inherit lua;
   };
 
-  luafilesystem = buildLuaPackage {
+  luaexpat = buildLuaPackage rec {
+    version = "1.3.0";
+    name = "expat-${version}";
+    isLibrary = true;
+    src = fetchurl {
+      url = "https://matthewwild.co.uk/projects/luaexpat/luaexpat-${version}.tar.gz";
+      sha256 = "1hvxqngn0wf5642i5p3vcyhg3pmp102k63s9ry4jqyyqc1wkjq6h";
+    };
+
+    buildInputs = [ expat ];
+
+    preBuild = ''
+      makeFlagsArray=(
+        LUA_LDIR="$out/share/lua/${lua.luaversion}"
+        LUA_INC="-I${lua}/include" LUA_CDIR="$out/lib/lua/${lua.luaversion}"
+        EXPAT_INC="-I${expat}/include");
+    '';
+
+    meta = {
+      homepage = "http://matthewwild.co.uk/projects/luaexpat";
+      hydraPlatforms = stdenv.lib.platforms.linux;
+      maintainers = [ stdenv.lib.maintainers.flosse ];
+    };
+  };
+
+  luafilesystem = buildLuaPackage rec {
     name = "filesystem-1.6.2";
     src = fetchurl {
       url = "https://github.com/keplerproject/luafilesystem/archive/v1_6_2.tar.gz";
@@ -36,6 +61,32 @@ let
     };
   };
 
+  luasec = buildLuaPackage rec {
+    version = "0.5";
+    name = "sec-${version}";
+    src = fetchurl {
+      url = "https://github.com/brunoos/luasec/archive/luasec-${version}.tar.gz";
+      sha256 = "08rm12cr1gjdnbv2jpk7xykby9l292qmz2v0dfdlgb4jfj7mk034";
+    };
+
+    buildInputs = [ openssl ];
+
+    preBuild = ''
+      makeFlagsArray=(
+        linux
+        LUAPATH="$out/lib/lua/${lua.luaversion}"
+        LUACPATH="$out/lib/lua/${lua.luaversion}"
+        INC_PATH="-I${lua}/include"
+        LIB_PATH="-L$out/lib");
+    '';
+
+    meta = {
+      homepage = "https://github.com/brunoos/luasec";
+      hydraPlatforms = stdenv.lib.platforms.linux;
+      maintainers = [ stdenv.lib.maintainers.flosse ];
+    };
+  };
+
   luasocket = buildLuaPackage rec {
     name = "socket-${version}";
     version = "2.0.2";