diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index dcefd1c51a7..fcbac4c7f54 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -217,6 +217,7 @@
ihaskell = 189;
i2p = 190;
lambdabot = 191;
+ asterisk = 192;
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
@@ -411,6 +412,7 @@
ihaskell = 189;
i2p = 190;
lambdabot = 191;
+ #asterisk = 192; # unused
# When adding a gid, make sure it doesn't match an existing
# uid. Users and groups with the same name should have equal
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index a1bb9b89f38..08b232272ff 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -242,6 +242,7 @@
./services/network-filesystems/yandex-disk.nix
./services/networking/aiccu.nix
./services/networking/amuled.nix
+ ./services/networking/asterisk.nix
./services/networking/atftpd.nix
./services/networking/avahi-daemon.nix
./services/networking/bind.nix
diff --git a/nixos/modules/services/networking/asterisk.nix b/nixos/modules/services/networking/asterisk.nix
new file mode 100644
index 00000000000..b079cb22730
--- /dev/null
+++ b/nixos/modules/services/networking/asterisk.nix
@@ -0,0 +1,223 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.asterisk;
+
+ asteriskUser = "asterisk";
+
+ varlibdir = "/var/lib/asterisk";
+ spooldir = "/var/spool/asterisk";
+ logdir = "/var/log/asterisk";
+
+ asteriskEtc = pkgs.stdenv.mkDerivation
+ ((mapAttrs' (name: value: nameValuePair
+ # Fudge the names to make bash happy
+ ((replaceChars ["."] ["_"] name) + "_")
+ (value)
+ ) cfg.confFiles) //
+ {
+ confFilesString = concatStringsSep " " (
+ attrNames cfg.confFiles
+ );
+
+ name = "asterisk.etc";
+
+ # Default asterisk.conf file
+ # (Notice that astetcdir will be set to the path of this derivation)
+ asteriskConf = ''
+ [directories]
+ astetcdir => @out@
+ astmoddir => ${pkgs.asterisk}/lib/asterisk/modules
+ astvarlibdir => /var/lib/asterisk
+ astdbdir => /var/lib/asterisk
+ astkeydir => /var/lib/asterisk
+ astdatadir => /var/lib/asterisk
+ astagidir => /var/lib/asterisk/agi-bin
+ astspooldir => /var/spool/asterisk
+ astrundir => /var/run/asterisk
+ astlogdir => /var/log/asterisk
+ astsbindir => ${pkgs.asterisk}/sbin
+ '';
+ extraConf = cfg.extraConfig;
+
+ # Loading all modules by default is considered sensible by the authors of
+ # "Asterisk: The Definitive Guide". Secure sites will likely want to
+ # specify their own "modules.conf" in the confFiles option.
+ modulesConf = ''
+ [modules]
+ autoload=yes
+ '';
+
+ # Use syslog for logging so logs can be viewed with journalctl
+ loggerConf = ''
+ [general]
+
+ [logfiles]
+ syslog.local0 => notice,warning,error
+ '';
+
+ buildCommand = ''
+ mkdir -p "$out"
+
+ # Create asterisk.conf, pointing astetcdir to the path of this derivation
+ echo "$asteriskConf" | sed "s|@out@|$out|g" > "$out"/asterisk.conf
+ echo "$extraConf" >> "$out"/asterisk.conf
+
+ echo "$modulesConf" > "$out"/modules.conf
+
+ echo "$loggerConf" > "$out"/logger.conf
+
+ # Config files specified in confFiles option override all other files
+ for i in $confFilesString; do
+ conf=$(echo "$i"_ | sed 's/\./_/g')
+ echo "''${!conf}" > "$out"/"$i"
+ done
+ '';
+ });
+in
+
+{
+ options = {
+ services.asterisk = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable the Asterisk PBX server.
+ '';
+ };
+
+ extraConfig = mkOption {
+ default = "";
+ type = types.lines;
+ example = ''
+ [options]
+ verbose=3
+ debug=3
+ '';
+ description = ''
+ Extra configuration options appended to the default
+ asterisk.conf file.
+ '';
+ };
+
+ confFiles = mkOption {
+ default = {};
+ type = types.attrsOf types.str;
+ example = literalExample
+ ''
+ {
+ "extensions.conf" = '''
+ [tests]
+ ; Dial 100 for "hello, world"
+ exten => 100,1,Answer()
+ same => n,Wait(1)
+ same => n,Playback(hello-world)
+ same => n,Hangup()
+
+ [softphones]
+ include => tests
+
+ [unauthorized]
+ ''';
+ "sip.conf" = '''
+ [general]
+ allowguest=no ; Require authentication
+ context=unauthorized ; Send unauthorized users to /dev/null
+ srvlookup=no ; Don't do DNS lookup
+ udpbindaddr=0.0.0.0 ; Listen on all interfaces
+ nat=force_rport,comedia ; Assume device is behind NAT
+
+ [softphone](!)
+ type=friend ; Match on username first, IP second
+ context=softphones ; Send to softphones context in
+ ; extensions.conf file
+ host=dynamic ; Device will register with asterisk
+ disallow=all ; Manually specify codecs to allow
+ allow=g722
+ allow=ulaw
+ allow=alaw
+
+ [myphone](softphone)
+ secret=GhoshevFew ; Change this password!
+ ''';
+ "logger.conf" = '''
+ [general]
+
+ [logfiles]
+ ; Add debug output to log
+ syslog.local0 => notice,warning,error,debug
+ ''';
+ }
+ '';
+ description = ''
+ Sets the content of config files (typically ending with
+ .conf) in the Asterisk configuration directory.
+
+ Note that if you want to change asterisk.conf, it
+ is preferable to use the
+ option over this option. If "asterisk.conf" is
+ specified with the option (not recommended),
+ you must be prepared to set your own astetcdir
+ path.
+
+ See
+
+ for more examples of what is possible here.
+ '';
+ };
+
+ extraArguments = mkOption {
+ default = [];
+ type = types.listOf types.str;
+ example =
+ [ "-vvvddd" "-e" "1024" ];
+ description = ''
+ Additional command line arguments to pass to Asterisk.
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ users.extraUsers = singleton
+ { name = asteriskUser;
+ uid = config.ids.uids.asterisk;
+ description = "Asterisk daemon user";
+ home = varlibdir;
+ };
+
+ systemd.services.asterisk = {
+ description = ''
+ Asterisk PBX server
+ '';
+
+ wantedBy = [ "multi-user.target" ];
+
+ preStart = ''
+ # Copy skeleton directory tree to /var
+ for d in '${varlibdir}' '${spooldir}' '${logdir}'; do
+ # TODO: Make exceptions for /var directories that likely should be updated
+ if [ ! -e "$d" ]; then
+ cp --recursive ${pkgs.asterisk}/"$d" "$d"
+ chown --recursive ${asteriskUser} "$d"
+ find "$d" -type d | xargs chmod 0755
+ fi
+ done
+ '';
+
+ serviceConfig = {
+ ExecStart =
+ let
+ # FIXME: This doesn't account for arguments with spaces
+ argString = concatStringsSep " " cfg.extraArguments;
+ in
+ "${pkgs.asterisk}/bin/asterisk -U ${asteriskUser} -C ${asteriskEtc}/asterisk.conf ${argString} -F";
+ Type = "forking";
+ PIDFile = "/var/run/asterisk/asterisk.pid";
+ };
+ };
+ };
+}
diff --git a/pkgs/servers/asterisk/default.nix b/pkgs/servers/asterisk/default.nix
new file mode 100644
index 00000000000..c37292d385f
--- /dev/null
+++ b/pkgs/servers/asterisk/default.nix
@@ -0,0 +1,61 @@
+{ stdenv, fetchurl, fetchgit, jansson, libxml2, libxslt, ncurses, openssl, sqlite, utillinux }:
+
+stdenv.mkDerivation rec {
+ name = "asterisk-${version}";
+ version = "13.3.2";
+
+ src = fetchurl {
+ url = "http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-${version}.tar.gz";
+ sha256 = "19dafvy6ch4v8949bjim64fff456k78156m30dy2yvhm94m5k1zz";
+ };
+
+ # Note that these sounds are included with the release tarball. They are
+ # provided here verbatim for the convenience of anyone wanting to build
+ # Asterisk from other sources.
+ coreSounds = fetchurl {
+ url = http://downloads.asterisk.org/pub/telephony/sounds/releases/asterisk-core-sounds-en-gsm-1.4.26.tar.gz;
+ sha256 = "2300e3ed1d2ded6808a30a6ba71191e7784710613a5431afebbd0162eb4d5d73";
+ };
+ mohSounds = fetchurl {
+ url = http://downloads.asterisk.org/pub/telephony/sounds/releases/asterisk-moh-opsound-wav-2.03.tar.gz;
+ sha256 = "449fb810d16502c3052fedf02f7e77b36206ac5a145f3dacf4177843a2fcb538";
+ };
+ # TODO: Sounds for other languages could be added here
+
+ buildInputs = [ jansson libxml2 libxslt ncurses openssl sqlite utillinux ];
+
+ patches = [
+ # Disable downloading of sound files (we will fetch them
+ # ourselves if needed).
+ ./disable-download.patch
+
+ # We want the Makefile to install the default /var skeleton
+ # under ${out}/var but we also want to use /var at runtime.
+ # This patch changes the runtime behavior to look for state
+ # directories in /var rather than ${out}/var.
+ ./runtime-vardirs.patch
+ ];
+
+ # Use the following preConfigure section when building Asterisk from sources
+ # other than the release tarball.
+# preConfigure = ''
+# ln -s ${coreSounds} sounds/asterisk-core-sounds-en-gsm-1.4.26.tar.gz
+# ln -s ${mohSounds} sounds/asterisk-moh-opsound-wav-2.03.tar.gz
+# '';
+
+ # The default libdir is $PREFIX/usr/lib, which causes problems when paths
+ # compiled into Asterisk expect ${out}/usr/lib rather than ${out}/lib.
+ configureFlags = "--libdir=\${out}/lib";
+
+ postInstall = ''
+ # Install sample configuration files for this version of Asterisk
+ make samples
+ '';
+
+ meta = with stdenv.lib; {
+ description = "Software implementation of a telephone private branch exchange (PBX)";
+ homepage = http://www.asterisk.org/;
+ license = licenses.gpl2;
+ maintainers = with maintainers; [ auntie ];
+ };
+}
diff --git a/pkgs/servers/asterisk/disable-download.patch b/pkgs/servers/asterisk/disable-download.patch
new file mode 100644
index 00000000000..8b15ecdfaaa
--- /dev/null
+++ b/pkgs/servers/asterisk/disable-download.patch
@@ -0,0 +1,12 @@
+diff -ruN asterisk-13.2.0/sounds/Makefile asterisk-13.2.0-patched/sounds/Makefile
+--- asterisk-13.2.0/sounds/Makefile 2014-09-09 14:01:11.000000000 -0600
++++ asterisk-13.2.0-patched/sounds/Makefile 2015-03-31 16:12:00.549133670 -0600
+@@ -89,7 +89,7 @@
+ ) && touch "$(1)$(if $(3),/$(3),)/$$@"; \
+ fi
+
+-asterisk-$(2)$(if $(3),-$(3),)-%.tar.gz: have_download
++asterisk-$(2)$(if $(3),-$(3),)-%.tar.gz:
+ ifneq ($(SOUNDS_CACHE_DIR),)
+ $(CMD_PREFIX) \
+ if test ! -f "$(1)$(if $(3),/$(3),)/.$$(subst .tar.gz,,$$@)"; then \
diff --git a/pkgs/servers/asterisk/runtime-vardirs.patch b/pkgs/servers/asterisk/runtime-vardirs.patch
new file mode 100644
index 00000000000..dfc00186d13
--- /dev/null
+++ b/pkgs/servers/asterisk/runtime-vardirs.patch
@@ -0,0 +1,50 @@
+diff -rupN asterisk-13.3.2/build_tools/make_defaults_h asterisk-13.3.2-patched/build_tools/make_defaults_h
+--- asterisk-13.3.2/build_tools/make_defaults_h 2012-01-30 14:21:16.000000000 -0700
++++ asterisk-13.3.2-patched/build_tools/make_defaults_h 2015-04-15 19:07:46.760351155 -0600
+@@ -1,4 +1,13 @@
+ #!/bin/sh
++
++ASTLOGDIR=/var/log/asterisk
++ASTVARRUNDIR=/var/run/asterisk
++ASTVARLIBDIR=/var/lib/asterisk
++ASTDBDIR=${ASTVARLIBDIR}
++ASTDATADIR=${ASTVARLIBDIR}
++AGI_DIR=${ASTDATADIR}/agi-bin
++ASTSPOOLDIR=/var/spool/asterisk
++
+ cat << END
+ /*
+ * defaults.h
+@@ -9,21 +18,21 @@ cat << END
+
+ #define DEFAULT_CONFIG_DIR "${INSTALL_PATH}${ASTETCDIR}"
+ #define DEFAULT_MODULE_DIR "${INSTALL_PATH}${ASTMODDIR}"
+-#define DEFAULT_AGI_DIR "${INSTALL_PATH}${AGI_DIR}"
+-#define DEFAULT_LOG_DIR "${INSTALL_PATH}${ASTLOGDIR}"
++#define DEFAULT_AGI_DIR "${AGI_DIR}"
++#define DEFAULT_LOG_DIR "${ASTLOGDIR}"
+
+-#define DEFAULT_RUN_DIR "${INSTALL_PATH}${ASTVARRUNDIR}"
+-#define DEFAULT_SOCKET "${INSTALL_PATH}${ASTVARRUNDIR}/asterisk.ctl"
+-#define DEFAULT_PID "${INSTALL_PATH}${ASTVARRUNDIR}/asterisk.pid"
++#define DEFAULT_RUN_DIR "${ASTVARRUNDIR}"
++#define DEFAULT_SOCKET "${ASTVARRUNDIR}/asterisk.ctl"
++#define DEFAULT_PID "${ASTVARRUNDIR}/asterisk.pid"
+
+-#define DEFAULT_VAR_DIR "${INSTALL_PATH}${ASTVARLIBDIR}"
+-#define DEFAULT_DB "${INSTALL_PATH}${ASTDBDIR}/astdb"
++#define DEFAULT_VAR_DIR "${ASTVARLIBDIR}"
++#define DEFAULT_DB "${ASTDBDIR}/astdb"
+
+-#define DEFAULT_DATA_DIR "${INSTALL_PATH}${ASTDATADIR}"
+-#define DEFAULT_KEY_DIR "${INSTALL_PATH}${ASTDATADIR}/keys"
++#define DEFAULT_DATA_DIR "${ASTDATADIR}"
++#define DEFAULT_KEY_DIR "${ASTDATADIR}/keys"
+
+-#define DEFAULT_SPOOL_DIR "${INSTALL_PATH}${ASTSPOOLDIR}"
+-#define DEFAULT_TMP_DIR "${INSTALL_PATH}${ASTSPOOLDIR}/tmp"
++#define DEFAULT_SPOOL_DIR "${ASTSPOOLDIR}"
++#define DEFAULT_TMP_DIR "${ASTSPOOLDIR}/tmp"
+
+ #define DEFAULT_SBIN_DIR "${INSTALL_PATH}${ASTSBINDIR}"
+ END
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index af2507320c0..dd09411733a 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -8250,6 +8250,8 @@ let
apcupsd = callPackage ../servers/apcupsd { };
+ asterisk = callPackage ../servers/asterisk { };
+
sabnzbd = callPackage ../servers/sabnzbd { };
bind = callPackage ../servers/dns/bind { };