renamed gpgpy-ezmlm to crypto-ezmlm

This commit is contained in:
lars 2007-04-04 23:29:03 +00:00
parent e4d82256e7
commit ee170fc7da
11 changed files with 1397 additions and 0 deletions

View file

@ -0,0 +1,330 @@
#!/usr/bin/env python2.4
#
# This file is part of gpgpy-ezmlm - an encryption filter for the
# ezmlm-idx mailinglist manager.
#
# Copyright 02007 Sense.Lab e.V. <info@senselab.org>
#
# This script decrypts an incoming mail and encrypts it for each recipient
# separately. Afterwards it calls qmail-queue for each recipient.
# It is meant as a wrapper around qmail-queue. See 'man qmail-queue' for
# details of the qmail-queue interface.
#
# Syntax:
# gpgpy-ezmlm-encrypt [MAILINGLIST_DIRECTORY]
#
# If no MAILINGLIST_DIRECTORY is given, then it will only run some self-tests.
#
# Environment settings:
# - QMAILQUEUE should contain the path of the qmail-queue program (or a
# substitute - e.g. for spam filtering) - otherwise the default location
# /var/qmail/bin/qmail-queue is used
#
#
# gpgpy-ezmlm is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# gpgpy-ezmlm is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with the CryptoBox; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# TODO: implement 'sign_messages' setting
import sys, os, re
import email
import email.Parser
import email.Message
import subprocess
############### some default settings ##################
## we will finally deliver via the original qmail-queue
if os.environ.has_key("QMAILQUEUE"):
QMAILQUEUE_BIN = os.environ["QMAILQUEUE"]
else:
QMAILQUEUE_BIN = '/var/qmail/bin/qmail-queue'
## the list specific configuration file
CONF_FILE = 'conf-gpgpy'
## default settings - the setting keys must always be lower case!
DEFAULT_SETTINGS = {
"plain_without_key": False,
"sign_messages": False,
"gnupg_dir": ".gnupg"
}
## put this warning into a mail instead of the encrypted content, in case
## the key of the recipient is missing
NOKEY_WARNING = "No valid encryption key found!"
## in case of 'cannot decrypt' errors
DECRYPT_ERROR = "Failed to decrypt the mail that was sent to the mailinglist. Please check the configuration of the mailinglist. Maybe the sender used an invalid encryption key?"
################ the encryption handler ################
class MailEncryption:
def __init__(self, list_dir):
self.list_dir = os.path.abspath(list_dir)
## does the list directory exist?
if not os.access(self.list_dir, os.X_OK):
internal_error("Could not access mailinglist directory: %s" \
% self.list_dir)
## read the config file
self.config = self.read_config()
## does the gnupg directory exist?
if not os.access(self.config["gnupg_dir"], os.X_OK):
internal_error("Could not access gnupg directory: %s" \
% self.config["gnupg_dir"])
## set GPGHOME environment - this should be used by pyme
os.environ["GNUPGHOME"] = self.config["gnupg_dir"]
## we _must_ import pyme after configuring the GNUPGHOME setting
import pyme.core
self.pyme = pyme
self.context = self.pyme.core.Context()
self.context.set_armor(1)
def read_config(self):
"""Read the config file.
If a value is not defined in the config file, then the default value
is used.
Any line that does not really look like a config setting is ignored.
Any unknown configuration settings are ignored, too.
"""
result = DEFAULT_SETTINGS
## retrieve the absolute path of the configuration file
## by default it is relative to the mailinglist's directory
if os.path.isabs(CONF_FILE):
conf_file = CONF_FILE
else:
conf_file = os.path.join(self.list_dir, CONF_FILE)
if not os.access(conf_file, os.R_OK):
internal_error("Could not read gpgpy-ezmlm config file: %s" % conf_file)
## read all lines of the configuration file
all_lines = [ e.strip() for e in file(conf_file).readlines() ]
for line in all_lines:
## ignore empty lines, comments and lines without "="
if (not line) or e.startswith("#") or (e.find("=") == -1):
continue
key, value = line.split("=", 1)
## turn everything to lower case and remove surrounding whitespace
key, value = (key.strip().lower(), value.strip())
if (len(value) > 1) and \
((value.startswith('"') and value.endswith('"')) \
or (value.startswith("'") and value.endswith("'"))):
value = value[1:-1]
## ignore empty values or keys
if not key or not value:
continue
## check boolean values
if key in ['plain_without_key', 'sign_messages']:
if value.lower() == 'no':
result[key] = False
elif value.lower() == 'yes':
result[key] = True
else:
continue
## process the key directory
elif key == 'gnupg_dir':
result[key] = value
## unknown setting - ignore
else:
continue
if result["gnupg_dir"].startswith('~'):
result["gnupg_dir"] = os.path.expanduser(result["gnupg_dir"])
elif not os.path.isabs(result["gnupg_dir"]):
result["gnupg_dir"] = os.path.abspath(os.path.join(
self.list_dir, result["gnupg_dir"]))
return result
def get_valid_keys(self, pattern=""):
return [ key for key in self.context.op_keylist_all(pattern, 0)
if (key.can_encrypt != 0) ]
def encrypt_to_keys(self, plain, keylist):
plaindata = self.pyme.core.Data(plain)
cipher = self.pyme.core.Data(plain)
self.context.op_encrypt(keylist, 1, plaindata, cipher)
cipher.seek(0, 0)
return cipher.read()
def reencrypt_mail(self, mail, keys):
if mail.is_multipart():
payloads = mail.get_payload()
index = 0
while index < len(payloads):
if self.is_encrypted(payloads[index].get_payload()):
decrypted_part = email.message_from_string(
self.decrypt_block(payloads[index].get_payload()))
if keys:
payloads[index].set_payload(self.encrypt_to_keys(
decrypted_part.as_string(), keys))
else:
if self.config["plain_without_key"]:
payloads[index].set_payload(decrypted_part.as_string())
else:
payloads[index].set_payload(NOKEY_WARNING)
index += 1
else:
if self.is_encrypted(mail.get_payload()):
if keys:
mail.set_payload(self.encrypt_to_keys(
self.decrypt_block(mail.get_payload()), keys))
else:
if self.config["plain_without_key"]:
mail.set_payload(self.decrypt_block(mail.get_payload()))
else:
mail.set_payload(NOKEY_WARNING)
def is_encrypted(self, text):
return text.find("-----BEGIN PGP MESSAGE-----") != -1
def decrypt_block(self, text):
cipher = self.pyme.core.Data(text)
plain = self.pyme.core.Data()
try:
self.context.op_decrypt(cipher, plain)
except self.pyme.errors.GPGMEError:
## decryption failed - we do not do anything
plain = self.pyme.core.Data(DECRYPT_ERROR)
plain.seek(0, 0)
return plain.read()
def process_mail(self, sender, recipient, mail_text):
"""Decrypt the mail and encrypt it again for the specified recipient
"""
mail = email.message_from_string(mail_text)
keys = self.get_valid_keys(recipient)
## reencrypt the whole mail for the specific recipient
self.reencrypt_mail(mail, keys)
## use tmpfile as input for qmail-queue
## we have to complicate things a little bit, as qmail-queue expects input
## at file handle 1 - this is usually stdout
tmpfile = os.tmpfile()
tmpfile.write('F%s\0T%s\0\0' % (sender, recipient))
tmpfile.seek(0)
## execute the original qmail-queue
proc = subprocess.Popen(
shell = False,
stdin = subprocess.PIPE,
stdout = tmpfile.fileno(),
env = os.environ,
args = [ QMAILQUEUE_BIN ] )
proc.stdin.write(mail.as_string())
## tmpfile is deleted automatically after closing
tmpfile.close()
proc.stdin.close()
proc.wait()
## exit immediately, if qmail-queue failed once
if proc.returncode != 0:
sys.exit(proc.returncode)
#################### input/output stuff ###################
def internal_error(message=None, exitcode=81):
if message:
sys.stderr.write(message + "\n")
sys.exit(exitcode)
def process_input_and_output(handler):
"""Read mail content and the envelopement information from fd1 and fd2
see 'main qmail-queue' for details
"""
in_mail = os.fdopen(0, "r")
in_envelope = os.fdopen(1, "rb")
## try to read mail and
try:
mail_text = in_mail.read()
envelope = in_envelope.read()
except IOError:
## report "Unable to read the message or envelope." (see 'man qmail-queue')
sys.exit(54)
## see 'man qmail-queue' for details of the envelope format
envelope_addresses = re.match(u'F(.+?)\0((?:T[^\0]+?\0)+)\0$', envelope)
if not envelope_addresses or (len(envelope_addresses.groups()) != 2):
## report "Envelope format error." (see 'man qmail-queue')
sys.exit(91)
## the first match is the sender address
envelope_sender = envelope_addresses.groups()[0]
## the second match is the list of all recipients
## each preceded by "T" and followed by "\0"
envelope_recipients = envelope_addresses.groups()[1].split("\0")
## remove leading "T" and skip empty values
envelope_recipients = [ e[1:] for e in envelope_recipients if e ]
for recipient in envelope_recipients:
handler.process_mail(envelope_sender, recipient, mail_text)
def check_for_errors():
errors = False
## check the original qmail-queue binary
if not os.access(QMAILQUEUE_BIN, os.X_OK):
sys.stderr.write("Could not find executable qmail-queue: %s\n" % QMAILQUEUE_BIN)
errors = True
## check the existence of the pyme module
try:
import pyme
except ImportError:
sys.stderr.write("Failed to import python-pyme!\n")
errors = True
## check if the subprocess module is available (python >= 2.4)
try:
import subprocess
except ImportError:
sys.stderr.write("Failed to import the python module 'subprocess'! It requires python2.4.\n")
errors = True
return errors == False
if __name__ == '__main__':
if not check_for_errors():
internal_error()
if len(sys.argv) == 1:
## we were only supposed to run the self-tests - exiting successfully
sys.exit(0)
## we expect exactly one parameter - the mailinglist directory
if len(sys.argv) != 2:
internal_error("More than one parameter (the mailinglist directory) given!")
## print some help if it was requested
if sys.argv[0] == '--help':
sys.stderr.write("Syntax: %s [MAILINGLIST_DIRECTORY]\n\n" % \
os.path.basename(sys.argv[0]))
sys.stderr.write("If you omit the MAILINGLIST_DIRECTORY, " \
+ "then only some self-tests are done.\n\n")
sys.exit(0)
## retrieve the mailing list directory by reading the dotqmail file
list_dir = sys.argv[1]
## does the mailinglist directory exist?
if not os.access(list_dir, os.X_OK):
internal_error("Could not access the mailinglist directory: %s" % list_dir)
## reencrypt the mail for each recipient
mail_handler = MailEncryption(list_dir)
process_input_and_output(mail_handler)

