From ee170fc7da55d93b3fb9a0ee88558f8dfd2bf5dc Mon Sep 17 00:00:00 2001 From: lars Date: Wed, 4 Apr 2007 23:29:03 +0000 Subject: [PATCH] renamed gpgpy-ezmlm to crypto-ezmlm --- crypto-ezmlm/trunk/Makefile | 75 +++++ crypto-ezmlm/trunk/README | 126 +++++++ crypto-ezmlm/trunk/bin/gpgpy-ezmlm-encrypt | 330 +++++++++++++++++++ crypto-ezmlm/trunk/bin/gpgpy-ezmlm-manage | 285 ++++++++++++++++ crypto-ezmlm/trunk/bin/gpgpy-ezmlm-queue | 129 ++++++++ crypto-ezmlm/trunk/bin/qmail-queue-dummy | 18 + crypto-ezmlm/trunk/man/conf-gpgpy.5 | 89 +++++ crypto-ezmlm/trunk/man/gpgpy-ezmlm-encrypt.1 | 61 ++++ crypto-ezmlm/trunk/man/gpgpy-ezmlm-manage.1 | 99 ++++++ crypto-ezmlm/trunk/man/gpgpy-ezmlm-queue.1 | 83 +++++ crypto-ezmlm/trunk/man/gpgpy-ezmlm.5 | 102 ++++++ 11 files changed, 1397 insertions(+) create mode 100644 crypto-ezmlm/trunk/Makefile create mode 100644 crypto-ezmlm/trunk/README create mode 100755 crypto-ezmlm/trunk/bin/gpgpy-ezmlm-encrypt create mode 100755 crypto-ezmlm/trunk/bin/gpgpy-ezmlm-manage create mode 100755 crypto-ezmlm/trunk/bin/gpgpy-ezmlm-queue create mode 100755 crypto-ezmlm/trunk/bin/qmail-queue-dummy create mode 100644 crypto-ezmlm/trunk/man/conf-gpgpy.5 create mode 100644 crypto-ezmlm/trunk/man/gpgpy-ezmlm-encrypt.1 create mode 100644 crypto-ezmlm/trunk/man/gpgpy-ezmlm-manage.1 create mode 100644 crypto-ezmlm/trunk/man/gpgpy-ezmlm-queue.1 create mode 100644 crypto-ezmlm/trunk/man/gpgpy-ezmlm.5 diff --git a/crypto-ezmlm/trunk/Makefile b/crypto-ezmlm/trunk/Makefile new file mode 100644 index 0000000..44fee62 --- /dev/null +++ b/crypto-ezmlm/trunk/Makefile @@ -0,0 +1,75 @@ + +PREFIX ?= /usr/local +QMAILQUEUE ?= /var/qmail/bin/qmail-queue + +# man pages are compressed by default +COMPR_BIN ?= gzip +COMPR_EXT ?= .gz + +# we need to replace some paths within the scripts and man pages +SED_BIN ?= sed +SED_PARAMS = s\#/usr/local/\#${PREFIX}/\#g; s\#/var/qmail/bin/qmail-queue\#${QMAILQUEUE}\#g + +SCRIPTS = gpgpy-ezmlm-manage gpgpy-ezmlm-queue gpgpy-ezmlm-encrypt +MANPAGES1 = gpgpy-ezmlm-manage.1 gpgpy-ezmlm-queue.1 gpgpy-ezmlm-encrypt.1 +MANPAGES5 = gpgpy-ezmlm.5 conf-gpgpy.5 + +.PHONY = prepare install test clean help + +prepare: + @mkdir -p target + @echo "Adjusting installation paths for scripts ..." + @for script_file in ${SCRIPTS} ;\ + do "${SED_BIN}" "${SED_PARAMS}" "bin/$$script_file" >"target/$$script_file" ;\ + done + @echo "Adjusting installation paths for manpages ..." + @for man_file in ${MANPAGES1} ${MANPAGES5};\ + do "${SED_BIN}" "${SED_PARAMS}" "man/$$man_file" | gzip >"target/$$man_file${COMPR_EXT}" ;\ + done + + +install: prepare + @echo "Installing scripts ..." + @mkdir -p "${PREFIX}/bin/" + @for file in ${SCRIPTS} ;\ + do install "target/$$file" "${PREFIX}/bin/" ;\ + done + @echo "Installing man pages ..." + @mkdir -p "${PREFIX}/share/man/man1/" + @for file in ${MANPAGES1} ;\ + do install "target/$$file${COMPR_EXT}" "${PREFIX}/share/man/man1/" ;\ + done + @mkdir -p "${PREFIX}/share/man/man5/" + @for file in ${MANPAGES5} ;\ + do install "target/$$file${COMPR_EXT}" "${PREFIX}/share/man/man5/" ;\ + done + +test: install + @echo "Testing gpgpy-ezmlm-manage ..." + @"${PREFIX}/bin/gpgpy-ezmlm-manage" >/dev/null && echo " => OK" + @echo "Testing gpgpy-ezmlm-queue ..." + @"${PREFIX}/bin/gpgpy-ezmlm-queue" test >/dev/null && echo " => OK" + +clean: + @echo "Removing temporary files ..." + @for file in ${SCRIPTS} ;\ + do rm -f "target/$$file" ;\ + done + @for file in ${MANPAGES1} ${MANPAGES5} ;\ + do rm -f "target/$$file${COMPR_EXT}" ;\ + done + -@rmdir target 2>/dev/null + + +help: + @echo "Valid targets are:" + @echo " prepare - adjust paths" + @echo " install - install scripts and man pages" + @echo " test - check if the installation was successful" + @echo " clean - remove temporary files" + @echo + @echo "The following environment settings are used:" + @echo " PREFIX - the installation path prefix - defaults to /usr/local" + @echo " QMAILQUEUE - location of your installed qmail-queue binary" + @echo + diff --git a/crypto-ezmlm/trunk/README b/crypto-ezmlm/trunk/README new file mode 100644 index 0000000..033fb6d --- /dev/null +++ b/crypto-ezmlm/trunk/README @@ -0,0 +1,126 @@ +This file is part of gpgpy-ezmlm - an encryption filter for the +ezmlm mailinglist manager. + +Installation and configuration issues are described. + +Copyright 02007 Sense.Lab e.V. + +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 + +-------------------------------------------------------------- + +Table of contents: + 1) Requirements + 2) Get the source + 3) Installation + 4) Integration with qmail + 5) Managing encrypted mailing lists + 6) Interoperability issues + 7) Report bugs / feedback + +-------------------------------------------------------------- + +1) Requirements: + - python2.4 + - python-pyme + - qmail + - ezmlm-idx (v0.431 or higher) + + +2) Get the source +The current release of gpgpy-ezmlm can be obtained from: + + https://systemausfall.org/toolforge/gpgpy-ezmlm + +Extract the compressed archive and read README. + + +3) Installation +This should be trivial for default installations: + make + make install + make test + +Please fix any problems, that may occour during the tests. + +Non-default installations can be customized - run "make help" for details. + +Afterwards the scripts and man pages are installed to their appropriate +locations. You still need to follow the instructions of section +"Integration with qmail" below. + + +4) Integration with qmail +Add the following environment setting to your qmail startup script +(e.g. /var/qmail/rc): + + QMAILQUEUE=/usr/local/bin/gpgpy-ezmlm-queue + +The default rc file would look like the following: + + #!/bin/sh + exec env - PATH="/var/qmail/bin:$PATH" \ + QMAILQUEUE=/usr/local/bin/gpgpy-ezmlm-queue \ + qmail-start "`cat /var/qmail/control/defaultdelivery`" + +Now you should restart qmail. + + +5) Managing encrypted mailing lists +Use the gpgpy-ezmlm-manage program to enable or disable gnupg encryption +for a specific list or to generate the secret key of a list. +BEWARE: you should run all of the following actions as the user that +manages the specific mailing list (e.g. vlists, vpopmail, ???). Otherwise +it is quite likely that you will create permission problems, which will show +up later during mail delivery. + +If you want to enable encryption for a mailing list, then you should run: + + /usr/local/bin/gpgpy-ezmlm-manage MAILINGLIST_DIR enable + /usr/local/bin/gpgpy-ezmlm-manage MAILINGLIST_DIR genkey + +This enables encryption for the specific list by creating the configuration +file "conf-gpgpy" in the list directory. Take a look at it for details. +Afterwards a new key is generated - every encrypted mailinglist needs a secret +key (without a passphrase) to decrypt incoming mails. Additionally you may +supply some description for the key (name, comment and mail address) - +otherwise these information are (wisely) guessed by the program. + +Now you should import the keys of all recipients of this list to the gnupg +key directory of the list. You can retrieve the location of this directory by +running the following command: + + /usr/local/bin/gpgpy-ezmlm-manage MAILINGLIST_DIR get_gnupg_dir + +For example you could import a new public key by issuing: + + gnupg --homedir MAILINGLIST_GNUPG_DIR --import KEYFILE + + +6) Interoperability issues +If you already use the QMAILQUEUE setting to integrate a spam filter into your +qmail setup (e.g. ifspamh), then you can still use gpgpy-ezmlm, too. +Simply use GPGPY_QMAILQUEUE instead of QMAILQUEUE for your spam filtering +program. This tells gpgpy-ezmlm to use the spam filtering program instead +of qmail-queue for mail queueing. + + +7) Report bugs / feedback +Please send any reports about problems or successful installations to +devel@senselab.org. Thanks! + +Or report bugs: + https://systemausfall.org/trac/ezmlm-web/newticket (component: "gpgpy-ezmlm") + diff --git a/crypto-ezmlm/trunk/bin/gpgpy-ezmlm-encrypt b/crypto-ezmlm/trunk/bin/gpgpy-ezmlm-encrypt new file mode 100755 index 0000000..53920d7 --- /dev/null +++ b/crypto-ezmlm/trunk/bin/gpgpy-ezmlm-encrypt @@ -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. +# +# 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) + diff --git a/crypto-ezmlm/trunk/bin/gpgpy-ezmlm-manage b/crypto-ezmlm/trunk/bin/gpgpy-ezmlm-manage new file mode 100755 index 0000000..efc1a97 --- /dev/null +++ b/crypto-ezmlm/trunk/bin/gpgpy-ezmlm-manage @@ -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. +# +# 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 = """ + + 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 + + """ + + +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) + diff --git a/crypto-ezmlm/trunk/bin/gpgpy-ezmlm-queue b/crypto-ezmlm/trunk/bin/gpgpy-ezmlm-queue new file mode 100755 index 0000000..ac8dd03 --- /dev/null +++ b/crypto-ezmlm/trunk/bin/gpgpy-ezmlm-queue @@ -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. +# +# 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" + diff --git a/crypto-ezmlm/trunk/bin/qmail-queue-dummy b/crypto-ezmlm/trunk/bin/qmail-queue-dummy new file mode 100755 index 0000000..aa8d7e9 --- /dev/null +++ b/crypto-ezmlm/trunk/bin/qmail-queue-dummy @@ -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()) + diff --git a/crypto-ezmlm/trunk/man/conf-gpgpy.5 b/crypto-ezmlm/trunk/man/conf-gpgpy.5 new file mode 100644 index 0000000..e979057 --- /dev/null +++ b/crypto-ezmlm/trunk/man/conf-gpgpy.5 @@ -0,0 +1,89 @@ +.TH conf-gpgpy 5 "March 02007" "gpgpy-ezmlm" "Manual of gpgpy-ezmlm" +.SH NAME +conf-gpgpy \- format and available configuration options of the mailing list +specific configuration file for encryption via gpgpy-ezmlm +.SH DESCRIPTION +The file \fBconf-gpgpy\fR is used by the encryption wrapper gpgpy-ezmlm that +can be integrated into the ezmlm-idx mailing list manager. +.PP +If a mailing list directory contains the file \fBconf-gpgpy\fR, then encryption +support is enabled for the list. The manual of \fIgpgpy-ezmlm-manage\fR(1) +tells you how to create this file. +.SH FORMAT +An entry in \fBconf-gpgpy\fR has the following format: +.RS +.sp +\fIOPTION\fP = \fIVALUE\fP +.sp +.RE +.PP +.IP \fIOPTION\fP +the name of a setting +.br +surrounding whitespaces are stripped +.br +case does not matter +.IP \fIVALUE\fP +the value of a setting +.br +may be enclosed in double or single quotes +.br +surrounding whitespaces are stripped +.br +case usually matters +.br +boolean values must be `no' or `yes' (case independent) +.PP +Lines are ignored if they start with `#', do not contain `=' or are empty. +.SH AVAILABLE OPTIONS +.IP \fBplain_without_key\fP +If there is no valid key available for a recipient, then she should receive the +message in plaintext. Otherwise a warning message is sent instead of the +encrypted part. +.br +.sp +Possible values are `no' or `yes'. +.br +.sp +The default value is `no'. +.IP \fBsign_messages\fP +Sign all outgoing mails with the key of the mailing list. +.br +.sp +Possible values are `no' or `yes'. +.br +.sp +The default value is `no'. +.IP \fBgnupg_dir\fP +The given directory contains the gnupg keyring for this mailing list. +Values starting with a slash (`/') are interpreted as absolute paths. +Values starting with a tilde (`~') are subject to user expansion. +All other paths are interpreted relative to the mailing list directory. +.br +.sp +The default value is `.gnupg', thus each mailing list uses its own keyring by +default. +.SH EXAMPLE +The following is the default content of a \fBconf-gpgpy\fP file, as it is +created by \fBgpgpy-ezmlm-manage\fP: +.RS +.sp +.nf +plain_without_key = no +sign_messages = no +gnupg_dir = .gnupg +.SH FILES +conf-gpgpy +.SH AUTHOR +Written by Lars Kruse +.SH REPORTING BUGS +Report bugs to +.SH COPYRIGHT +Copyright \(co 02006-02007 Lars Kruse +.br +This is free software. You may redistribute copies of it under the terms of the +GNU General Public License . There is NO +WARRANTY, to the extent permitted by law. +.SH SEE ALSO +gpgpy-ezmlm(5), gpgpy-ezmlm-manage(1), gpgpy-ezmlm-encrypt(1), gpgpy-ezmlm-queue(1) + diff --git a/crypto-ezmlm/trunk/man/gpgpy-ezmlm-encrypt.1 b/crypto-ezmlm/trunk/man/gpgpy-ezmlm-encrypt.1 new file mode 100644 index 0000000..4128cf8 --- /dev/null +++ b/crypto-ezmlm/trunk/man/gpgpy-ezmlm-encrypt.1 @@ -0,0 +1,61 @@ +.TH gpgpy-ezmlm-encrypt 1 "March 02007" "gpgpy-ezmlm" "Manual of gpgpy-ezmlm" +.SH NAME +gpgpy-ezmlm-encrypt \- the qmail-queue substitue \fIgpgpy-ezmlm-queue\fR +calls this script to decrypt and reencrypt outgoing mails of the +ezmlm-idx mailing list manager. +.SH SYNOPSIS +.B gpgpy-ezmlm-encrypt +check +.br +.B gpgpy-ezmlm-encrypt +[\fIMAILINGLIST_DIR\fR] +.SH DESCRIPTION +gpgpy-ezmlm-encrypt reads a mail from descriptor 0. It then reads the envelope +information from descriptor 1. It assumes that the given mailing list directory +is configured to be encrypted. It tries to decrypt the message and to encrypt +it then for every single recipient given by the envelope information. +Afterwards it hands the reencrypted mail and the respective envelope +information over to qmail-queue (or a similar substitute like ifspamh). +.PP +Read the manual of \fIqmail-queue\fR(8) to find out more details about the +interface of qmail-queue - except for the optional mailing list directory +argument it is identical to gpgpy-ezmlm-encrypt. +.PP +gpgpy-ezmlm-encrypt supports encrypted inline and multipart messages. Only +parts that had to be decrypted are also encrypted for the recipients. So +plaintext parts of a message will be delivered as plaintext, too. +.SH SELF-TESTS +If you call gpgpy-ezmlm-encrypt without an argument, then it only runs some +self-tests. This should ensure that the environment of gpgpy-ezmlm-encrypt +works in a sane way. +.PP +If no problems were encountered, then the resulting exit code will be zero. +A value of 81 indicates a serious problem. +.SH MAILING LIST DIRECTORY +Every ezmlm mailing list is stored in a separate directory. It contains all +subscribers, moderators, the configuration and the archive of sent messages. +Read the manual of ezmlm(5) for further details. +.PP +Encrypted mailing list directories differ from normal ones by the existence of +the file \fBconf-gpgpy\fR. See the manual of conf-gpgpy(5) for details. +.PP +The mailing list directory most likely also contains a gnupg directory for +storing the private and public keys available to the list. The location of this +directory is configured via conf-gpgpy(5). +.SH EXIT CODES +The exit codes of gpgpy-ezmlm-encrypt are similar to the ones defind in the +manual of qmail-queue(8). In contrast to qmail-queue, you may also expect some +error messages at STDERR. +.SH AUTHOR +Lars Kruse +.SH REPORTING BUGS +Report bugs to +.SH COPYRIGHT +Copyright \(co 02007 Lars Kruse +.br +This is free software. You may redistribute copies of it under the terms of the +GNU General Public License . There is NO +WARRANTY, to the extent permitted by law. +.SH SEE ALSO +gpgpy-ezmlm(5), gpgpy-ezmlm-queue(1), conf-gpgpy(5), qmail-queue(8), ezmlm(5) + diff --git a/crypto-ezmlm/trunk/man/gpgpy-ezmlm-manage.1 b/crypto-ezmlm/trunk/man/gpgpy-ezmlm-manage.1 new file mode 100644 index 0000000..802424e --- /dev/null +++ b/crypto-ezmlm/trunk/man/gpgpy-ezmlm-manage.1 @@ -0,0 +1,99 @@ +.TH gpgpy-ezmlm-manage 1 "March 02007" "gpgpy-ezmlm" "Manual of gpgpy-ezmlm" +.SH NAME +gpgpy-ezmlm-manage \- manage encrypted ezmlm mailing lists +.SH SYNOPSIS +.B gpgpy-ezmlm-manage [\fIMAILINGLIST_DIR\fR] [\fIACTION\fR] [\fIPARAMETER\fR] +.SH DESCRIPTION +gpgpy-ezmlm-manage configures the encryption support of your \fBezmlm(5)\fR +mailing lists. +.PP +Call gpgpy-ezmlm-manage without any arguments to run some self-tests. An +exit code of zero indicate, that no problem was found. Any other exit code is +accompanied by a description of the detected problem. +.PP +Besides these self-tests, gpgpy-ezmlm-manage supports the following actions: +.IP \fBenable\fR +Enable encryption for a mailing list. Essentially this just creates the +file \fBconf-gpgpy\fR(5) in the mailing list directory with default values. +.br +Nothing happens, if the mailing list directory already contains this file. +.br +Afterwards you will probably want to create a private key for the list +by using the action \fBgenkey\fR described below. +.IP \fBdisable\fR +Disable encryption of a mailing list. This just removes the file +\fBconf-gpgpy\fR(5) from the mailing list directory. +.br +Nothing happens, if this file does not exist. +.br +Be aware, that the gnupg keyring of the mailing list +will not be deleted automatically. This makes it possible to enable encryption +later again without recreating and importing the previous keys. Remove the +gnupg directory manually if you know, what you are doing. Check the action +\fBget_gnupg_dir\fR below for this purpose. +.IP "\fBgenkey\fR [ NAME [ COMMENT [ MAIL ]]]" +Generate the private key of this list. Additional arguments may be used to +change the description of the key (see \fBgpg\fR(1) for details). Empty values +are guessed automatically - e.g. the mail address of the key is extracted from +the respective files of the ezmlm-idx mailing list directory. +.br +Key generation may take some time. +.br +The generated keys do (by default) never expire. +.br +Use gpg(1) directly, if you do not like the default assumptions of +gpgpy-ezmlm-manage. For this purpose you should retrieve the location of the +gnupg keyring directory by using the action \fBget_gnupg_dir\fR described +below. +.IP \fBis_encrypted\fR +Check if the specified mailing list is currently encrypted. This just checks +if the file \fBconf-gpgpy\fR(5) exists in the mailing list directory. +.br +An exit code of zero indicates an encrypted mailing list. The exit code 100 +is returned for a plaintext mailing list. Any other exit code indicates a +configuration problem. +.br +The current encryption state of the mailing list is also written to STDOUT in +a humanly readable way. +.IP \fBget_gnupg_dir\fR +Return the directory of the gnupg keyring used by this mailinglist. The result +is written to STDOUT. +.br +The location of the directory can be configured in the file \fBconf-gpgpy\fR(5). +See its manpage for details. +.br +Use the gnupg directory to manage the keyring of the list. E.g. the following +command imports the public key of a recipient into the keyring: +.RS +.RS +.sp +.nf +gpg --homedir MAILINGLIST_KEYRING_DIR --import KEYFILE +.RE +.RE +.SH EXIT CODES +gpgpy-ezmlm-manage returns the following (non-zero) exit codes: +.IP \fB1\fR +gpgpy-ezmlm is not installed or configured properly. +.IP \fB2\fR +The specified arguments are invalid. +.IP \fB3\fR +The specified mailing list directory is invalid. +.IP \fB4\fR +The requested action failed. +.IP \fB100\fR +The action \fBis_encrypted\fR returns this value for non-encrypted mailing +lists. +.SH AUTHOR +Lars Kruse +.SH REPORTING BUGS +Report bugs to +.SH COPYRIGHT +Copyright \(co 02007 Lars Kruse +.br +This is free software. You may redistribute copies of it under the terms of the +GNU General Public License . There is NO +WARRANTY, to the extent permitted by law. +.SH SEE ALSO +gpgpy-ezmlm(5), conf-gpgpy(5), ezmlm(5), gpgpy-ezmlm-queue(1) + diff --git a/crypto-ezmlm/trunk/man/gpgpy-ezmlm-queue.1 b/crypto-ezmlm/trunk/man/gpgpy-ezmlm-queue.1 new file mode 100644 index 0000000..11f7d4d --- /dev/null +++ b/crypto-ezmlm/trunk/man/gpgpy-ezmlm-queue.1 @@ -0,0 +1,83 @@ +.TH gpgpy-ezmlm-queue 1 "March 02007" "gpgpy-ezmlm" "Manual of gpgpy-ezmlm" +.SH NAME +gpgpy-ezmlm-queue \- a wrapper around qmail-queue for handling gpg encrypted +ezmlm-idx mailing lists +.SH SYNOPSIS +.B gpgpy-ezmlm-queue +.sp +.B gpgpy-ezmlm-queue +test +.SH DESCRIPTION +gpgpy-ezmlm-queue expects a mail at descriptor 0 and envelope information +at descriptor 1. It uses the qmail specific environemnt variables (e.g. HOME +and EXT) to check if the mail was sent by an encrypted ezmlm mailing list. +Take a look at the manual of \fIqmail-command\fR(8) for more details about +these environment settings. +.PP +If the mail was queued by an encrypted ezmlm mailing list, then +\fIgpgpy-ezmlm-encrypt\fR(1) is used to process the mail before finally +queueing the mail. Otherwise \fiqmail-queue\fR(8) is called directly. +.PP +gpgpy-ezmlm-queue does not read anything from the file descriptors 0 and 1. +Instead it just hands over these descriptors to either qmail-queue or +gpgpy-ezmlm-encrypt. +.SH SELF-TESTS +If you call gpgpy-ezmlm-queue with the argument "\fBtest\fR", then it only runs +self-tests. This should ensure that the environment of gpgpy-ezmlm-queue +works in a sane way. +.PP +If no problems were encountered, then the resulting exit code will be zero. +A value of 81 indicates a serious problem. A description of the problems is +written to STDERR. +.SH INTEGRATION INTO QMAIL +It is required, that your qmail installation includes the qmailqueue patch. +It is part of many qmail patchsets - e.g. qmail-ldap or similar. +.PP +In order to use the gpgpy-ezmlm-queue wrapper in your mail delivery chain, +you have to set the QMAILQUEUE environment setting during the startup of +qmail to the location of gpgpy-ezmlm-queue. By default this should be +/usr/local/bin/gpgpy-ezmlm-queue. +.IP "Example for a \fI/var/qmail/rc\fR startup file:" +.sp +.nf +#!/bin/sh + +exec env - PATH="/var/qmail/bin:$PATH" \\ +QMAILQUEUE=/usr/local/bin/gpgpy-ezmlm-queue \\ +qmail-start "`cat /var/qmail/control/defaultdelivery`" +.PP +If you used to override the QMAILQUEUE setting with another program location +(e.g. for spam filtering), then you should start to use the setting +\fBGPGPY_QMAILQUEUE\fR for this value. This tells gpgpy-ezmlm-encrypt to +run the specified program instead of qmail-queue for the final delivery. +.SH ENVIRONMENT VARIABLES +.IP \fBGPGPY_QMAILQUEUE\fR +Override the default location /var/qmail/bin/qmail-queue for the queueing +program. This may also be the path to a qmail-queue substitute, e.g. +\fIifspamh\fR or similar. +.IP \fBGPGPY_EZMLM_ENCRYPT\fR +Override the default location /usr/local/bin/gpgpy-ezmlm-encrypt for the +gpgpy-ezmlm encryption wrapper around qmail-queue. +.IP \fBGPGPY_RESTRICT_UID\fR +If all encrypted mailing lists are delivered by the same user account (e.g. +vlists, vpopmail, ...), then you should consider to set this environment +variable to the numerical value of its user id. This will skip the +detection of encrypted lists, if the UID setting given by qmail-command is +different. +.SH EXIT CODES +gpgpy-ezmlm-queue only returns specific exit codes during self-test. For normal +operations gpgpy-ezmlm-encrypt and qmail-queue are responsible for setting the +exit code. +.SH AUTHOR +Lars Kruse +.SH REPORTING BUGS +Report bugs to +.SH COPYRIGHT +Copyright \(co 02007 Lars Kruse +.br +This is free software. You may redistribute copies of it under the terms of the +GNU General Public License . There is NO +WARRANTY, to the extent permitted by law. +.SH SEE ALSO +gpgpy-ezmlm(5), gpgpy-ezmlm-encrypt(1), conf-gpgpy(5), qmail-queue(8), ezmlm(5) + diff --git a/crypto-ezmlm/trunk/man/gpgpy-ezmlm.5 b/crypto-ezmlm/trunk/man/gpgpy-ezmlm.5 new file mode 100644 index 0000000..64b078f --- /dev/null +++ b/crypto-ezmlm/trunk/man/gpgpy-ezmlm.5 @@ -0,0 +1,102 @@ +.TH gpgpy-ezmlm 1 "March 02007" "gpgpy-ezmlm" "Manual of gpgpy-ezmlm" +.SH NAME +gpgpy-ezmlm \- overview of the gpgpy-ezmlm encryption filter for ezmlm-idx +mailing lists +.SH OVERVIEW +.PP +The usual mail delivery of ezmlm-idx: +.sp +.nf + +---------------+ +------------+ +-------------+ + | \fBincoming mail\fR | | \fBezmlm-send\fR | | \fB$QMAILQUEUE\fR | + | for the | ===> | processing | ===> | queueing | + | mailing list | | list setup | | all mails | + +---------------+ +------------+ +-------------+ +.PP +Mail delivery for gpgpy-ezmlm encrypted lists: +.sp +.nf + +---------------+ +------------+ +-------------------+ + | \fBincoming mail\fR | | \fBezmlm-send\fR | | \fBgpgpy-ezmlm-queue\fR | + | for the | ===> | processing | ===> | check if the list | =... + | mailing list | | list setup | | is encrypted | + +---------------+ +------------+ +-------------------+ +.sp + +--------------------+ + | \fB$GPGPY_QMAILQUEUE\fR | + /===================================> | | + || | queueing all mails | + || plaintext mailing list +--------------------+ + || + ...=+| + || + || encrypted mailing list + || + || +---------------------+ +-------------------+ + || | \fBgpgpy-ezmlm-encrypt\fR | | \fB$GPGPY_QMAILQUEUE\fR | + /====> | decrypt and encrypt | ==++==> | queue mail for | + | for each subscriber | || | 1st subscriber | + +---------------------+ || +-------------------+ + || + || +-------------------+ + || | \fB$GPGPY_QMAILQUEUE\fR | + |+==> | queue mail for | + || | 2nd subscriber | + || +-------------------+ + || + || + \+==> ... +.IP \fINote:\fR +The environment variables \fB$QMAILQUEUE\fR and \fB$GPGPY_QMAILQUEUE\fR are not +set in a standard qmail installation. Thus they default to +/var/qmail/bin/qmail-queue. +.SH HOW DOES IT WORK +Since ezmlm-idx v0.431 \fBezmlm-send\fR(1) respects the QMAILQUEUE environment +setting when queueing a mail. If QMAILQUEUE is not set, then the original +qmail-queue program is used instead. +.PP +gpgpy-ezmlm relies on the QMAILQUEUE setting pointing to +\fBgpgpy-ezmlm-queue\fR(1). Read its manpage for how to do this easily. +.PP +If you used to override the QMAILQUEUE setting with another program location +(e.g. for spam filtering), then you should start to use the setting +\fBGPGPY_QMAILQUEUE\fR for this value. This tells gpgpy-ezmlm-encrypt to +run the specified program instead of qmail-queue for the final delivery. +.SH ENVIRONMENT VARIABLES +.IP \fBGPGPY_QMAILQUEUE\fR +Override the default location /var/qmail/bin/qmail-queue for the queueing +program. This may also be the path to a qmail-queue substitute, e.g. +\fIifspamh\fR or similar. +.IP \fBGPGPY_EZMLM_ENCRYPT\fR +Override the default location /usr/local/bin/gpgpy-ezmlm-encrypt for the +gpgpy-ezmlm encryption wrapper around qmail-queue. +.IP \fBGPGPY_RESTRICT_UID\fR +If all encrypted mailing lists are delivered by the same user account (e.g. +vlists, vpopmail, ...), then you should consider to set this environment +variable to the numerical value of its user id. This will skip the +detection of encrypted lists, if the UID setting given by qmail-command is +different. +.SH WHY DOES GPGPY-EZMLM NEED TWO SCRIPTS FOR QUEUEING? +The reason is simple: it is all about speed. +.PP +gpgpy-ezmlm-queue is a shell script and requires very little overhead for +execution. Thus it does not have a big impact on the time-critical delivery +performance of your mailserver. +.PP +gpgpy-ezmlm-encrypt is implemented in python, as this language offers the +\fIpyme\fR module for easy handling of gnupg encryption. It is only called for +messages that are sent by encrypted mailing lists, so the impact of the python +overhead on overall mail delivery should be acceptable. +.SH AUTHOR +Lars Kruse +.SH REPORTING BUGS +Report bugs to +.SH COPYRIGHT +Copyright \(co 02007 Lars Kruse +.br +This is free software. You may redistribute copies of it under the terms of the +GNU General Public License . There is NO +WARRANTY, to the extent permitted by law. +.SH SEE ALSO +gpgpy-ezmlm-queue(1), gpgpy-ezmlm-encrypt(1), qmail-queue(8), ezmlm(5), ezmlm-send(1) +