Go to file
s3lph a02f2d9e68
All checks were successful
/ build_wheel (push) Successful in 2m5s
/ build_debian (push) Successful in 2m38s
/ test (push) Successful in 1m22s
/ codestyle (push) Successful in 1m21s
/ mypy (push) Successful in 1m30s
/ schleuder (push) Successful in 4m2s
feat: migrate from woodpecker to forgejo actions
2023-12-19 08:31:26 +01:00
.forgejo/workflows feat: migrate from woodpecker to forgejo actions 2023-12-19 08:31:26 +01:00
multischleuder feat: migrate from woodpecker to forgejo actions 2023-12-19 08:31:26 +01:00
package/debian/multischleuder feat: migrate from woodpecker to forgejo actions 2023-12-19 08:31:26 +01:00
test fix(ci): remove obsolete schleuder-cli workaround 2023-08-12 14:58:57 +02:00
.gitignore Add test case with real schleuder 2022-04-17 00:26:14 +02:00
CHANGELOG.md feat: migrate from woodpecker to forgejo actions 2023-12-19 08:31:26 +01:00
LICENSE Add LICENSE 2022-04-14 02:52:47 +00:00
README.md feat: migrate from woodpecker to forgejo actions 2023-12-19 08:31:26 +01:00
setup.cfg Cleanup, proper project setup, codestyle & typechecking 2022-04-14 04:46:14 +02:00
setup.py fix(ci): add missing deepdiff dependency 2023-08-12 14:59:34 +02:00

MultiSchleuder

Automatically and periodically merge subscribers and keys of multiple Schleuder lists into one.

Dependencies

  • python-dateutil, because where would we be without it?
  • PGPy: For sending encrypted messages
  • PyYAML: For parsing the config file

Installation

You can find Debian packages and Python wheels over at Packages.

Configuration

In the Debian package, the config file lives at /etc/multischleuder/multischleuder.yml

---

# Configure this to talk to your schleuder-api-daemon.
api:
  url: "https://localhost:4443"
  token: "130a8c095d14fa51e73727e9d8ef5db3a3bf0cae7d995c1f"
  cafile: /etc/multischleuder/schleuder-ca.pem

lists:

    # The Schleuder list to manage.  Must exist
  - target: global@schleuder.example.org
    unmanaged:
      # Adresses to ignore everywhere.  Usually you want to
      # put the admins of your target Schleuder here, in order
      # to prevent them from becoming unsubscribed.
      - admin@example.org
    banned:
      # If for some reason, you need to ban a subscriber from the
      # target list only, put them here
      - banned@example.org
    sources:
      # The Schleuder lists to take subscribers and keys from.
      # They must already exist.
      - east@schleuder.example.org
      - west@schleuder.example.org
      - north@schleuder.example.org
      - south@schleuder.example.org
    # When sending mails, use this as the sender address.  If absent,
    # the -owner address is used.
    from: global-owner@schleuder.example.org
    # Whether to notify subscribers of key or email address conflicts.
    send_conflict_messages: yes
    # Whether to notify the target Schleuder's admins about changes.
    send_admin_reports: yes

# Hook this up to your MTA, 
smtp:
  hostname: localhost  # default: localhost
  port: 10025  # default: 25
  tls: PLAIN  # PLAIN|STARTTLS|SMTPS; default: PLAIN
  username: admin     # optional
  password: password  # optional

conflict:
  # How often to notify users about conflicts
  interval: 604800  # 1 week
  # The file where Schleuder memorizes when it has last sent messages for
  # which conflicts
  statefile: /var/lib/multischleuder/conflict.json
  # The template used when sending mails to a subscriber involved in a key conflict
  # (multiple keys used by the same subscriber).  You can use the following fields:
  #   {subscriber}:  Email address of the affected subscriber
  #   {schleuder}:   Name (email) of the target Schleuder
  #   {chosen}:      The key that was chosen to subscribe to the target Schleuder
  #   {affected}:    A list of "fingerprint: source schleuder" candidates involved
  #                  in the conflict.
  key_template: |
    Hi {subscriber},
    
    While compiling the subscriber list of {schleuder}, your
    address {subscriber} was subscribed on multiple sub-lists with
    different PGP keys.  There may be something fishy or malicious going on,
    or this may simply have been a mistake by you or a list admin.
    
    You have only been subscribed to {schleuder} using the key you
    have been subscribed with for the *longest* time:
      
    {chosen}
      
    Please review the following keys and talk to the admins of the
    corresponding sub-lists to resolve this issue:
    
    Fingerprint                               Sub-List
    -----------                               --------
    {affected}    
  
    For your convenience, this message has been encrypted with *all* of the
    above keys.  If you have any questions, or do not understand this
    message, please refer to your local Schleuder admin, or reply to this
    message.
  
    Regards
    MultiSchleuder {schleuder}
  # The template used when sending mails to subscribers involved in a user conflict
  # (multiple subscribers using the same key).  You can use the following fields:
  #   {subscriber}:  Email address of the subscriber addressed in this email
  #   {fingerprint}: Fingerprint of the key used multiple times
  #   {schleuder}:   Name (email) of the target Schleuder
  #   {chosen}:      The email that was chosen to subscribe to the target Schleuder
  #   {affected}:    A list of "email address: source schleuder" candidates involved
  #                  in the conflict.
  user_template: |
    Hi {subscriber},
    
    While compiling the subscriber list of {schleuder}, your
    key {fingerprint} was used by subscribers on multiple sub-lists with
    different email adresses.  There may be something fishy or malicious
    going on, or this may simply have been a mistake by you or a list admin.
    
    You have only been subscribed to {schleuder} using the address you
    have been subscribed with for the *longest* time:
      
    {chosen}
      
    Please review the following adresses and talk to the admins of the
    corresponding sub-lists to resolve this issue:
    
    Adress                     Sub-List
    ------                     --------
    {affected}    
  
    For your convenience, this message has been sent to *all* of the above
    adresses.  If you have any questions, or do not understand this
    message, please refer to your local Schleuder admin, or reply to this
    message.
  
    Regards
    MultiSchleuder {schleuder}

Usage

multischleuder --config path/to/multischleuder.yml 

Multischleuder also comes with a dry-run mode:

multischleuder --config path/to/multischleuder.yml --dry-run

And to increase the log level:

multischleuder --config path/to/multischleuder.yml --verbose

Conflict Resolution

Schleuder is quite restrictive when it comes to mapping subscriptions to keys and vice versa:

  • A key (identified by its fingerprint) can only be used by one subscriber, even if the key has multiple uids.
  • A subscriber can only be subscribed using a single key, even if multiple keys with the same uid are in the keyring.

This can lead to conflicts when merging multiple lists, because these properties don't necessarily hold up for the union of all sublist subscribers and keys.

MultiSchleuder resolves conflicts in a simple, but primitive manner:

  1. First it checks whether two or more subscribers are using the same key. If so, the oldest subscription wins, the other subscribers are not subscribed to the target list.
  2. Then it checks whether a subscriber has more than one key. If so, the key used by the oldest subscription wins.

This is by no means a perfect solution. It does however yield consistent results. In both cases, if configured to do so, MultiSchleuder will send a notification message to all subscribers involved in a conflict, encrypting it with all keys involved in the conflict. If one or more keys are - for whatever reason - unusable, the message will not be encrypted. This is a deliberate decision, since the amount of metadata possibly leaked from such a message is fairly small, and we consider it worth taking this risk, given that the other possibility would be to not notify a subscriber when something potentially malicious is going on.