View file

@ -0,0 +1,285 @@
#!/usr/bin/env python2.4
#
# This file is part of gpgpy-ezmlm - an encryption filter for the
# ezmlm-idx mailinglist manager.
#
# Copyright 02007 Sense.Lab e.V. <info@senselab.org>
#
# This script converts an existing plaintext ezmlm mailing list into an
# encrypted mailing list. This change does not interfere with the useal
# operation of ezmlm-idx.
#
# Syntax:
# gpgpy-ezmlm-manage MAILINGLIST_DIRECTORY [enable|disable]
# enable or disable encryption for the list
#
# gpgpy-ezmlm-manage MAILINGLIST_DIRECTORY is_encrypted
# check if encryption for this mailing list is enabled (exitcode = 0)
#
# gpgpy-ezmlm-manage MAILINGLIST_DIRECTORY genkey [NAME [COMMENT [MAIL_ADDRESS]]]
# generate the secret key of a list
# NAME, COMMENT and MAIL_ADDRESS are optional parameters - otherwise
# reasonable default values are generated
#
# gpgpy-ezmlm-manage MAILINGLIST_DIRECTORY get_gnupg_dir
# return the directory containing the keys of this list
#
# If no MAILINGLIST_DIRECTORY is given, then it will only run some self-tests.
#
#
# gpgpy-ezmlm is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# gpgpy-ezmlm is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with the CryptoBox; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
## config file inside of a mailing list directory
CONF_FILE = "conf-gpgpy"
## default gnupg directory relative to a mailing list directory
DEFAULT_GNUPG_DIR = ".gnupg"
## default settings for mailing lists
CONFIG_SETTINGS = """plain_without_key = no
sign_messages = no
gnupg_dir = %s
""" % DEFAULT_GNUPG_DIR
## settings for new keys
GENERATE_KEY_SETTINGS = """
<GnupgKeyParms format="internal">
Key-Type: DSA
Key-Length: 1024
Subkey-Type: ELG-E
Subkey-Length: 4096
Name-Real: %(name)s
Name-Comment: %(comment)s
Name-Email: %(mail)s
</GnupgKeyParms>
"""
import sys, os
def check_for_errors():
"""Check for environmental problems
"""
errors = False
try:
import pyme
except ImportError:
sys.stderr.write("Failed to import the python module 'pyme'.\n")
errors = True
return errors == False
def enable_encryption(list_dir):
"""Turn on encryption for a mailing list
"""
conf_file = os.path.join(list_dir, CONF_FILE)
if not os.path.isfile(conf_file):
try:
new_file = file(conf_file, "w")
new_file.write(CONFIG_SETTINGS)
new_file.close()
except IOError, err_msg:
sys.stderr.write("Failed to write the gpgpy-ezmlm configuration " \
+ "file (%s): %s\n" % (conf_file, err_msg))
return False
return True
def disable_encryption(list_dir):
"""Turn off encryption for a mailing list
Secret and public keys are not removed.
"""
conf_file = os.path.join(list_dir, CONF_FILE)
if os.path.isfile(conf_file):
try:
os.remove(conf_file)
except OSError, err_msg:
sys.stderr.write("Failed to delete the gpgpy-ezmlm configuration" \
+ " file (%s): %s\n" % (conf_file, err_msg))
return False
return True
def is_encrypted(list_dir):
"""Check if the mailing list is encrypted or not
"""
conf_file = os.path.join(list_dir, CONF_FILE)
return os.path.isfile(conf_file)
def get_gnupg_setting(list_dir):
conf_file = os.path.join(list_dir, CONF_FILE)
gnupg_setting = DEFAULT_GNUPG_DIR
if os.path.isfile(conf_file):
for line in file(conf_file).readlines():
key, value = line.split("=", 1)
key, value = (key.strip().lower(), value.strip())
## remove surrounding quotes
if (len(value) > 1) and \
((value.startswith('"') and value.endswith('"')) \
or (value.startswith("'") and value.endswith("'"))):
value = value[1:-1]
if key == 'gnupg_dir':
gnupg_setting = value
break
if gnupg_setting.startswith('~'):
return os.path.expanduser(gnupg_setting)
elif os.path.isabs(gnupg_setting):
return gnupg_setting
else:
return os.path.realpath(os.path.join(list_dir, gnupg_setting))
def get_mail_address_of_list(list_dir):
local_file = os.path.join(list_dir, "outlocal")
host_file = os.path.join(list_dir, "outhost")
local_mail = ""
host_mail = ""
if os.access(local_file, os.R_OK):
try:
local_mail = file(local_file).read().strip()
except IOError:
pass
if os.access(host_file, os.R_OK):
try:
host_mail = file(host_file).read().strip()
except IOError:
pass
if local_mail and host_mail:
return "%s@%s" % (local_mail, host_mail)
elif local_mail:
return local_mail
elif host_mail:
return host_mail
else:
return "unknown"
def generate_key(list_dir, name, comment, mail):
os.environ["GNUPGHOME"] = get_gnupg_setting(list_dir)
import pyme
import pyme.core
import re
context = pyme.core.Context()
context.set_armor(1)
context.set_progress_cb(None, None)
values = { "name": name, "comment": comment, "mail": mail }
if not name:
values["name"] = "Mailing list %s" % os.path.basename(list_dir)
if not comment:
values["comment"] = "encrypted"
if not mail:
values["mail"] = get_mail_address_of_list(list_dir)
bad_characters = re.compile("([\(\)<>])")
for key, value in values.items():
if bad_characters.search(value):
sys.stderr.write("The description (%s) of the key to be " % key \
+ "generated contains invalid characters: '%s'\n" % \
str(bad_characters.search(value).groups()[0]))
return False
key_settings = GENERATE_KEY_SETTINGS % values
try:
context.op_genkey(key_settings, None, None)
except pyme.errors.GPGMEError, err_msg:
sys.stderr.write("Failed to create the gnupg key: %s\n" % err_msg)
return False
return True
def check_mailinglist_directory(list_dir):
"""Check if the given directory contains an ezmlm mailing list
"""
## does the mailing list directory exist?
if not os.path.isdir(list_dir):
sys.stderr.write("The mailing list directory does not exist: %s\n" % list_dir)
return False
## is the mailing list directory accessible?
if not os.access(list_dir, os.X_OK):
sys.stderr.write("Could not access the mailing list directory: %s\n" % list_dir)
return False
if not os.path.isfile(os.path.join(list_dir, 'lock')):
sys.stderr.write("The directory (%s) does not seem to" % list_dir \
+ " contain an ezmlm mailing list.\n")
return False
return True
def output_help():
prog_name = os.path.basename(sys.argv[0])
print "Syntax:"
print "\t%s MAILINGLIST_DIRECTORY [enable|disable]" % prog_name
print "\t%s MAILINGLIST_DIRECTORY is_encrypted" % prog_name
print "\t%s MAILINGLIST_DIRECTORY genkey [NAME [COMMENT [MAIL]]]" % prog_name
print "\t%s MAILINGLIST_DIRECTORY get_gnupg_dir" % prog_name
print
if __name__ == "__main__":
if not check_for_errors():
sys.exit(1)
else:
## no parameters - only self-testing was requested - we quit now
if len(sys.argv) == 1:
print "OK"
sys.exit(0)
if len(sys.argv) == 2:
if sys.argv[1] == "--help":
output_help()
sys.exit(0)
else:
sys.stderr.write("Not enough parameters: %s\n" % sys.argv[1])
output_help()
sys.exit(2)
else:
list_dir = sys.argv[1]
if not check_mailinglist_directory(list_dir):
sys.exit(3)
## is the action valid?
action = sys.argv[2]
if action == "enable":
enable_encryption(list_dir)
elif action == "disable":
disable_encryption(list_dir)
elif action == "is_encrypted":
if is_encrypted(list_dir):
print "The mailing list in %s is encrypted." % list_dir
sys.exit(0)
else:
print "The mailing list in %s is not encrypted." % list_dir
sys.exit(100)
elif action == "get_gnupg_dir":
print get_gnupg_setting(list_dir)
elif action == "genkey":
name, comment, mail = None, None, None
if len(sys.argv) > 6:
sys.stderr.write("Too many arguments (%d) - try '--help' for details.\n" % len(sys.argv)-1 )
sys.exit(2)
if len(sys.argv) > 5:
mail = sys.argv[5]
if len(sys.argv) > 4:
comment = sys.argv[4]
if len(sys.argv) > 3:
name = sys.argv[3]
if generate_key(list_dir, name, comment, mail):
sys.exit(0)
else:
sys.exit(4)
else:
sys.stderr.write("Unknown action requested: %s\n" % sys.argv[2])
sys.exit(2)

