summary refs log tree commit diff
path: root/pkgs/tools/networking/networkmanager
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/tools/networking/networkmanager')
-rw-r--r--pkgs/tools/networking/networkmanager/0.9.8/default.nix64
-rw-r--r--pkgs/tools/networking/networkmanager/0.9.8/libnl-3.2.25.patch61
-rw-r--r--pkgs/tools/networking/networkmanager/0.9.8/nixos-purity.patch77
-rw-r--r--pkgs/tools/networking/networkmanager/applet/default.nix89
-rw-r--r--pkgs/tools/networking/networkmanager/default.nix113
-rw-r--r--pkgs/tools/networking/networkmanager/dmenu/default.nix40
-rw-r--r--pkgs/tools/networking/networkmanager/fix-install-paths.patch16
-rw-r--r--pkgs/tools/networking/networkmanager/fix-paths.patch92
-rw-r--r--pkgs/tools/networking/networkmanager/fortisslvpn/default.nix84
-rw-r--r--pkgs/tools/networking/networkmanager/fortisslvpn/fix-paths.patch11
-rw-r--r--pkgs/tools/networking/networkmanager/iodine/default.nix58
-rw-r--r--pkgs/tools/networking/networkmanager/iodine/fix-paths.patch11
-rw-r--r--pkgs/tools/networking/networkmanager/l2tp/default.nix51
-rw-r--r--pkgs/tools/networking/networkmanager/l2tp/fix-paths.patch22
-rw-r--r--pkgs/tools/networking/networkmanager/libnma/default.nix91
-rw-r--r--pkgs/tools/networking/networkmanager/libnma/hardcode-gsettings.patch26
-rw-r--r--pkgs/tools/networking/networkmanager/openconnect/default.nix81
-rw-r--r--pkgs/tools/networking/networkmanager/openconnect/fix-paths.patch20
-rw-r--r--pkgs/tools/networking/networkmanager/openvpn/default.nix46
-rw-r--r--pkgs/tools/networking/networkmanager/openvpn/fix-paths.patch34
-rw-r--r--pkgs/tools/networking/networkmanager/sstp/default.nix64
-rw-r--r--pkgs/tools/networking/networkmanager/strongswan/default.nix34
-rw-r--r--pkgs/tools/networking/networkmanager/tray.nix31
-rw-r--r--pkgs/tools/networking/networkmanager/vpnc/default.nix50
-rw-r--r--pkgs/tools/networking/networkmanager/vpnc/fix-paths.patch31
25 files changed, 1297 insertions, 0 deletions
diff --git a/pkgs/tools/networking/networkmanager/0.9.8/default.nix b/pkgs/tools/networking/networkmanager/0.9.8/default.nix
new file mode 100644
index 00000000000..757c886fdf3
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/0.9.8/default.nix
@@ -0,0 +1,64 @@
+{ lib, stdenv, fetchurl, intltool, pkg-config, dbus-glib
+, udev, libnl, libuuid, gnutls, dhcp
+, libgcrypt, perl, libgudev, avahi, ppp, kmod }:
+
+stdenv.mkDerivation rec {
+  pname = "networkmanager";
+  version = "0.9.8.10";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/NetworkManager/0.9/NetworkManager-${version}.tar.xz";
+    sha256 = "0wn9qh8r56r8l19dqr68pdl1rv3zg1dv47rfy6fqa91q7li2fk86";
+  };
+
+  preConfigure = ''
+    substituteInPlace tools/glib-mkenums --replace /usr/bin/perl ${perl}/bin/perl
+    substituteInPlace src/nm-device.c \
+      --replace @avahi@ ${avahi} \
+      --replace @kmod@ ${kmod}
+    substituteInPlace src/ppp-manager/nm-ppp-manager.c \
+      --replace @ppp@ ${ppp} \
+      --replace @kmod@ ${kmod}
+  '';
+
+  # Right now we hardcode quite a few paths at build time. Probably we should
+  # patch networkmanager to allow passing these path in config file. This will
+  # remove unneeded build-time dependencies.
+  configureFlags = [
+    "--with-distro=exherbo"
+    "--with-dhclient=${dhcp}/sbin/dhclient"
+    "--with-dhcpcd=no"
+    "--with-iptables=no"
+    "--with-udev-dir=\${out}/lib/udev"
+    "--with-resolvconf=no"
+    "--sysconfdir=/etc" "--localstatedir=/var"
+    "--with-dbus-sys-dir=\${out}/etc/dbus-1/system.d"
+    "--with-crypto=gnutls" "--disable-more-warnings"
+    "--with-systemdsystemunitdir=$(out)/etc/systemd/system"
+    "--with-kernel-firmware-dir=/run/current-system/firmware"
+    "--disable-ppp"
+  ];
+
+  buildInputs = [ udev libnl libuuid gnutls libgcrypt libgudev ];
+
+  propagatedBuildInputs = [ dbus-glib ];
+
+  nativeBuildInputs = [ intltool pkg-config ];
+
+  patches =
+    [ ./libnl-3.2.25.patch
+      ./nixos-purity.patch
+    ];
+
+  preInstall =
+    ''
+      installFlagsArray=( "sysconfdir=$out/etc" "localstatedir=$out/var" )
+    '';
+
+  meta = with lib; {
+    homepage = "http://projects.gnome.org/NetworkManager/";
+    description = "Network configuration and management tool";
+    license = licenses.gpl2Plus;
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/tools/networking/networkmanager/0.9.8/libnl-3.2.25.patch b/pkgs/tools/networking/networkmanager/0.9.8/libnl-3.2.25.patch
new file mode 100644
index 00000000000..17c2966b706
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/0.9.8/libnl-3.2.25.patch
@@ -0,0 +1,61 @@
+diff --git a/src/nm-netlink-monitor.c b/src/nm-netlink-monitor.c
+index ba8053e..5ac39d3 100644
+--- a/src/nm-netlink-monitor.c
++++ b/src/nm-netlink-monitor.c
+@@ -177,40 +177,15 @@ link_msg_handler (struct nl_object *obj, void *arg)
+ static int
+ event_msg_recv (struct nl_msg *msg, void *arg)
+ {
+-	struct nl_sock *nlh = arg;
+-	struct nlmsghdr *hdr = nlmsg_hdr (msg);
+ 	struct ucred *creds = nlmsg_get_creds (msg);
+-	const struct sockaddr_nl *snl;
+-	guint32 local_port;
+-	gboolean accept_msg = FALSE;
+-
+-	/* Only messages sent from the kernel */
+-	if (!creds || creds->uid != 0) {
+-		nm_log_dbg (LOGD_HW, "ignoring netlink message from UID %d",
+-		            creds ? creds->uid : -1);
+-		return NL_SKIP;
+-	}
+-
+-	snl = nlmsg_get_src (msg);
+-	g_assert (snl);
+-
+-	/* Accept any messages from the kernel */
+-	if (hdr->nlmsg_pid == 0 || snl->nl_pid == 0)
+-		accept_msg = TRUE;
+ 
+-	/* And any multicast message directed to our netlink PID, since multicast
+-	 * currently requires CAP_ADMIN to use.
+-	 */
+-	local_port = nl_socket_get_local_port (nlh);
+-	if ((hdr->nlmsg_pid == local_port) && snl->nl_groups)
+-		accept_msg = TRUE;
+-
+-	if (accept_msg == FALSE) {
+-		nm_log_dbg (LOGD_HW, "ignoring netlink message from PID %d (local PID %d, multicast %d)",
+-		            hdr->nlmsg_pid,
+-		            local_port,
+-		            (hdr->nlmsg_flags & NLM_F_MULTI));
+-		return NL_SKIP;
++	if (!creds || creds->pid || creds->uid || creds->gid) {
++		if (creds)
++			nm_log_dbg (LOGD_HW, "netlink: received non-kernel message (pid %d uid %d gid %d)",
++			            creds->pid, creds->uid, creds->gid);
++		else
++			nm_log_dbg (LOGD_HW, "netlink: received message without credentials");
++		return NL_STOP;
+ 	}
+ 
+ 	return NL_OK;
+@@ -285,7 +260,7 @@ nlh_setup (struct nl_sock *nlh,
+ {
+ 	int err;
+ 
+-	nl_socket_modify_cb (nlh, NL_CB_MSG_IN, NL_CB_CUSTOM, event_msg_recv, cb_data);
++	nl_socket_modify_cb (nlh, NL_CB_MSG_IN, NL_CB_CUSTOM, event_msg_recv, NULL);
+ 
+ 	if (valid_func)
+ 		nl_socket_modify_cb (nlh, NL_CB_VALID, NL_CB_CUSTOM, valid_func, cb_data);
diff --git a/pkgs/tools/networking/networkmanager/0.9.8/nixos-purity.patch b/pkgs/tools/networking/networkmanager/0.9.8/nixos-purity.patch
new file mode 100644
index 00000000000..9ebc080ba96
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/0.9.8/nixos-purity.patch
@@ -0,0 +1,77 @@
+diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c
+index 0932139..5b5aee8 100644
+--- a/src/dhcp-manager/nm-dhcp-dhclient.c
++++ b/src/dhcp-manager/nm-dhcp-dhclient.c
+@@ -68,10 +68,6 @@ const char *
+ nm_dhcp_dhclient_get_path (const char *try_first)
+ {
+ 	static const char *dhclient_paths[] = {
+-		"/sbin/dhclient",
+-		"/usr/sbin/dhclient",
+-		"/usr/pkg/sbin/dhclient",
+-		"/usr/local/sbin/dhclient",
+ 		NULL
+ 	};
+ 	const char **path = dhclient_paths;
+diff --git a/src/dhcp-manager/nm-dhcp-dhcpcd.c b/src/dhcp-manager/nm-dhcp-dhcpcd.c
+index 237661f..48bc33f 100644
+--- a/src/dhcp-manager/nm-dhcp-dhcpcd.c
++++ b/src/dhcp-manager/nm-dhcp-dhcpcd.c
+@@ -51,10 +51,6 @@ const char *
+ nm_dhcp_dhcpcd_get_path (const char *try_first)
+ {
+ 	static const char *dhcpcd_paths[] = {
+-		"/sbin/dhcpcd",
+-		"/usr/sbin/dhcpcd",
+-		"/usr/pkg/sbin/dhcpcd",
+-		"/usr/local/sbin/dhcpcd",
+ 		NULL
+ 	};
+ 	const char **path = dhcpcd_paths;
+diff --git a/src/nm-device.c b/src/nm-device.c
+index 1dc94ee..e60f3c8 100644
+--- a/src/nm-device.c
++++ b/src/nm-device.c
+@@ -1321,8 +1321,7 @@ aipd_start (NMDevice *self, NMDeviceStateReason *reason)
+ 	char *argv[6], *cmdline;
+ 	const char **aipd_binary = NULL;
+ 	static const char *aipd_paths[] = {
+-		"/usr/sbin/avahi-autoipd",
+-		"/usr/local/sbin/avahi-autoipd",
++		"@avahi@/sbin/avahi-autoipd",
+ 		NULL
+ 	};
+ 	int i = 0;
+@@ -2555,7 +2554,7 @@ share_init (void)
+ 	}
+ 
+ 	for (iter = modules; *iter; iter++) {
+-		char *argv[3] = { "/sbin/modprobe", *iter, NULL };
++		char *argv[3] = { "@kmod@/bin/modprobe", *iter, NULL };
+ 		char *envp[1] = { NULL };
+ 		GError *error = NULL;
+ 
+diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c
+index 59698c3..7dba0f7 100644
+--- a/src/ppp-manager/nm-ppp-manager.c
++++ b/src/ppp-manager/nm-ppp-manager.c
+@@ -661,9 +661,7 @@ static inline const char *
+ nm_find_pppd (void)
+ {
+ 	static const char *pppd_binary_paths[] = {
+-		"/usr/local/sbin/pppd",
+-		"/usr/sbin/pppd",
+-		"/sbin/pppd",
++		"@ppp@/sbin/pppd",
+ 		NULL
+ 	};
+ 
+@@ -988,7 +986,7 @@ nm_ppp_manager_start (NMPPPManager *manager,
+ 
+ 	/* Make sure /dev/ppp exists (bgo #533064) */
+ 	if (stat ("/dev/ppp", &st) || !S_ISCHR (st.st_mode))
+-		ignored = system ("/sbin/modprobe ppp_generic");
++		ignored = system ("@kmod@/bin/modprobe ppp_generic");
+ 
+ 	connection = nm_act_request_get_connection (req);
+ 	g_assert (connection);
diff --git a/pkgs/tools/networking/networkmanager/applet/default.nix b/pkgs/tools/networking/networkmanager/applet/default.nix
new file mode 100644
index 00000000000..5f83ffae055
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/applet/default.nix
@@ -0,0 +1,89 @@
+{ lib, stdenv
+, fetchurl
+, meson
+, ninja
+, gettext
+, pkg-config
+, networkmanager
+, gnome
+, libnotify
+, libsecret
+, polkit
+, modemmanager
+, libnma
+, glib-networking
+, gsettings-desktop-schemas
+, libgudev
+, jansson
+, wrapGAppsHook
+, gobject-introspection
+, python3
+, gtk3
+, libappindicator-gtk3
+, glib
+}:
+
+stdenv.mkDerivation rec {
+  pname = "network-manager-applet";
+  version = "1.22.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.majorMinor version}/${pname}-${version}.tar.xz";
+    sha256 = "sha256-xw2AtI1AqcuZ7JZ8xDifZ+fwMBUopp1IFXIEEzGmRr4=";
+  };
+
+  mesonFlags = [
+    "-Dselinux=false"
+    "-Dappindicator=yes"
+  ];
+
+  outputs = [ "out" "man" ];
+
+  buildInputs = [
+    libnma
+    gtk3
+    networkmanager
+    libnotify
+    libsecret
+    gsettings-desktop-schemas
+    polkit
+    libgudev
+    modemmanager
+    jansson
+    glib
+    glib-networking
+    libappindicator-gtk3
+    gnome.adwaita-icon-theme
+  ];
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    gettext
+    pkg-config
+    wrapGAppsHook
+    gobject-introspection
+    python3
+  ];
+
+  postPatch = ''
+    chmod +x meson_post_install.py # patchShebangs requires executable file
+    patchShebangs meson_post_install.py
+  '';
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "networkmanagerapplet";
+      versionPolicy = "odd-unstable";
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://gitlab.gnome.org/GNOME/network-manager-applet/";
+    description = "NetworkManager control applet for GNOME";
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ phreedom ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/tools/networking/networkmanager/default.nix b/pkgs/tools/networking/networkmanager/default.nix
new file mode 100644
index 00000000000..4f3b7a3204d
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/default.nix
@@ -0,0 +1,113 @@
+{ lib, stdenv, fetchurl, substituteAll, intltool, pkg-config, fetchpatch, dbus
+, gnome, systemd, libuuid, polkit, gnutls, ppp, dhcp, iptables, python3, vala
+, libgcrypt, dnsmasq, bluez5, readline, libselinux, audit
+, gobject-introspection, modemmanager, openresolv, libndp, newt, libsoup
+, ethtool, gnused, iputils, kmod, jansson, gtk-doc, libxslt
+, docbook_xsl, docbook_xml_dtd_412, docbook_xml_dtd_42, docbook_xml_dtd_43
+, openconnect, curl, meson, ninja, libpsl, mobile-broadband-provider-info, runtimeShell }:
+
+let
+  pythonForDocs = python3.withPackages (pkgs: with pkgs; [ pygobject3 ]);
+in stdenv.mkDerivation rec {
+  pname = "networkmanager";
+  version = "1.30.4";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/NetworkManager/${lib.versions.majorMinor version}/NetworkManager-${version}.tar.xz";
+    sha256 = "sha256-YFC3JCEuo85zhhEzWb6pr6H2eaVPYNmZpZmYkuZywZA=";
+  };
+
+  outputs = [ "out" "dev" "devdoc" "man" "doc" ];
+
+  # Right now we hardcode quite a few paths at build time. Probably we should
+  # patch networkmanager to allow passing these path in config file. This will
+  # remove unneeded build-time dependencies.
+  mesonFlags = [
+    "-Ddhclient=${dhcp}/bin/dhclient"
+    "-Ddnsmasq=${dnsmasq}/bin/dnsmasq"
+    # Upstream prefers dhclient, so don't add dhcpcd to the closure
+    "-Ddhcpcd=no"
+    "-Ddhcpcanon=no"
+    "-Dpppd=${ppp}/bin/pppd"
+    "-Diptables=${iptables}/bin/iptables"
+    # to enable link-local connections
+    "-Dudev_dir=${placeholder "out"}/lib/udev"
+    "-Dresolvconf=${openresolv}/bin/resolvconf"
+    "-Ddbus_conf_dir=${placeholder "out"}/share/dbus-1/system.d"
+    "-Dsystemdsystemunitdir=${placeholder "out"}/etc/systemd/system"
+    "-Dkernel_firmware_dir=/run/current-system/firmware"
+    "--sysconfdir=/etc"
+    "--localstatedir=/var"
+    "-Dcrypto=gnutls"
+    "-Dsession_tracking=systemd"
+    "-Dmodem_manager=true"
+    "-Dnmtui=true"
+    "-Ddocs=true"
+    "-Dtests=no"
+    "-Dqt=false"
+    "-Dpolkit_agent_helper_1=/run/wrappers/bin/polkit-agent-helper-1"
+    # Allow using iwd when configured to do so
+    "-Diwd=true"
+    "-Dlibaudit=yes-disabled-by-default"
+    # We don't use firewalld in NixOS
+    "-Dfirewalld_zone=false"
+  ];
+
+  patches = [
+    (substituteAll {
+      src = ./fix-paths.patch;
+      inherit iputils kmod openconnect ethtool gnused systemd;
+      inherit runtimeShell;
+    })
+
+    # Meson does not support using different directories during build and
+    # for installation like Autotools did with flags passed to make install.
+    ./fix-install-paths.patch
+  ];
+
+  buildInputs = [
+    systemd libselinux audit libpsl libuuid polkit ppp libndp curl mobile-broadband-provider-info
+    bluez5 dnsmasq gobject-introspection modemmanager readline newt libsoup jansson
+  ];
+
+  propagatedBuildInputs = [ gnutls libgcrypt ];
+
+  nativeBuildInputs = [
+    meson ninja intltool pkg-config
+    vala gobject-introspection dbus
+    # Docs
+    gtk-doc libxslt docbook_xsl docbook_xml_dtd_412 docbook_xml_dtd_42 docbook_xml_dtd_43 pythonForDocs
+  ];
+
+  doCheck = false; # requires /sys, the net
+
+  postPatch = ''
+    patchShebangs ./tools
+    patchShebangs libnm/generate-setting-docs.py
+  '';
+
+  preBuild = ''
+    # Our gobject-introspection patches make the shared library paths absolute
+    # in the GIR files. When building docs, the library is not yet installed,
+    # though, so we need to replace the absolute path with a local one during build.
+    # We are using a symlink that will be overridden during installation.
+    mkdir -p ${placeholder "out"}/lib
+    ln -s $PWD/libnm/libnm.so.0 ${placeholder "out"}/lib/libnm.so.0
+  '';
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = "NetworkManager";
+      attrPath = "networkmanager";
+      versionPolicy = "odd-unstable";
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://wiki.gnome.org/Projects/NetworkManager";
+    description = "Network configuration and management tool";
+    license = licenses.gpl2Plus;
+    maintainers = teams.freedesktop.members ++ (with maintainers; [ phreedom domenkozar obadz ]);
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/tools/networking/networkmanager/dmenu/default.nix b/pkgs/tools/networking/networkmanager/dmenu/default.nix
new file mode 100644
index 00000000000..9ea3dde19ab
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/dmenu/default.nix
@@ -0,0 +1,40 @@
+{ lib, stdenv, glib, fetchFromGitHub, networkmanager, python3Packages
+, gobject-introspection }:
+
+let inherit (python3Packages) python pygobject3;
+in stdenv.mkDerivation rec {
+  pname = "networkmanager_dmenu";
+  version = "1.6.0";
+
+  src = fetchFromGitHub {
+    owner = "firecat53";
+    repo = "networkmanager-dmenu";
+    rev = version;
+    sha256 = "1liidqh8c33pxyb07qyj0jkd0fdak73g9r2iwiq62vfzrpik09k0";
+  };
+
+  buildInputs = [ glib python pygobject3 gobject-introspection networkmanager python3Packages.wrapPython ];
+
+  dontBuild = true;
+
+  installPhase = ''
+    mkdir -p $out/bin
+    cp networkmanager_dmenu $out/bin/
+  '';
+
+  postFixup = ''
+    makeWrapperArgs="\
+      --prefix GI_TYPELIB_PATH : $GI_TYPELIB_PATH \
+      --prefix PYTHONPATH : \"$(toPythonPath $out):$(toPythonPath ${pygobject3})\""
+    wrapPythonPrograms
+  '';
+
+
+  meta = with lib; {
+    description  = "Small script to manage NetworkManager connections with dmenu instead of nm-applet";
+    homepage     = "https://github.com/firecat53/networkmanager-dmenu";
+    license      = lib.licenses.mit;
+    maintainers  = [ lib.maintainers.jensbin ];
+    platforms    = lib.platforms.all;
+  };
+}
diff --git a/pkgs/tools/networking/networkmanager/fix-install-paths.patch b/pkgs/tools/networking/networkmanager/fix-install-paths.patch
new file mode 100644
index 00000000000..4e80247cf14
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/fix-install-paths.patch
@@ -0,0 +1,16 @@
+diff --git a/meson.build b/meson.build
+index a2d925a7e..5a65cd2fe 100644
+--- a/meson.build
++++ b/meson.build
+@@ -959,9 +959,9 @@ meson.add_install_script(
+   join_paths('tools', 'meson-post-install.sh'),
+   nm_datadir,
+   nm_bindir,
+-  nm_pkgconfdir,
++  nm_prefix + nm_pkgconfdir,
+   nm_pkglibdir,
+-  nm_pkgstatedir,
++  nm_prefix + nm_pkgstatedir,
+   nm_mandir,
+   nm_sysconfdir,
+   enable_docs ? '1' : '0',
diff --git a/pkgs/tools/networking/networkmanager/fix-paths.patch b/pkgs/tools/networking/networkmanager/fix-paths.patch
new file mode 100644
index 00000000000..cb9d3c3a0d2
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/fix-paths.patch
@@ -0,0 +1,92 @@
+diff --git a/clients/common/nm-vpn-helpers.c b/clients/common/nm-vpn-helpers.c
+index 15c47c3ec..4d1913aa6 100644
+--- a/clients/common/nm-vpn-helpers.c
++++ b/clients/common/nm-vpn-helpers.c
+@@ -208,15 +208,7 @@ nm_vpn_openconnect_authenticate_helper(const char *host,
+         NULL,
+     };
+ 
+-    path = nm_utils_file_search_in_paths("openconnect",
+-                                         "/usr/sbin/openconnect",
+-                                         DEFAULT_PATHS,
+-                                         G_FILE_TEST_IS_EXECUTABLE,
+-                                         NULL,
+-                                         NULL,
+-                                         error);
+-    if (!path)
+-        return FALSE;
++    path = "@openconnect@/bin/openconnect";
+ 
+     if (!g_spawn_sync(NULL,
+                       (char **) NM_MAKE_STRV(path, "--authenticate", host),
+diff --git a/data/84-nm-drivers.rules b/data/84-nm-drivers.rules
+index e398cb9f2..a43d61864 100644
+--- a/data/84-nm-drivers.rules
++++ b/data/84-nm-drivers.rules
+@@ -7,6 +7,6 @@ ACTION!="add|change", GOTO="nm_drivers_end"
+ # Determine ID_NET_DRIVER if there's no ID_NET_DRIVER or DRIVERS (old udev?)
+ ENV{ID_NET_DRIVER}=="?*", GOTO="nm_drivers_end"
+ DRIVERS=="?*", GOTO="nm_drivers_end"
+-PROGRAM="/bin/sh -c '/usr/sbin/ethtool -i $$1 |/usr/bin/sed -n s/^driver:\ //p' -- $env{INTERFACE}", ENV{ID_NET_DRIVER}="%c"
++PROGRAM="@runtimeShell@ -c '@ethtool@/bin/ethtool -i $$1 |@gnused@/bin/sed -n s/^driver:\ //p' -- $env{INTERFACE}", ENV{ID_NET_DRIVER}="%c"
+ 
+ LABEL="nm_drivers_end"
+diff --git a/data/NetworkManager.service.in b/data/NetworkManager.service.in
+index 91ebd9a36..5201a56c3 100644
+--- a/data/NetworkManager.service.in
++++ b/data/NetworkManager.service.in
+@@ -8,7 +8,7 @@ Before=network.target @DISTRO_NETWORK_SERVICE@
+ [Service]
+ Type=dbus
+ BusName=org.freedesktop.NetworkManager
+-ExecReload=/usr/bin/busctl call org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager Reload u 0
++ExecReload=@systemd@/bin/busctl call org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager Reload u 0
+ #ExecReload=/bin/kill -HUP $MAINPID
+ ExecStart=@sbindir@/NetworkManager --no-daemon
+ Restart=on-failure
+diff --git a/libnm/meson.build b/libnm/meson.build
+index d0846419c..a7adb2cc6 100644
+--- a/libnm/meson.build
++++ b/libnm/meson.build
+@@ -280,7 +280,6 @@ if enable_introspection
+     output: 'nm-settings-docs-gir.xml',
+     command: [
+       generate_setting_docs_env,
+-      python.path(),
+       join_paths(meson.source_root(), 'tools', 'generate-docs-nm-settings-docs-gir.py'),
+       '--lib-path', meson.current_build_dir(),
+       '--gir', '@INPUT@',
+diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
+index 040dd0b4d..98aea3aa9 100644
+--- a/src/core/devices/nm-device.c
++++ b/src/core/devices/nm-device.c
+@@ -13957,14 +13957,14 @@ nm_device_start_ip_check(NMDevice *self)
+             gw = nm_ip4_config_best_default_route_get(priv->ip_config_4);
+             if (gw) {
+                 _nm_utils_inet4_ntop(NMP_OBJECT_CAST_IP4_ROUTE(gw)->gateway, buf);
+-                ping_binary = nm_utils_find_helper("ping", "/usr/bin/ping", NULL);
++                ping_binary = "@iputils@/bin/ping";
+                 log_domain  = LOGD_IP4;
+             }
+         } else if (priv->ip_config_6 && priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE) {
+             gw = nm_ip6_config_best_default_route_get(priv->ip_config_6);
+             if (gw) {
+                 _nm_utils_inet6_ntop(&NMP_OBJECT_CAST_IP6_ROUTE(gw)->gateway, buf);
+-                ping_binary = nm_utils_find_helper("ping6", "/usr/bin/ping6", NULL);
++                ping_binary = "@iputils@/bin/ping";
+                 log_domain  = LOGD_IP6;
+             }
+         }
+diff --git a/src/core/nm-core-utils.c b/src/core/nm-core-utils.c
+index 9075c30dd..4b140e92b 100644
+--- a/src/core/nm-core-utils.c
++++ b/src/core/nm-core-utils.c
+@@ -333,7 +333,7 @@ nm_utils_modprobe(GError **error, gboolean suppress_error_logging, const char *a
+ 
+     /* construct the argument list */
+     argv = g_ptr_array_sized_new(4);
+-    g_ptr_array_add(argv, "/sbin/modprobe");
++    g_ptr_array_add(argv, "@kmod@/bin/modprobe");
+     g_ptr_array_add(argv, "--use-blacklist");
+     g_ptr_array_add(argv, (char *) arg1);
+ 
diff --git a/pkgs/tools/networking/networkmanager/fortisslvpn/default.nix b/pkgs/tools/networking/networkmanager/fortisslvpn/default.nix
new file mode 100644
index 00000000000..f97bac13cf7
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/fortisslvpn/default.nix
@@ -0,0 +1,84 @@
+{ lib, stdenv
+, fetchurl
+, substituteAll
+, openfortivpn
+, gettext
+, pkg-config
+, file
+, glib
+, gtk3
+, networkmanager
+, ppp
+, libsecret
+, withGnome ? true
+, gnome
+, fetchpatch
+, libnma
+}:
+
+stdenv.mkDerivation rec {
+  pname = "NetworkManager-fortisslvpn";
+  version = "1.2.10";
+  name = "${pname}${if withGnome then "-gnome" else ""}-${version}";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.majorMinor version}/${pname}-${version}.tar.xz";
+    sha256 = "1sw66cxgs4in4cjp1cm95c5ijsk8xbbmq4ykg2jwqwgz6cf2lr3s";
+  };
+
+  patches = [
+    (substituteAll {
+      src = ./fix-paths.patch;
+      inherit openfortivpn;
+    })
+
+    # Don't use etc/dbus-1/system.d
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/NetworkManager-fortisslvpn/merge_requests/11.patch";
+      sha256 = "0l7l2r1njh62lh2pf497ibf99sgkvjsj58xr76qx3jxgq9zfw6n9";
+    })
+  ];
+
+  nativeBuildInputs = [
+    gettext
+    pkg-config
+    file
+  ];
+
+  buildInputs = [
+    openfortivpn
+    networkmanager
+    ppp
+    glib
+  ] ++ lib.optionals withGnome [
+    gtk3
+    libsecret
+    libnma
+  ];
+
+  configureFlags = [
+    "--with-gnome=${if withGnome then "yes" else "no"}"
+    "--localstatedir=/var"
+    "--enable-absolute-paths"
+  ];
+
+  installFlags = [
+    # the installer only creates an empty directory in localstatedir, so
+    # we can drop it
+    "localstatedir=."
+  ];
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "networkmanager-fortisslvpn";
+      versionPolicy = "odd-unstable";
+    };
+  };
+
+  meta = with lib; {
+    description = "NetworkManager’s FortiSSL plugin";
+    inherit (networkmanager.meta) maintainers platforms;
+    license = licenses.gpl2;
+  };
+}
diff --git a/pkgs/tools/networking/networkmanager/fortisslvpn/fix-paths.patch b/pkgs/tools/networking/networkmanager/fortisslvpn/fix-paths.patch
new file mode 100644
index 00000000000..a1241b6738c
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/fortisslvpn/fix-paths.patch
@@ -0,0 +1,11 @@
+--- a/src/nm-fortisslvpn-service.c
++++ b/src/nm-fortisslvpn-service.c
+@@ -387,7 +387,7 @@
+ {
+ 	static const char *openfortivpn_binary_paths[] =
+ 		{
+-			"/bin/openfortivpn",
++			"@openfortivpn@/bin/openfortivpn",
+ 			"/usr/bin/openfortivpn",
+ 			"/usr/local/bin/openfortivpn",
+ 			NULL
diff --git a/pkgs/tools/networking/networkmanager/iodine/default.nix b/pkgs/tools/networking/networkmanager/iodine/default.nix
new file mode 100644
index 00000000000..e56d9411b39
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/iodine/default.nix
@@ -0,0 +1,58 @@
+{ lib, stdenv, fetchFromGitLab, substituteAll, autoreconfHook, iodine, intltool, pkg-config, networkmanager, libsecret, gtk3
+, withGnome ? true, gnome, fetchpatch, libnma, glib }:
+
+let
+  pname = "NetworkManager-iodine";
+  version = "unstable-2019-11-05";
+in stdenv.mkDerivation {
+  name = "${pname}${if withGnome then "-gnome" else ""}-${version}";
+
+  src = fetchFromGitLab {
+    domain = "gitlab.gnome.org";
+    owner = "GNOME";
+    repo = "network-manager-iodine";
+    rev = "2ef0abf089b00a0546f214dde0d45e63f2990b79";
+    sha256 = "1ps26fr9b1yyafj7lrzf2kmaxb0ipl0mhagch5kzrjdsc5xkajz7";
+  };
+
+  patches = [
+    (substituteAll {
+      src = ./fix-paths.patch;
+      inherit iodine;
+    })
+    # Don't use etc/dbus-1/system.d
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/network-manager-iodine/merge_requests/2.patch";
+      sha256 = "108pkf0mddj32s46k7jkmpwcaq2ylci4dqpp7wck3zm9q2jffff2";
+    })
+  ];
+
+  buildInputs = [ iodine networkmanager glib ]
+    ++ lib.optionals withGnome [ gtk3 libsecret libnma ];
+
+  nativeBuildInputs = [ intltool autoreconfHook pkg-config ];
+
+  # glib-2.62 deprecations
+  NIX_CFLAGS_COMPILE = "-DGLIB_DISABLE_DEPRECATION_WARNINGS";
+
+  preConfigure = "intltoolize";
+  configureFlags = [
+    "--without-libnm-glib"
+    "--with-gnome=${if withGnome then "yes" else "no"}"
+    "--localstatedir=/" # needed for the management socket under /run/NetworkManager
+    "--enable-absolute-paths"
+  ];
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "networkmanager-iodine";
+    };
+  };
+
+  meta = with lib; {
+    description = "NetworkManager's iodine plugin";
+    inherit (networkmanager.meta) maintainers platforms;
+    license = licenses.gpl2Plus;
+  };
+}
diff --git a/pkgs/tools/networking/networkmanager/iodine/fix-paths.patch b/pkgs/tools/networking/networkmanager/iodine/fix-paths.patch
new file mode 100644
index 00000000000..d32dbfadbaf
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/iodine/fix-paths.patch
@@ -0,0 +1,11 @@
+--- a/src/nm-iodine-service.c
++++ b/src/nm-iodine-service.c
+@@ -62,7 +62,7 @@
+ 
+ static const char *iodine_binary_paths[] =
+ {
+-	"/usr/bin/iodine",
++	"@iodine@/bin/iodine",
+ 	"/usr/sbin/iodine",
+ 	"/usr/local/bin/iodine",
+ 	"/usr/local/sbin/iodine",
diff --git a/pkgs/tools/networking/networkmanager/l2tp/default.nix b/pkgs/tools/networking/networkmanager/l2tp/default.nix
new file mode 100644
index 00000000000..bfcc2d8ae86
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/l2tp/default.nix
@@ -0,0 +1,51 @@
+{ lib, stdenv, substituteAll, fetchFromGitHub, autoreconfHook, libtool, intltool, pkg-config
+, file, findutils
+, gtk3, networkmanager, ppp, xl2tpd, strongswan, libsecret
+, withGnome ? true, libnma }:
+
+stdenv.mkDerivation rec {
+  name = "${pname}${if withGnome then "-gnome" else ""}-${version}";
+  pname = "NetworkManager-l2tp";
+  version = "1.2.12";
+
+  src = fetchFromGitHub {
+    owner = "nm-l2tp";
+    repo = "network-manager-l2tp";
+    rev = version;
+    sha256 = "0cq07kvlm98s8a7l4a3zmqnif8x3307kv7n645zx3f1r7x72b8m4";
+  };
+
+  patches = [
+    (substituteAll {
+      src = ./fix-paths.patch;
+      inherit strongswan xl2tpd;
+    })
+  ];
+
+  buildInputs = [ networkmanager ppp ]
+    ++ lib.optionals withGnome [ gtk3 libsecret libnma ];
+
+  nativeBuildInputs = [ autoreconfHook libtool intltool pkg-config file findutils ];
+
+  preConfigure = ''
+    intltoolize -f
+  '';
+
+  configureFlags = [
+    "--without-libnm-glib"
+    "--with-gnome=${if withGnome then "yes" else "no"}"
+    "--localstatedir=/var"
+    "--sysconfdir=$(out)/etc"
+    "--enable-absolute-paths"
+  ];
+
+  enableParallelBuilding = true;
+
+  meta = with lib; {
+    description = "L2TP plugin for NetworkManager";
+    inherit (networkmanager.meta) platforms;
+    homepage = "https://github.com/nm-l2tp/network-manager-l2tp";
+    license = licenses.gpl2;
+    maintainers = with maintainers; [ abbradar obadz ];
+  };
+}
diff --git a/pkgs/tools/networking/networkmanager/l2tp/fix-paths.patch b/pkgs/tools/networking/networkmanager/l2tp/fix-paths.patch
new file mode 100644
index 00000000000..531672c3936
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/l2tp/fix-paths.patch
@@ -0,0 +1,22 @@
+diff --git a/shared/utils.c b/shared/utils.c
+index c978a1f..d2c36cd 100644
+--- a/shared/utils.c
++++ b/shared/utils.c
+@@ -52,7 +52,7 @@ nm_find_ipsec (void)
+ {
+ 	static const char *ipsec_binary_paths[] =
+ 		{
+-			"/sbin/ipsec",
++			"@strongswan@/bin/ipsec",
+ 			"/usr/sbin/ipsec",
+ 			"/usr/local/sbin/ipsec",
+ 			"/sbin/strongswan",
+@@ -77,7 +77,7 @@ nm_find_l2tpd (void)
+ {
+ 	static const char *l2tp_binary_paths[] =
+ 		{
+-			"/sbin/xl2tpd",
++			"@xl2tpd@/bin/xl2tpd",
+ 			"/usr/sbin/xl2tpd",
+ 			"/usr/local/sbin/xl2tpd",
+ 			NULL
diff --git a/pkgs/tools/networking/networkmanager/libnma/default.nix b/pkgs/tools/networking/networkmanager/libnma/default.nix
new file mode 100644
index 00000000000..50fc66a8d68
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/libnma/default.nix
@@ -0,0 +1,91 @@
+{ stdenv
+, fetchurl
+, meson
+, ninja
+, gettext
+, gtk-doc
+, pkg-config
+, vala
+, networkmanager
+, gnome
+, isocodes
+, libxml2
+, docbook_xsl
+, docbook_xml_dtd_43
+, mobile-broadband-provider-info
+, gobject-introspection
+, gtk3
+, withGnome ? true
+, gcr
+, glib
+, substituteAll
+, lib
+}:
+
+stdenv.mkDerivation rec {
+  pname = "libnma";
+  version = "1.8.30";
+
+  outputs = [ "out" "dev" "devdoc" ];
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.majorMinor version}/${pname}-${version}.tar.xz";
+    sha256 = "1d5gzn7ss5vi0bhc8s4i5gsrck1ajslajam5jxfqazg094mffcys";
+  };
+
+  patches = [
+    # Needed for wingpanel-indicator-network and switchboard-plug-network
+    ./hardcode-gsettings.patch
+  ];
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    gettext
+    pkg-config
+    gobject-introspection
+    gtk-doc
+    docbook_xsl
+    docbook_xml_dtd_43
+    libxml2
+    vala
+  ];
+
+  buildInputs = [
+    gtk3
+    networkmanager
+    isocodes
+    mobile-broadband-provider-info
+  ] ++ lib.optionals withGnome [
+    # advanced certificate chooser
+    gcr
+  ];
+
+  mesonFlags = [
+    "-Dgcr=${lib.boolToString withGnome}"
+  ];
+
+  postPatch = ''
+    substituteInPlace src/nma-ws/nma-eap.c --subst-var-by \
+      NM_APPLET_GSETTINGS ${glib.makeSchemaPath "$out" "${pname}-${version}"}
+  '';
+
+  postInstall = ''
+    glib-compile-schemas $out/share/glib-2.0/schemas
+  '';
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      versionPolicy = "odd-unstable";
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://gitlab.gnome.org/GNOME/libnma";
+    description = "NetworkManager UI utilities (libnm version)";
+    license = licenses.gpl2Plus; # Mix of GPL and LPGL 2+
+    maintainers = teams.gnome.members;
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/tools/networking/networkmanager/libnma/hardcode-gsettings.patch b/pkgs/tools/networking/networkmanager/libnma/hardcode-gsettings.patch
new file mode 100644
index 00000000000..9b2f5366950
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/libnma/hardcode-gsettings.patch
@@ -0,0 +1,26 @@
+--- a/src/nma-ws/nma-eap.c
++++ b/src/nma-ws/nma-eap.c
+@@ -248,11 +248,16 @@ nma_eap_ca_cert_ignore_get (NMAEap *method, NMConnection *connection)
+ static GSettings *
+ _get_ca_ignore_settings (NMConnection *connection)
+ {
++	g_autoptr (GSettingsSchemaSource) *schema_source;
++	g_autoptr (GSettingsSchema) *schema;
+ 	GSettings *settings;
+ 	char *path = NULL;
+ 	const char *uuid;
+
+ 	g_return_val_if_fail (connection, NULL);
+
++	schema_source = g_settings_schema_source_new_from_directory ("@NM_APPLET_GSETTINGS@", g_settings_schema_source_get_default (), TRUE, NULL);
++	schema = g_settings_schema_source_lookup (schema_source, "org.gnome.nm-applet.eap", FALSE);
++
+ 	uuid = nm_connection_get_uuid (connection);
+ 	g_return_val_if_fail (uuid && *uuid, NULL);
+
+ 	path = g_strdup_printf ("/org/gnome/nm-applet/eap/%s/", uuid);
+-	settings = g_settings_new_with_path ("org.gnome.nm-applet.eap", path);
++	settings = g_settings_new_full (schema, NULL, path);
+ 	g_free (path);
+
+ 	return settings;
diff --git a/pkgs/tools/networking/networkmanager/openconnect/default.nix b/pkgs/tools/networking/networkmanager/openconnect/default.nix
new file mode 100644
index 00000000000..c03a698514a
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/openconnect/default.nix
@@ -0,0 +1,81 @@
+{ lib, stdenv
+, fetchurl
+, substituteAll
+, glib
+, libxml2
+, openconnect
+, intltool
+, pkg-config
+, autoreconfHook
+, networkmanager
+, gcr
+, libsecret
+, file
+, gtk3
+, withGnome ? true
+, gnome
+, kmod
+, fetchpatch
+}:
+
+let
+  pname = "NetworkManager-openconnect";
+  version = "1.2.6";
+in stdenv.mkDerivation {
+  name = "${pname}${if withGnome then "-gnome" else ""}-${version}";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.majorMinor version}/${pname}-${version}.tar.xz";
+    sha256 = "0nlp290nkawc4wqm978n4vhzg3xdqi8kpjjx19l855vab41rh44m";
+  };
+
+  patches = [
+    (substituteAll {
+      src = ./fix-paths.patch;
+      inherit kmod openconnect;
+    })
+
+    # Don't use etc/dbus-1/system.d
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/NetworkManager-openconnect/merge_requests/9.patch";
+      sha256 = "0yd2dmq6gq6y4czr7dqdgaiqvw2vyv2gikznpfdxyfn2v1pcrk9m";
+    })
+  ];
+
+  buildInputs = [
+    glib
+    libxml2
+    openconnect
+    networkmanager
+  ] ++ lib.optionals withGnome [
+    gtk3
+    gcr
+    libsecret
+  ];
+
+  nativeBuildInputs = [
+    intltool
+    pkg-config
+    file
+  ];
+
+  configureFlags = [
+    "--with-gnome=${if withGnome then "yes" else "no"}"
+    "--enable-absolute-paths"
+    "--without-libnm-glib"
+  ];
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "networkmanager-openconnect";
+      versionPolicy = "odd-unstable";
+    };
+  };
+
+  meta = with lib; {
+    description = "NetworkManager’s OpenConnect plugin";
+    inherit (networkmanager.meta) maintainers platforms;
+    license = licenses.gpl2Plus;
+  };
+}
diff --git a/pkgs/tools/networking/networkmanager/openconnect/fix-paths.patch b/pkgs/tools/networking/networkmanager/openconnect/fix-paths.patch
new file mode 100644
index 00000000000..9b342f5bd08
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/openconnect/fix-paths.patch
@@ -0,0 +1,20 @@
+--- a/src/nm-openconnect-service.c
++++ b/src/nm-openconnect-service.c
+@@ -60,7 +60,7 @@
+ 
+ static const char *openconnect_binary_paths[] =
+ {
+-	"/usr/bin/openconnect",
++	"@openconnect@/bin/openconnect",
+ 	"/usr/sbin/openconnect",
+ 	"/usr/local/bin/openconnect",
+ 	"/usr/local/sbin/openconnect",
+@@ -734,7 +734,7 @@
+ 
+ 	_LOGD ("nm-openconnect-service (version " DIST_VERSION ") starting...");
+ 
+-	if (system ("/sbin/modprobe tun") == -1)
++	if (system ("@kmod@/bin/modprobe tun") == -1)
+ 		exit (EXIT_FAILURE);
+ 
+ 	if (bus_name)
diff --git a/pkgs/tools/networking/networkmanager/openvpn/default.nix b/pkgs/tools/networking/networkmanager/openvpn/default.nix
new file mode 100644
index 00000000000..06df79e4705
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/openvpn/default.nix
@@ -0,0 +1,46 @@
+{ lib, stdenv, fetchurl, substituteAll, openvpn, intltool, libxml2, pkg-config, file, networkmanager, libsecret
+, gtk3, withGnome ? true, gnome, kmod, libnma }:
+
+let
+  pname = "NetworkManager-openvpn";
+  version = "1.8.12";
+in stdenv.mkDerivation {
+  name = "${pname}${if withGnome then "-gnome" else ""}-${version}";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.majorMinor version}/${pname}-${version}.tar.xz";
+    sha256 = "062kh4zj7jfbwy4zzcwpq2m457bzbpm3l18s0ysnw3mgia3siz8f";
+  };
+
+  patches = [
+    (substituteAll {
+      src = ./fix-paths.patch;
+      inherit kmod openvpn;
+    })
+  ];
+
+  buildInputs = [ openvpn networkmanager ]
+    ++ lib.optionals withGnome [ gtk3 libsecret libnma ];
+
+  nativeBuildInputs = [ intltool pkg-config file libxml2 ];
+
+  configureFlags = [
+    "--with-gnome=${if withGnome then "yes" else "no"}"
+    "--localstatedir=/" # needed for the management socket under /run/NetworkManager
+    "--enable-absolute-paths"
+  ];
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "networkmanager-openvpn";
+      versionPolicy = "odd-unstable";
+    };
+  };
+
+  meta = with lib; {
+    description = "NetworkManager's OpenVPN plugin";
+    inherit (networkmanager.meta) maintainers platforms;
+    license = licenses.gpl2Plus;
+  };
+}
diff --git a/pkgs/tools/networking/networkmanager/openvpn/fix-paths.patch b/pkgs/tools/networking/networkmanager/openvpn/fix-paths.patch
new file mode 100644
index 00000000000..b735da28dca
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/openvpn/fix-paths.patch
@@ -0,0 +1,34 @@
+--- a/properties/nm-openvpn-editor.c
++++ b/properties/nm-openvpn-editor.c
+@@ -775,8 +775,7 @@
+ nm_find_openvpn (void)
+ {
+ 	static const char *openvpn_binary_paths[] = {
+-		"/usr/sbin/openvpn",
+-		"/sbin/openvpn",
++		"@openvpn@/bin/openvpn",
+ 		NULL
+ 	};
+ 	const char  **openvpn_binary = openvpn_binary_paths;
+--- a/src/nm-openvpn-service.c
++++ b/src/nm-openvpn-service.c
+@@ -522,9 +522,7 @@
+ openvpn_binary_find_exepath (void)
+ {
+ 	static const char *paths[] = {
+-		"/usr/sbin/openvpn",
+-		"/sbin/openvpn",
+-		"/usr/local/sbin/openvpn",
++		"@openvpn@/bin/openvpn",
+ 	};
+ 	int i;
+ 
+@@ -2326,7 +2324,7 @@
+ 	_LOGD ("nm-openvpn-service (version " DIST_VERSION ") starting...");
+ 
+ 	if (   !g_file_test ("/sys/class/misc/tun", G_FILE_TEST_EXISTS)
+-	    && (system ("/sbin/modprobe tun") == -1))
++	    && (system ("@kmod@/bin/modprobe tun") == -1))
+ 		return EXIT_FAILURE;
+ 
+ 	plugin = nm_openvpn_plugin_new (bus_name);
diff --git a/pkgs/tools/networking/networkmanager/sstp/default.nix b/pkgs/tools/networking/networkmanager/sstp/default.nix
new file mode 100644
index 00000000000..f4866234438
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/sstp/default.nix
@@ -0,0 +1,64 @@
+{ lib, stdenv
+, autoreconfHook
+, fetchFromGitHub
+, fetchpatch
+, file
+, glib
+, gnome
+, gtk3
+, intltool
+, libnma
+, libsecret
+, networkmanager
+, pkg-config
+, ppp
+, sstp
+, substituteAll
+, withGnome ? true }:
+
+let
+  pname = "NetworkManager-sstp";
+  version = "unstable-2020-04-20";
+in stdenv.mkDerivation {
+  name = "${pname}${if withGnome then "-gnome" else ""}-${version}";
+
+  src = fetchFromGitHub {
+    owner = "enaess";
+    repo = "network-manager-sstp";
+    rev = "735d8ca078f933e085029f60a737e3cf1d8c29a8";
+    sha256 = "0aahfhy2ch951kzj6gnd8p8hv2s5yd5y10wrmj68djhnx2ml8cd3";
+  };
+
+  buildInputs = [ sstp networkmanager glib ppp ]
+    ++ lib.optionals withGnome [ gtk3 libsecret libnma ];
+
+  nativeBuildInputs = [ file intltool autoreconfHook pkg-config ];
+
+  postPatch = ''
+    sed -i 's#/sbin/pppd#${ppp}/bin/pppd#' src/nm-sstp-service.c
+    sed -i 's#/sbin/sstpc#${sstp}/bin/sstpc#' src/nm-sstp-service.c
+  '';
+
+  # glib-2.62 deprecations
+  NIX_CFLAGS_COMPILE = "-DGLIB_DISABLE_DEPRECATION_WARNINGS";
+
+  preConfigure = "intltoolize";
+  configureFlags = [
+    "--without-libnm-glib"
+    "--with-gnome=${if withGnome then "yes" else "no"}"
+    "--enable-absolute-paths"
+  ];
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "networkmanager-sstp";
+    };
+  };
+
+  meta = with lib; {
+    description = "NetworkManager's sstp plugin";
+    inherit (networkmanager.meta) maintainers platforms;
+    license = licenses.gpl2Plus;
+  };
+}
diff --git a/pkgs/tools/networking/networkmanager/strongswan/default.nix b/pkgs/tools/networking/networkmanager/strongswan/default.nix
new file mode 100644
index 00000000000..cebcec35a31
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/strongswan/default.nix
@@ -0,0 +1,34 @@
+{ lib, stdenv, fetchurl, intltool, pkg-config, networkmanager, strongswanNM
+, gtk3, gnome, libsecret, libnma }:
+
+stdenv.mkDerivation rec {
+  pname = "NetworkManager-strongswan";
+  version = "1.5.2";
+
+  src = fetchurl {
+    url = "https://download.strongswan.org/NetworkManager/${pname}-${version}.tar.bz2";
+    sha256 = "0sc1yzlxjfvl58hjjw99bchqc4061i3apw254z61v22k4sajnif8";
+  };
+
+  buildInputs = [ networkmanager strongswanNM libsecret gtk3 libnma ];
+
+  nativeBuildInputs = [ intltool pkg-config ];
+
+  # glib-2.62 deprecations
+  NIX_CFLAGS_COMPILE = "-DGLIB_DISABLE_DEPRECATION_WARNINGS";
+
+  configureFlags = [
+    "--without-libnm-glib"
+    "--with-charon=${strongswanNM}/libexec/ipsec/charon-nm"
+    "--with-nm-libexecdir=$(out)/libexec"
+    "--with-nm-plugindir=$(out)/lib/NetworkManager"
+  ];
+
+  PKG_CONFIG_LIBNM_VPNSERVICEDIR = "$(out)/lib/NetworkManager/VPN";
+
+  meta = with lib; {
+    description = "NetworkManager's strongswan plugin";
+    inherit (networkmanager.meta) platforms;
+    license = licenses.gpl2Plus;
+  };
+}
diff --git a/pkgs/tools/networking/networkmanager/tray.nix b/pkgs/tools/networking/networkmanager/tray.nix
new file mode 100644
index 00000000000..e8ce8ad342f
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/tray.nix
@@ -0,0 +1,31 @@
+{ lib, mkDerivation, fetchFromGitHub, cmake, qttools, qtbase, networkmanager-qt, modemmanager-qt }:
+
+mkDerivation rec {
+  pname = "nm-tray";
+  version = "0.4.3";
+
+  src = fetchFromGitHub {
+    owner = "palinek";
+    repo = pname;
+    rev = version;
+    sha256 = "08c86kd613wlvw9571q7a3lb7g6skyyasjw6h1g543rbl4jn2c2v";
+  };
+
+  postPatch = ''
+    sed -i -e '1i#include <QMetaEnum>' src/nmmodel.cpp
+  '';
+
+  nativeBuildInputs = [ cmake qttools ];
+
+  cmakeFlags = [ "-DWITH_MODEMMANAGER_SUPPORT=ON" ];
+
+  buildInputs = [ qtbase networkmanager-qt modemmanager-qt ];
+
+  meta = with lib; {
+    description = "Simple Network Manager frontend written in Qt";
+    homepage = "https://github.com/palinek/nm-tray";
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ dtzWill ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/tools/networking/networkmanager/vpnc/default.nix b/pkgs/tools/networking/networkmanager/vpnc/default.nix
new file mode 100644
index 00000000000..70e7104696e
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/vpnc/default.nix
@@ -0,0 +1,50 @@
+{ lib, stdenv, fetchurl, substituteAll, vpnc, intltool, pkg-config, networkmanager, libsecret
+, gtk3, withGnome ? true, gnome, glib, kmod, file, fetchpatch, libnma }:
+let
+  pname = "NetworkManager-vpnc";
+  version = "1.2.6";
+in stdenv.mkDerivation {
+  name = "${pname}${if withGnome then "-gnome" else ""}-${version}";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.majorMinor version}/${pname}-${version}.tar.xz";
+    sha256 = "1js5lwcsqws4klgypfxl4ikmakv7v7xgddij1fj6b0y0qicx0kyy";
+  };
+
+  patches = [
+    (substituteAll {
+      src = ./fix-paths.patch;
+      inherit vpnc kmod;
+    })
+    # Don't use etc/dbus-1/system.d
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/NetworkManager-vpnc/merge_requests/5.patch";
+      sha256 = "0z0x5vqmrsap3ynamhya7gh6c6k5grhj2vqpy76alnv9xns8dzi6";
+    })
+  ];
+
+  buildInputs = [ vpnc networkmanager glib ]
+    ++ lib.optionals withGnome [ gtk3 libsecret libnma ];
+
+  nativeBuildInputs = [ intltool pkg-config file ];
+
+  configureFlags = [
+    "--without-libnm-glib"
+    "--with-gnome=${if withGnome then "yes" else "no"}"
+    "--enable-absolute-paths"
+  ];
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "networkmanager-vpnc";
+      versionPolicy = "odd-unstable";
+    };
+  };
+
+  meta = with lib; {
+    description = "NetworkManager's VPNC plugin";
+    inherit (networkmanager.meta) maintainers platforms;
+    license = licenses.gpl2Plus;
+  };
+}
diff --git a/pkgs/tools/networking/networkmanager/vpnc/fix-paths.patch b/pkgs/tools/networking/networkmanager/vpnc/fix-paths.patch
new file mode 100644
index 00000000000..98238ac01f7
--- /dev/null
+++ b/pkgs/tools/networking/networkmanager/vpnc/fix-paths.patch
@@ -0,0 +1,31 @@
+--- a/properties/nm-vpnc-editor-plugin.c
++++ b/properties/nm-vpnc-editor-plugin.c
+@@ -161,7 +161,7 @@
+ 	GError *error = NULL;
+ 
+ 	const char *decrypt_possible_paths[] = {
+-		"/usr/lib/vpnc/cisco-decrypt",
++		"@vpnc@/bin/cisco-decrypt",
+ 		"/usr/bin/cisco-decrypt",
+ 		NULL
+ 	};
+--- a/src/nm-vpnc-service.c
++++ b/src/nm-vpnc-service.c
+@@ -610,7 +610,7 @@
+ find_vpnc (void)
+ {
+ 	static const char *vpnc_paths[] = {
+-		"/usr/sbin/vpnc",
++		"@vpnc@/bin/vpnc",
+ 		"/sbin/vpnc",
+ 		"/usr/local/sbin/vpnc",
+ 		NULL
+@@ -1308,7 +1308,7 @@
+ 	_LOGD ("   vpnc interactive mode is %s", interactive_available ? "enabled" : "disabled");
+ 	_LOGD ("   uses%s --bus-name \"%s\"", bus_name_free ? "" : " default", bus_name);
+ 
+-	if (system ("/sbin/modprobe tun") == -1)
++	if (system ("@kmod@/bin/modprobe tun") == -1)
+ 		exit (EXIT_FAILURE);
+ 
+ 	plugin = nm_vpnc_plugin_new (bus_name);