commit
a24431e56f
@ -142,6 +142,13 @@
|
|||||||
<link linkend="opt-services.persistent-evdev.enable">services.persistent-evdev</link>.
|
<link linkend="opt-services.persistent-evdev.enable">services.persistent-evdev</link>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://schleuder.org/">schleuder</link>, a
|
||||||
|
mailing list manager with PGP support. Enable using
|
||||||
|
<link linkend="opt-services.schleuder.enable">services.schleuder</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<link xlink:href="https://www.expressvpn.com">expressvpn</link>,
|
<link xlink:href="https://www.expressvpn.com">expressvpn</link>,
|
||||||
|
@ -60,6 +60,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||||||
Available as [services.infnoise](options.html#opt-services.infnoise.enable).
|
Available as [services.infnoise](options.html#opt-services.infnoise.enable).
|
||||||
- [persistent-evdev](https://github.com/aiberia/persistent-evdev), a daemon to add virtual proxy devices that mirror a physical input device but persist even if the underlying hardware is hot-plugged. Available as [services.persistent-evdev](#opt-services.persistent-evdev.enable).
|
- [persistent-evdev](https://github.com/aiberia/persistent-evdev), a daemon to add virtual proxy devices that mirror a physical input device but persist even if the underlying hardware is hot-plugged. Available as [services.persistent-evdev](#opt-services.persistent-evdev.enable).
|
||||||
|
|
||||||
|
- [schleuder](https://schleuder.org/), a mailing list manager with PGP support. Enable using [services.schleuder](#opt-services.schleuder.enable).
|
||||||
|
|
||||||
- [expressvpn](https://www.expressvpn.com), the CLI client for ExpressVPN. Available as [services.expressvpn](#opt-services.expressvpn.enable).
|
- [expressvpn](https://www.expressvpn.com), the CLI client for ExpressVPN. Available as [services.expressvpn](#opt-services.expressvpn.enable).
|
||||||
|
|
||||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||||
|
@ -515,6 +515,7 @@
|
|||||||
./services/mail/rspamd.nix
|
./services/mail/rspamd.nix
|
||||||
./services/mail/rss2email.nix
|
./services/mail/rss2email.nix
|
||||||
./services/mail/roundcube.nix
|
./services/mail/roundcube.nix
|
||||||
|
./services/mail/schleuder.nix
|
||||||
./services/mail/sympa.nix
|
./services/mail/sympa.nix
|
||||||
./services/mail/nullmailer.nix
|
./services/mail/nullmailer.nix
|
||||||
./services/matrix/appservice-discord.nix
|
./services/matrix/appservice-discord.nix
|
||||||
|
162
nixos/modules/services/mail/schleuder.nix
Normal file
162
nixos/modules/services/mail/schleuder.nix
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.services.schleuder;
|
||||||
|
settingsFormat = pkgs.formats.yaml { };
|
||||||
|
postfixMap = entries: lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value: "${name} ${value}") entries);
|
||||||
|
writePostfixMap = name: entries: pkgs.writeText name (postfixMap entries);
|
||||||
|
configScript = pkgs.writeScript "schleuder-cfg" ''
|
||||||
|
#!${pkgs.runtimeShell}
|
||||||
|
set -exuo pipefail
|
||||||
|
umask 0077
|
||||||
|
${pkgs.yq}/bin/yq \
|
||||||
|
--slurpfile overrides <(${pkgs.yq}/bin/yq . <${lib.escapeShellArg cfg.extraSettingsFile}) \
|
||||||
|
< ${settingsFormat.generate "schleuder.yml" cfg.settings} \
|
||||||
|
'. * $overrides[0]' \
|
||||||
|
> /etc/schleuder/schleuder.yml
|
||||||
|
chown schleuder: /etc/schleuder/schleuder.yml
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.schleuder = {
|
||||||
|
enable = lib.mkEnableOption "Schleuder secure remailer";
|
||||||
|
enablePostfix = lib.mkEnableOption "automatic postfix integration" // { default = true; };
|
||||||
|
lists = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
List of list addresses that should be handled by Schleuder.
|
||||||
|
|
||||||
|
Note that this is only handled by the postfix integration, and
|
||||||
|
the setup of the lists, their members and their keys has to be
|
||||||
|
performed separately via schleuder's API, using a tool such as
|
||||||
|
schleuder-cli.
|
||||||
|
'';
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
default = [ ];
|
||||||
|
example = [ "widget-team@example.com" "security@example.com" ];
|
||||||
|
};
|
||||||
|
/* maybe one day....
|
||||||
|
domains = lib.mkOption {
|
||||||
|
description = "Domains for which all mail should be handled by Schleuder.";
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
default = [];
|
||||||
|
example = ["securelists.example.com"];
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
settings = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Settings for schleuder.yml.
|
||||||
|
|
||||||
|
Check the <link xlink:href="https://0xacab.org/schleuder/schleuder/blob/master/etc/schleuder.yml">example configuration</link> for possible values.
|
||||||
|
'';
|
||||||
|
type = lib.types.submodule {
|
||||||
|
freeformType = settingsFormat.type;
|
||||||
|
options.keyserver = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = ''
|
||||||
|
Key server from which to fetch and update keys.
|
||||||
|
|
||||||
|
Note that NixOS uses a different default from upstream, since the upstream default sks-keyservers.net is deprecated.
|
||||||
|
'';
|
||||||
|
default = "keys.openpgp.org";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
extraSettingsFile = lib.mkOption {
|
||||||
|
description = "YAML file to merge into the schleuder config at runtime. This can be used for secrets such as API keys.";
|
||||||
|
type = lib.types.nullOr lib.types.path;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
listDefaults = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Default settings for lists (list-defaults.yml).
|
||||||
|
|
||||||
|
Check the <link xlink:href="https://0xacab.org/schleuder/schleuder/-/blob/master/etc/list-defaults.yml">example configuration</link> for possible values.
|
||||||
|
'';
|
||||||
|
type = settingsFormat.type;
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = !(cfg.settings.api ? valid_api_keys);
|
||||||
|
message = ''
|
||||||
|
services.schleuder.settings.api.valid_api_keys is set. Defining API keys via NixOS config results in them being copied to the world-readable Nix store. Please use the extraSettingsFile option to store API keys in a non-public location.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = !(lib.any (db: db ? password) (lib.attrValues cfg.settings.database or {}));
|
||||||
|
message = ''
|
||||||
|
A password is defined for at least one database in services.schleuder.settings.database. Defining passwords via NixOS config results in them being copied to the world-readable Nix store. Please use the extraSettingsFile option to store database passwords in a non-public location.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
|
users.users.schleuder.isSystemUser = true;
|
||||||
|
users.users.schleuder.group = "schleuder";
|
||||||
|
users.groups.schleuder = {};
|
||||||
|
environment.systemPackages = [
|
||||||
|
pkgs.schleuder-cli
|
||||||
|
];
|
||||||
|
services.postfix = lib.mkIf cfg.enablePostfix {
|
||||||
|
extraMasterConf = ''
|
||||||
|
schleuder unix - n n - - pipe
|
||||||
|
flags=DRhu user=schleuder argv=/${pkgs.schleuder}/bin/schleuder work ''${recipient}
|
||||||
|
'';
|
||||||
|
transport = lib.mkIf (cfg.lists != [ ]) (postfixMap (lib.genAttrs cfg.lists (_: "schleuder:")));
|
||||||
|
extraConfig = ''
|
||||||
|
schleuder_destination_recipient_limit = 1
|
||||||
|
'';
|
||||||
|
# review: does this make sense?
|
||||||
|
localRecipients = lib.mkIf (cfg.lists != [ ]) cfg.lists;
|
||||||
|
};
|
||||||
|
systemd.services = let commonServiceConfig = {
|
||||||
|
# We would have liked to use DynamicUser, but since the default
|
||||||
|
# database is SQLite and lives in StateDirectory, and that same
|
||||||
|
# database needs to be readable from the postfix service, this
|
||||||
|
# isn't trivial to do.
|
||||||
|
User = "schleuder";
|
||||||
|
StateDirectory = "schleuder";
|
||||||
|
StateDirectoryMode = "0700";
|
||||||
|
}; in
|
||||||
|
{
|
||||||
|
schleuder-init = {
|
||||||
|
serviceConfig = commonServiceConfig // {
|
||||||
|
ExecStartPre = lib.mkIf (cfg.extraSettingsFile != null) [
|
||||||
|
"+${configScript}"
|
||||||
|
];
|
||||||
|
ExecStart = [ "${pkgs.schleuder}/bin/schleuder install" ];
|
||||||
|
Type = "oneshot";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
schleuder-api-daemon = {
|
||||||
|
after = [ "local-fs.target" "network.target" "schleuder-init.service" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
requires = [ "schleuder-init.service" ];
|
||||||
|
serviceConfig = commonServiceConfig // {
|
||||||
|
ExecStart = [ "${pkgs.schleuder}/bin/schleuder-api-daemon" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
schleuder-weekly-key-maintenance = {
|
||||||
|
after = [ "local-fs.target" "network.target" ];
|
||||||
|
startAt = "weekly";
|
||||||
|
serviceConfig = commonServiceConfig // {
|
||||||
|
ExecStart = [
|
||||||
|
"${pkgs.schleuder}/bin/schleuder refresh_keys"
|
||||||
|
"${pkgs.schleuder}/bin/schleuder check_keys"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.etc."schleuder/schleuder.yml" = lib.mkIf (cfg.extraSettingsFile == null) {
|
||||||
|
source = settingsFormat.generate "schleuder.yml" cfg.settings;
|
||||||
|
};
|
||||||
|
environment.etc."schleuder/list-defaults.yml".source = settingsFormat.generate "list-defaults.yml" cfg.listDefaults;
|
||||||
|
|
||||||
|
services.schleuder = {
|
||||||
|
#lists_dir = "/var/lib/schleuder.lists";
|
||||||
|
settings.filters_dir = lib.mkDefault "/var/lib/schleuder/filters";
|
||||||
|
settings.keyword_handlers_dir = lib.mkDefault "/var/lib/schleuder/keyword_handlers";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -485,6 +485,7 @@ in {
|
|||||||
samba = handleTest ./samba.nix {};
|
samba = handleTest ./samba.nix {};
|
||||||
samba-wsdd = handleTest ./samba-wsdd.nix {};
|
samba-wsdd = handleTest ./samba-wsdd.nix {};
|
||||||
sanoid = handleTest ./sanoid.nix {};
|
sanoid = handleTest ./sanoid.nix {};
|
||||||
|
schleuder = handleTest ./schleuder.nix {};
|
||||||
sddm = handleTest ./sddm.nix {};
|
sddm = handleTest ./sddm.nix {};
|
||||||
seafile = handleTest ./seafile.nix {};
|
seafile = handleTest ./seafile.nix {};
|
||||||
searx = handleTest ./searx.nix {};
|
searx = handleTest ./searx.nix {};
|
||||||
|
128
nixos/tests/schleuder.nix
Normal file
128
nixos/tests/schleuder.nix
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
let
|
||||||
|
certs = import ./common/acme/server/snakeoil-certs.nix;
|
||||||
|
domain = certs.domain;
|
||||||
|
in
|
||||||
|
import ./make-test-python.nix {
|
||||||
|
name = "schleuder";
|
||||||
|
nodes.machine = { pkgs, ... }: {
|
||||||
|
imports = [ ./common/user-account.nix ];
|
||||||
|
services.postfix = {
|
||||||
|
enable = true;
|
||||||
|
enableSubmission = true;
|
||||||
|
tlsTrustedAuthorities = "${certs.ca.cert}";
|
||||||
|
sslCert = "${certs.${domain}.cert}";
|
||||||
|
sslKey = "${certs.${domain}.key}";
|
||||||
|
inherit domain;
|
||||||
|
destination = [ domain ];
|
||||||
|
localRecipients = [ "root" "alice" "bob" ];
|
||||||
|
};
|
||||||
|
services.schleuder = {
|
||||||
|
enable = true;
|
||||||
|
# Don't do it like this in production! The point of this setting
|
||||||
|
# is to allow loading secrets from _outside_ the world-readable
|
||||||
|
# Nix store.
|
||||||
|
extraSettingsFile = pkgs.writeText "schleuder-api-keys.yml" ''
|
||||||
|
api:
|
||||||
|
valid_api_keys:
|
||||||
|
- fnord
|
||||||
|
'';
|
||||||
|
lists = [ "security@${domain}" ];
|
||||||
|
settings.api = {
|
||||||
|
tls_cert_file = "${certs.${domain}.cert}";
|
||||||
|
tls_key_file = "${certs.${domain}.key}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = [
|
||||||
|
pkgs.gnupg
|
||||||
|
pkgs.msmtp
|
||||||
|
(pkgs.writeScriptBin "do-test" ''
|
||||||
|
#!${pkgs.runtimeShell}
|
||||||
|
set -exuo pipefail
|
||||||
|
|
||||||
|
# Generate a GPG key with no passphrase and export it
|
||||||
|
sudo -u alice gpg --passphrase-fd 0 --batch --yes --quick-generate-key 'alice@${domain}' rsa4096 sign,encr < <(echo)
|
||||||
|
sudo -u alice gpg --armor --export alice@${domain} > alice.asc
|
||||||
|
# Create a new mailing list with alice as the owner, and alice's key
|
||||||
|
schleuder-cli list new security@${domain} alice@${domain} alice.asc
|
||||||
|
|
||||||
|
# Send an email from a non-member of the list. Use --auto-from so we don't have to specify who it's from twice.
|
||||||
|
msmtp --auto-from security@${domain} --host=${domain} --port=25 --tls --tls-starttls <<EOF
|
||||||
|
Subject: really big security issue!!
|
||||||
|
From: root@${domain}
|
||||||
|
|
||||||
|
I found a big security problem!
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Wait for delivery
|
||||||
|
(set +o pipefail; journalctl -f -n 1000 -u postfix | grep -m 1 'delivered to maildir')
|
||||||
|
|
||||||
|
# There should be exactly one email
|
||||||
|
mail=(/var/spool/mail/alice/new/*)
|
||||||
|
[[ "''${#mail[@]}" = 1 ]]
|
||||||
|
|
||||||
|
# Find the fingerprint of the mailing list key
|
||||||
|
read list_key_fp address < <(schleuder-cli keys list security@${domain} | grep security@)
|
||||||
|
schleuder-cli keys export security@${domain} $list_key_fp > list.asc
|
||||||
|
|
||||||
|
# Import the key into alice's keyring, so we can verify it as well as decrypting
|
||||||
|
sudo -u alice gpg --import <list.asc
|
||||||
|
# And perform the decryption.
|
||||||
|
sudo -u alice gpg -d $mail >decrypted
|
||||||
|
# And check that the text matches.
|
||||||
|
grep "big security problem" decrypted
|
||||||
|
'')
|
||||||
|
|
||||||
|
# For debugging:
|
||||||
|
# pkgs.vim pkgs.openssl pkgs.sqliteinteractive
|
||||||
|
];
|
||||||
|
|
||||||
|
security.pki.certificateFiles = [ certs.ca.cert ];
|
||||||
|
|
||||||
|
# Since we don't have internet here, use dnsmasq to provide MX records from /etc/hosts
|
||||||
|
services.dnsmasq = {
|
||||||
|
enable = true;
|
||||||
|
extraConfig = ''
|
||||||
|
selfmx
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.extraHosts = ''
|
||||||
|
127.0.0.1 ${domain}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# schleuder-cli's config is not quite optimal in several ways:
|
||||||
|
# - A fingerprint _must_ be pinned, it doesn't even have an option
|
||||||
|
# to trust the PKI
|
||||||
|
# - It compares certificate fingerprints rather than key
|
||||||
|
# fingerprints, so renewals break the pin (though that's not
|
||||||
|
# relevant for this test)
|
||||||
|
# - It compares them as strings, which means we need to match the
|
||||||
|
# expected format exactly. This means removing the :s and
|
||||||
|
# lowercasing it.
|
||||||
|
# Refs:
|
||||||
|
# https://0xacab.org/schleuder/schleuder-cli/-/issues/16
|
||||||
|
# https://0xacab.org/schleuder/schleuder-cli/-/blob/f8895b9f47083d8c7b99a2797c93f170f3c6a3c0/lib/schleuder-cli/helper.rb#L230-238
|
||||||
|
systemd.tmpfiles.rules = let cliconfig = pkgs.runCommand "schleuder-cli.yml"
|
||||||
|
{
|
||||||
|
nativeBuildInputs = [ pkgs.jq pkgs.openssl ];
|
||||||
|
} ''
|
||||||
|
fp=$(openssl x509 -in ${certs.${domain}.cert} -noout -fingerprint -sha256 | cut -d = -f 2 | tr -d : | tr 'A-Z' 'a-z')
|
||||||
|
cat > $out <<EOF
|
||||||
|
host: localhost
|
||||||
|
port: 4443
|
||||||
|
tls_fingerprint: "$fp"
|
||||||
|
api_key: fnord
|
||||||
|
EOF
|
||||||
|
''; in
|
||||||
|
[
|
||||||
|
"L+ /root/.schleuder-cli/schleuder-cli.yml - - - - ${cliconfig}"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
machine.wait_for_unit("multi-user.target")
|
||||||
|
machine.wait_until_succeeds("nc -z localhost 4443")
|
||||||
|
machine.succeed("do-test")
|
||||||
|
'';
|
||||||
|
}
|
@ -41,6 +41,20 @@ Gem.paths = { 'GEM_HOME' => #{bundle_path.dump} }
|
|||||||
$LOAD_PATH.unshift #{File.join(bundler_path, "/lib").dump}
|
$LOAD_PATH.unshift #{File.join(bundler_path, "/lib").dump}
|
||||||
|
|
||||||
require 'bundler'
|
require 'bundler'
|
||||||
|
# Monkey-patch out the check that Bundler performs to determine
|
||||||
|
# whether the bundler env is writable. It's not writable, even for
|
||||||
|
# root! And for this use of Bundler, it shouldn't be necessary since
|
||||||
|
# we're not trying to perform any package management operations, only
|
||||||
|
# produce a Gem path. Thus, we replace it with a method that will
|
||||||
|
# always return false, to squelch a warning from Bundler saying that
|
||||||
|
# sudo may be required.
|
||||||
|
module Bundler
|
||||||
|
class <<self
|
||||||
|
def requires_sudo?
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Bundler.setup(#{groups.map(&:dump).join(', ')})
|
Bundler.setup(#{groups.map(&:dump).join(', ')})
|
||||||
|
|
||||||
load Gem.bin_path(#{name.dump}, #{exe.dump})
|
load Gem.bin_path(#{name.dump}, #{exe.dump})
|
||||||
|
3
pkgs/tools/security/schleuder/Gemfile
Normal file
3
pkgs/tools/security/schleuder/Gemfile
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
source 'https://rubygems.org' do
|
||||||
|
gem 'schleuder'
|
||||||
|
end
|
85
pkgs/tools/security/schleuder/Gemfile.lock
Normal file
85
pkgs/tools/security/schleuder/Gemfile.lock
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
GEM
|
||||||
|
specs:
|
||||||
|
|
||||||
|
GEM
|
||||||
|
remote: https://rubygems.org/
|
||||||
|
specs:
|
||||||
|
activemodel (6.1.4.4)
|
||||||
|
activesupport (= 6.1.4.4)
|
||||||
|
activerecord (6.1.4.4)
|
||||||
|
activemodel (= 6.1.4.4)
|
||||||
|
activesupport (= 6.1.4.4)
|
||||||
|
activesupport (6.1.4.4)
|
||||||
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
|
i18n (>= 1.6, < 2)
|
||||||
|
minitest (>= 5.1)
|
||||||
|
tzinfo (~> 2.0)
|
||||||
|
zeitwerk (~> 2.3)
|
||||||
|
bcrypt (3.1.16)
|
||||||
|
charlock_holmes (0.7.7)
|
||||||
|
concurrent-ruby (1.1.9)
|
||||||
|
daemons (1.4.1)
|
||||||
|
eventmachine (1.2.7)
|
||||||
|
gpgme (2.0.20)
|
||||||
|
mini_portile2 (~> 2.3)
|
||||||
|
i18n (1.8.11)
|
||||||
|
concurrent-ruby (~> 1.0)
|
||||||
|
mail (2.7.1)
|
||||||
|
mini_mime (>= 0.1.1)
|
||||||
|
mail-gpg (0.4.4)
|
||||||
|
gpgme (~> 2.0, >= 2.0.2)
|
||||||
|
mail (~> 2.5, >= 2.5.3)
|
||||||
|
mini_mime (1.1.2)
|
||||||
|
mini_portile2 (2.7.1)
|
||||||
|
minitest (5.15.0)
|
||||||
|
multi_json (1.15.0)
|
||||||
|
mustermann (1.1.1)
|
||||||
|
ruby2_keywords (~> 0.0.1)
|
||||||
|
rack (2.2.3)
|
||||||
|
rack-protection (2.1.0)
|
||||||
|
rack
|
||||||
|
rake (13.0.6)
|
||||||
|
ruby2_keywords (0.0.5)
|
||||||
|
schleuder (4.0.2)
|
||||||
|
activerecord (~> 6.1.3)
|
||||||
|
bcrypt (~> 3.1.2)
|
||||||
|
charlock_holmes (~> 0.7.6)
|
||||||
|
gpgme (~> 2.0, >= 2.0.19)
|
||||||
|
mail (~> 2.7.1)
|
||||||
|
mail-gpg (~> 0.3)
|
||||||
|
rake (>= 10.5.0)
|
||||||
|
sinatra (~> 2)
|
||||||
|
sinatra-contrib (~> 2)
|
||||||
|
sqlite3 (~> 1.4.2)
|
||||||
|
thin (~> 1)
|
||||||
|
thor (~> 0)
|
||||||
|
sinatra (2.1.0)
|
||||||
|
mustermann (~> 1.0)
|
||||||
|
rack (~> 2.2)
|
||||||
|
rack-protection (= 2.1.0)
|
||||||
|
tilt (~> 2.0)
|
||||||
|
sinatra-contrib (2.1.0)
|
||||||
|
multi_json
|
||||||
|
mustermann (~> 1.0)
|
||||||
|
rack-protection (= 2.1.0)
|
||||||
|
sinatra (= 2.1.0)
|
||||||
|
tilt (~> 2.0)
|
||||||
|
sqlite3 (1.4.2)
|
||||||
|
thin (1.8.1)
|
||||||
|
daemons (~> 1.0, >= 1.0.9)
|
||||||
|
eventmachine (~> 1.0, >= 1.0.4)
|
||||||
|
rack (>= 1, < 3)
|
||||||
|
thor (0.20.3)
|
||||||
|
tilt (2.0.10)
|
||||||
|
tzinfo (2.0.4)
|
||||||
|
concurrent-ruby (~> 1.0)
|
||||||
|
zeitwerk (2.5.3)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
x86_64-linux
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
schleuder!
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
2.2.24
|
4
pkgs/tools/security/schleuder/cli/Gemfile
Normal file
4
pkgs/tools/security/schleuder/cli/Gemfile
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
source "https://rubygems.org"
|
||||||
|
|
||||||
|
gem "schleuder-cli", git: "https://0xacab.org/schleuder/schleuder-cli", tag: "schleuder-cli-0.1.0"
|
||||||
|
|
21
pkgs/tools/security/schleuder/cli/Gemfile.lock
Normal file
21
pkgs/tools/security/schleuder/cli/Gemfile.lock
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
GIT
|
||||||
|
remote: https://0xacab.org/schleuder/schleuder-cli
|
||||||
|
revision: 1de2548695d9a74f47b7868954561b48cbc966f9
|
||||||
|
tag: schleuder-cli-0.1.0
|
||||||
|
specs:
|
||||||
|
schleuder-cli (0.1.0)
|
||||||
|
thor (~> 0)
|
||||||
|
|
||||||
|
GEM
|
||||||
|
remote: https://rubygems.org/
|
||||||
|
specs:
|
||||||
|
thor (0.20.3)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
x86_64-linux
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
schleuder-cli!
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
2.3.6
|
34
pkgs/tools/security/schleuder/cli/default.nix
Normal file
34
pkgs/tools/security/schleuder/cli/default.nix
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{ lib
|
||||||
|
, bundlerApp
|
||||||
|
, ruby
|
||||||
|
, bundlerUpdateScript
|
||||||
|
}:
|
||||||
|
|
||||||
|
bundlerApp {
|
||||||
|
inherit ruby;
|
||||||
|
|
||||||
|
pname = "schleuder-cli";
|
||||||
|
|
||||||
|
gemdir = ./.;
|
||||||
|
|
||||||
|
installManpages = false;
|
||||||
|
|
||||||
|
exes = [
|
||||||
|
"schleuder-cli"
|
||||||
|
];
|
||||||
|
|
||||||
|
passthru.updateScript = bundlerUpdateScript "schleuder-cli";
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "A command line tool to create and manage schleuder-lists";
|
||||||
|
longDescription = ''
|
||||||
|
Schleuder-cli enables creating, configuring, and deleting lists,
|
||||||
|
subscriptions, keys, etc. It uses the Schleuder API, provided by
|
||||||
|
schleuder-api-daemon (part of Schleuder).
|
||||||
|
'';
|
||||||
|
homepage = "https://schleuder.org";
|
||||||
|
changelog = "https://0xacab.org/schleuder/schleuder-cli/-/blob/main/CHANGELOG.md";
|
||||||
|
license = licenses.gpl3Plus;
|
||||||
|
maintainers = with maintainers; [ hexa ];
|
||||||
|
};
|
||||||
|
}
|
25
pkgs/tools/security/schleuder/cli/gemset.nix
Normal file
25
pkgs/tools/security/schleuder/cli/gemset.nix
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
schleuder-cli = {
|
||||||
|
dependencies = ["thor"];
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
fetchSubmodules = false;
|
||||||
|
rev = "1de2548695d9a74f47b7868954561b48cbc966f9";
|
||||||
|
sha256 = "0k4i33w9a0bscw4wbs301vxca367g7pa89y6cr24i0014pbmhs9z";
|
||||||
|
type = "git";
|
||||||
|
url = "https://0xacab.org/schleuder/schleuder-cli";
|
||||||
|
};
|
||||||
|
version = "0.1.0";
|
||||||
|
};
|
||||||
|
thor = {
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "1yhrnp9x8qcy5vc7g438amd5j9sw83ih7c30dr6g6slgw9zj3g29";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "0.20.3";
|
||||||
|
};
|
||||||
|
}
|
38
pkgs/tools/security/schleuder/default.nix
Normal file
38
pkgs/tools/security/schleuder/default.nix
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{ lib
|
||||||
|
, bundlerApp
|
||||||
|
, ruby
|
||||||
|
, bundlerUpdateScript
|
||||||
|
, defaultGemConfig
|
||||||
|
, nixosTests
|
||||||
|
}:
|
||||||
|
|
||||||
|
bundlerApp {
|
||||||
|
inherit ruby;
|
||||||
|
|
||||||
|
pname = "schleuder";
|
||||||
|
|
||||||
|
gemdir = ./.;
|
||||||
|
|
||||||
|
exes = [
|
||||||
|
"schleuder"
|
||||||
|
"schleuder-api-daemon"
|
||||||
|
];
|
||||||
|
|
||||||
|
passthru.updateScript = bundlerUpdateScript "schleuder";
|
||||||
|
passthru.tests = {
|
||||||
|
inherit (nixosTests) schleuder;
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Schleuder is an encrypting mailing list manager with remailing-capabilities";
|
||||||
|
longDescription = ''
|
||||||
|
Schleuder is a group's email-gateway: subscribers can exchange
|
||||||
|
encrypted emails among themselves, receive emails from
|
||||||
|
non-subscribers and send emails to non-subscribers via the list.
|
||||||
|
'';
|
||||||
|
homepage = "https://schleuder.org";
|
||||||
|
changelog = "https://0xacab.org/schleuder/schleuder/blob/main/CHANGELOG.md";
|
||||||
|
license = licenses.gpl3Plus;
|
||||||
|
maintainers = with maintainers; [ hexa lheckemann ];
|
||||||
|
};
|
||||||
|
}
|
316
pkgs/tools/security/schleuder/gemset.nix
Normal file
316
pkgs/tools/security/schleuder/gemset.nix
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
{
|
||||||
|
activemodel = {
|
||||||
|
dependencies = ["activesupport"];
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "0g3qdz8dw6zkgz45jd13lwfdnm7rhgczv1pssw63g9k6qj3bkxjm";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "6.1.4.4";
|
||||||
|
};
|
||||||
|
activerecord = {
|
||||||
|
dependencies = ["activemodel" "activesupport"];
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "090d4wl1pq06m9mibpck0m5nm8h45fwhs3fjx27297kjmnv4gzik";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "6.1.4.4";
|
||||||
|
};
|
||||||
|
activesupport = {
|
||||||
|
dependencies = ["concurrent-ruby" "i18n" "minitest" "tzinfo" "zeitwerk"];
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "0rvnz9lsf9mrkpji748sf51f54m027snkw6rm8flyvf7fq18rm98";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "6.1.4.4";
|
||||||
|
};
|
||||||
|
bcrypt = {
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "02r1c3isfchs5fxivbq99gc3aq4vfyn8snhcy707dal1p8qz12qb";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "3.1.16";
|
||||||
|
};
|
||||||
|
charlock_holmes = {
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "0hybw8jw9ryvz5zrki3gc9r88jqy373m6v46ynxsdzv1ysiyr40p";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "0.7.7";
|
||||||
|
};
|
||||||
|
concurrent-ruby = {
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "0nwad3211p7yv9sda31jmbyw6sdafzmdi2i2niaz6f0wk5nq9h0f";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "1.1.9";
|
||||||
|
};
|
||||||
|
daemons = {
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "07cszb0zl8mqmwhc8a2yfg36vi6lbgrp4pa5bvmryrpcz9v6viwg";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "1.4.1";
|
||||||
|
};
|
||||||
|
eventmachine = {
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "0wh9aqb0skz80fhfn66lbpr4f86ya2z5rx6gm5xlfhd05bj1ch4r";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "1.2.7";
|
||||||
|
};
|
||||||
|
gpgme = {
|
||||||
|
dependencies = ["mini_portile2"];
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "0xbgh9d8nbvsvyzqnd0mzhz0nr9hx4qn025kmz6d837lry4lc6gw";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "2.0.20";
|
||||||
|
};
|
||||||
|
i18n = {
|
||||||
|
dependencies = ["concurrent-ruby"];
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "0vdd1kii40qhbr9n8qx71k2gskq6rkl8ygy8hw5hfj8bb5a364xf";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "1.8.11";
|
||||||
|
};
|
||||||
|
mail = {
|
||||||
|
dependencies = ["mini_mime"];
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "00wwz6ys0502dpk8xprwcqfwyf3hmnx6lgxaiq6vj43mkx43sapc";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "2.7.1";
|
||||||
|
};
|
||||||
|
mail-gpg = {
|
||||||
|
dependencies = ["gpgme" "mail"];
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "1rz936m8nacy7agksvpvkf6b37d1h5qvh5xkrjqvv5wbdqs3cyfj";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "0.4.4";
|
||||||
|
};
|
||||||
|
mini_mime = {
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "0lbim375gw2dk6383qirz13hgdmxlan0vc5da2l072j3qw6fqjm5";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "1.1.2";
|
||||||
|
};
|
||||||
|
mini_portile2 = {
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "0d3ga166pahsxavzwj19yjj4lr13rw1vsb36s2qs8blcxigrdp6z";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "2.7.1";
|
||||||
|
};
|
||||||
|
minitest = {
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "06xf558gid4w8lwx13jwfdafsch9maz8m0g85wnfymqj63x5nbbd";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "5.15.0";
|
||||||
|
};
|
||||||
|
multi_json = {
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "0pb1g1y3dsiahavspyzkdy39j4q377009f6ix0bh1ag4nqw43l0z";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "1.15.0";
|
||||||
|
};
|
||||||
|
mustermann = {
|
||||||
|
dependencies = ["ruby2_keywords"];
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "0ccm54qgshr1lq3pr1dfh7gphkilc19dp63rw6fcx7460pjwy88a";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "1.1.1";
|
||||||
|
};
|
||||||
|
rack = {
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "0i5vs0dph9i5jn8dfc6aqd6njcafmb20rwqngrf759c9cvmyff16";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "2.2.3";
|
||||||
|
};
|
||||||
|
rack-protection = {
|
||||||
|
dependencies = ["rack"];
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "159a4j4kragqh0z0z8vrpilpmaisnlz3n7kgiyf16bxkwlb3qlhz";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "2.1.0";
|
||||||
|
};
|
||||||
|
rake = {
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "15whn7p9nrkxangbs9hh75q585yfn66lv0v2mhj6q6dl6x8bzr2w";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "13.0.6";
|
||||||
|
};
|
||||||
|
ruby2_keywords = {
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "1vz322p8n39hz3b4a9gkmz9y7a5jaz41zrm2ywf31dvkqm03glgz";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "0.0.5";
|
||||||
|
};
|
||||||
|
schleuder = {
|
||||||
|
dependencies = ["activerecord" "bcrypt" "charlock_holmes" "gpgme" "mail" "mail-gpg" "rake" "sinatra" "sinatra-contrib" "sqlite3" "thin" "thor"];
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "15j1rfkfvni82msamikynsg48s50hbsx1pxm3y967caq9s80ll6c";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "4.0.2";
|
||||||
|
};
|
||||||
|
sinatra = {
|
||||||
|
dependencies = ["mustermann" "rack" "rack-protection" "tilt"];
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "0dd53rzpkxgs697pycbhhgc9vcnxra4ly4xar8ni6aiydx2f88zk";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "2.1.0";
|
||||||
|
};
|
||||||
|
sinatra-contrib = {
|
||||||
|
dependencies = ["multi_json" "mustermann" "rack-protection" "sinatra" "tilt"];
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "1rl1iiafz51yzjd0vchl2lni7lmwppjql6cn1fnfxbma707qlcja";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "2.1.0";
|
||||||
|
};
|
||||||
|
sqlite3 = {
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "0lja01cp9xd5m6vmx99zwn4r7s97r1w5cb76gqd8xhbm1wxyzf78";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "1.4.2";
|
||||||
|
};
|
||||||
|
thin = {
|
||||||
|
dependencies = ["daemons" "eventmachine" "rack"];
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "123bh7qlv6shk8bg8cjc84ix8bhlfcilwnn3iy6zq3l57yaplm9l";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "1.8.1";
|
||||||
|
};
|
||||||
|
thor = {
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "1yhrnp9x8qcy5vc7g438amd5j9sw83ih7c30dr6g6slgw9zj3g29";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "0.20.3";
|
||||||
|
};
|
||||||
|
tilt = {
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "0rn8z8hda4h41a64l0zhkiwz2vxw9b1nb70gl37h1dg2k874yrlv";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "2.0.10";
|
||||||
|
};
|
||||||
|
tzinfo = {
|
||||||
|
dependencies = ["concurrent-ruby"];
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "10qp5x7f9hvlc0psv9gsfbxg4a7s0485wsbq1kljkxq94in91l4z";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "2.0.4";
|
||||||
|
};
|
||||||
|
zeitwerk = {
|
||||||
|
groups = ["default"];
|
||||||
|
platforms = [];
|
||||||
|
source = {
|
||||||
|
remotes = ["https://rubygems.org"];
|
||||||
|
sha256 = "0lmg9x683gr9mkrbq9df2m0zb0650mdfxqna0bs10js44inv7znx";
|
||||||
|
type = "gem";
|
||||||
|
};
|
||||||
|
version = "2.5.3";
|
||||||
|
};
|
||||||
|
}
|
@ -5557,6 +5557,10 @@ with pkgs;
|
|||||||
conf = config.schildichat-web.conf or {};
|
conf = config.schildichat-web.conf or {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
schleuder = callPackage ../tools/security/schleuder { };
|
||||||
|
|
||||||
|
schleuder-cli = callPackage ../tools/security/schleuder/cli { };
|
||||||
|
|
||||||
tealdeer = callPackage ../tools/misc/tealdeer {
|
tealdeer = callPackage ../tools/misc/tealdeer {
|
||||||
inherit (darwin.apple_sdk.frameworks) Security;
|
inherit (darwin.apple_sdk.frameworks) Security;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user