View file

@ -0,0 +1,129 @@
#!/bin/sh
#
# This file is part of gpgpy-ezmlm - an encryption filter for the
# ezmlm-idx mailinglist manager.
#
# Copyright 02007 Sense.Lab e.V. <info@senselab.org>
#
# This script is used to decide if we have to call qmail-queue directly
# or if we should call the gpgpy re-encrypting wrapper instead.
#
# Add the following environment setting to qmail-start (e.g. in
# /var/qmail/rc):
# QMAILQUEUE=PATH_TO_THIS_SCRIPT
#
# In case you did not install qmail in its default directory (/var/qmail)
# or if you use a filtering qmail-queue wrapper (e.g. for spam filtering)
# then you should change the setting GPGPY_QMAILQUEUE so that it contains
# the path of your qmail-queue program.
#
#
# gpgpy-ezmlm is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# gpgpy-ezmlm is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with the CryptoBox; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
##################### configuration #####################
# maybe you have to adjust the following lines according to your setup
# the following settings can also be overriden by environment settings
# with the same name
# the original qmail-queue program
GPGPY_QMAILQUEUE=${GPGPY_QMAILQUEUE:=/var/qmail/bin/qmail-queue}
# the python filter of gpgpy-ezmlm-queue
GPGPY_EZMLM_ENCRYPT=${GPGPY_EZMLM_ENCRYPT:=/usr/local/bin/gpgpy-ezmlm-encrypt}
# are all encrypted mailinglists handled by a single user?
# then put its UID here - for all other UIDs the original qmail-queue will be
# used instead
GPGPY_RESTRICT_UID=${GPGPY_RESTRICT_UID:=}
# we read our configuration from 'conf-gpgpy'
GPGPY_EZMLM_CONF_FILE="conf-gpgpy"
# call the original qmail-queue program without the changed QMAILQUEUE setting
EXEC_ORIG_QUEUE="exec env --unset=QMAILQUEUE $GPGPY_QMAILQUEUE"
##################### self-test #########################
# should we do some self-tests?
if test "$#" -eq 1 -a "$1" = "test"
then error=
# check if the original qmail-queue is executable
if test -x "$GPGPY_QMAILQUEUE"
then true
else error=yes
echo >&2 "Could not find executable qmail-queue: $GPGPY_QMAILQUEUE"
fi
# check if the gpgpy-ezmlm wrapper for qmail-queue exists
# also check if it returns any errors
if test -x "$GPGPY_EZMLM_ENCRYPT"
then if "$GPGPY_EZMLM_ENCRYPT"
then true
else error=yes
fi 2>&1 | sed 's/^/[gpg-ezmlm-encrypt] /' >&2
else error=yes
echo >&2 "Could not find executable gpgpy-ezmlm-queue: $GPGPY_EZMLM_ENCRYPT"
fi
# check GPGPY_RESTRICT_UID for invalid values
if test -n "$GPGPY_RESTRICT_UID"
then if test 0 -le "$GPGPY_RESTRICT_UID" 2>/dev/null
then true
else error=yes
echo >&2 "Invalid value of GPGPY_RESTRICT_UID ($GPGPY_RESTRICT_UID) - only integer values are allowed!"
fi
fi
# print results to stderr
if test -z "$error"
then echo "Successfully finished self-tests"
exit 0
else echo >&2
echo >&2 "Some self-tests failed - please fix them before deploying gpgpy-ezmlm!"
exit 81
fi
fi
################### queue selection #####################
# do some tests to decide, if we should run the gpgpy filter or not
test -n "$GPGPY_RESTRICT_UID" -a "$UID" != "$GPGPY_RESTRICT_UID" && $EXEC_ORIG_QUEUE
# the HOME setting is necessary
test -z "$HOME" && $EXEC_ORIG_QUEUE
# which dot-qmail file should we check? (see 'man qmail-command' for details)
if test -z "$EXT"
then DOTQMAIL_FILE=$HOME/.qmail
else DOTQMAIL_FILE=$HOME/.qmail-$EXT
fi
# does the dot-qmail file exist?
test -r "$DOTQMAIL_FILE" || $EXEC_ORIG_QUEUE
# filter the respective mailing list directory of this delivery
MAILINGLIST_DIR=$(grep "/ezmlm-send '" "$DOTQMAIL_FILE" | sed "s#^.* '\(.*\)'.*\$#\1#")
# is it a mailinglist directory?
test -e "$MAILINGLIST_DIR/lock" || $EXEC_ORIG_QUEUE
# is this mailinglist configured for gpgpy-ezmlm?
test -r "$MAILINGLIST_DIR/$GPGPY_EZMLM_CONF_FILE" || $EXEC_ORIG_QUEUE
# ok - it is a delivery of an encrypted mailinglist
exec env QMAILQUEUE=$GPGPY_QMAILQUEUE "$GPGPY_EZMLM_ENCRYPT" "$MAILINGLIST_DIR"

View file

@ -0,0 +1,18 @@
#!/usr/bin/env python
#
# this simple script is a dummy implementation of qmail-queue
#
# it simply prints the incoming mail from file descriptor 0
# and the incoming envelope information from file descriptor 1
#
import sys, os
infile = os.fdopen(1, "r")
content = infile.read()
sys.stderr.write("Envelope: %s\n" % content)
sys.stderr.write("\n")
sys.stderr.write(sys.stdin.read())