diff options
Diffstat (limited to 'src/mailman/config')
| -rw-r--r-- | src/mailman/config/__init__.py | 30 | ||||
| -rw-r--r-- | src/mailman/config/config.py | 206 | ||||
| -rw-r--r-- | src/mailman/config/mailman.cfg | 69 | ||||
| -rw-r--r-- | src/mailman/config/schema.cfg | 589 |
4 files changed, 894 insertions, 0 deletions
diff --git a/src/mailman/config/__init__.py b/src/mailman/config/__init__.py new file mode 100644 index 000000000..11f4f0c80 --- /dev/null +++ b/src/mailman/config/__init__.py @@ -0,0 +1,30 @@ +# Copyright (C) 2008-2009 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman 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 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman 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 +# GNU Mailman. If not, see <http://www.gnu.org/licenses/>. + +"""Mailman configuration package.""" + +from __future__ import absolute_import, unicode_literals + +__metaclass__ = type +__all__ = [ + 'config', + ] + + +from mailman.config.config import Configuration + +config = Configuration() diff --git a/src/mailman/config/config.py b/src/mailman/config/config.py new file mode 100644 index 000000000..fa359a6f5 --- /dev/null +++ b/src/mailman/config/config.py @@ -0,0 +1,206 @@ +# Copyright (C) 2006-2009 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman 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 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman 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 +# GNU Mailman. If not, see <http://www.gnu.org/licenses/>. + +"""Configuration file loading and management.""" + +from __future__ import absolute_import, unicode_literals + +__metaclass__ = type +__all__ = [ + 'Configuration', + ] + + +import os +import sys +import errno +import logging + +from StringIO import StringIO +from lazr.config import ConfigSchema, as_boolean +from pkg_resources import resource_string + +from mailman import version +from mailman.core import errors +from mailman.domain import Domain +from mailman.languages import LanguageManager +from mailman.styles.manager import StyleManager +from mailman.utilities.filesystem import makedirs + + +SPACE = ' ' + + + +class Configuration(object): + """The core global configuration object.""" + + def __init__(self): + self.domains = {} # email host -> IDomain + self.switchboards = {} + self.languages = LanguageManager() + self.style_manager = StyleManager() + self.QFILE_SCHEMA_VERSION = version.QFILE_SCHEMA_VERSION + self._config = None + self.filename = None + # Create various registries. + self.chains = {} + self.rules = {} + self.handlers = {} + self.pipelines = {} + self.commands = {} + + def _clear(self): + """Clear the cached configuration variables.""" + self.domains.clear() + self.switchboards.clear() + self.languages = LanguageManager() + + def __getattr__(self, name): + """Delegate to the configuration object.""" + return getattr(self._config, name) + + def load(self, filename=None): + """Load the configuration from the schema and config files.""" + schema_string = resource_string('mailman.config', 'schema.cfg') + schema = ConfigSchema('schema.cfg', StringIO(schema_string)) + # If a configuration file was given, load it now too. First, load the + # absolute minimum default configuration, then if a configuration + # filename was given by the user, push it. + config_string = resource_string('mailman.config', 'mailman.cfg') + self._config = schema.loadFile(StringIO(config_string), 'mailman.cfg') + if filename is not None: + self.filename = filename + with open(filename) as user_config: + self._config.push(filename, user_config.read()) + self._post_process() + + def push(self, config_name, config_string): + """Push a new configuration onto the stack.""" + self._clear() + self._config.push(config_name, config_string) + self._post_process() + + def pop(self, config_name): + """Pop a configuration from the stack.""" + self._clear() + self._config.pop(config_name) + self._post_process() + + def _post_process(self): + """Perform post-processing after loading the configuration files.""" + # Set up the domains. + domains = self._config.getByCategory('domain', []) + for section in domains: + domain = Domain(section.email_host, section.base_url, + section.description, section.contact_address) + if domain.email_host in self.domains: + raise errors.BadDomainSpecificationError( + 'Duplicate email host: %s' % domain.email_host) + # Make sure there's only one mapping for the url_host + if domain.url_host in self.domains.values(): + raise errors.BadDomainSpecificationError( + 'Duplicate url host: %s' % domain.url_host) + # We'll do the reverse mappings on-demand. There shouldn't be too + # many virtual hosts that it will really matter that much. + self.domains[domain.email_host] = domain + # Set up directories. + self.BIN_DIR = os.path.abspath(os.path.dirname(sys.argv[0])) + self.VAR_DIR = var_dir = self._config.mailman.var_dir + # Now that we've loaded all the configuration files we're going to + # load, set up some useful directories. + join = os.path.join + self.LIST_DATA_DIR = join(var_dir, 'lists') + self.LOG_DIR = join(var_dir, 'logs') + self.LOCK_DIR = lockdir = join(var_dir, 'locks') + self.DATA_DIR = datadir = join(var_dir, 'data') + self.ETC_DIR = etcdir = join(var_dir, 'etc') + self.SPAM_DIR = join(var_dir, 'spam') + self.EXT_DIR = join(var_dir, 'ext') + self.QUEUE_DIR = join(var_dir, 'qfiles') + self.MESSAGES_DIR = join(var_dir, 'messages') + self.PUBLIC_ARCHIVE_FILE_DIR = join(var_dir, 'archives', 'public') + self.PRIVATE_ARCHIVE_FILE_DIR = join(var_dir, 'archives', 'private') + # Other useful files + self.PIDFILE = join(datadir, 'master-qrunner.pid') + self.SITE_PW_FILE = join(datadir, 'adm.pw') + self.LISTCREATOR_PW_FILE = join(datadir, 'creator.pw') + self.CONFIG_FILE = join(etcdir, 'mailman.cfg') + self.LOCK_FILE = join(lockdir, 'master-qrunner') + # Set up the switchboards. + from mailman.queue import Switchboard + Switchboard.initialize() + # Set up all the languages. + languages = self._config.getByCategory('language', []) + for language in languages: + code = language.name.split('.')[1] + self.languages.add_language(code, language.description, + language.charset, language.enabled) + # Always enable the server default language, which must be defined. + self.languages.enable_language(self._config.mailman.default_language) + self.ensure_directories_exist() + self.style_manager.populate() + + @property + def logger_configs(self): + """Return all log config sections.""" + return self._config.getByCategory('logging', []) + + @property + def paths(self): + """Return a substitution dictionary of all path variables.""" + return dict((k, self.__dict__[k]) + for k in self.__dict__ + if k.endswith('_DIR')) + + def ensure_directories_exist(self): + """Create all path directories if they do not exist.""" + for variable, directory in self.paths.items(): + makedirs(directory) + + @property + def qrunner_configs(self): + """Iterate over all the qrunner configuration sections.""" + for section in self._config.getByCategory('qrunner', []): + yield section + + @property + def archivers(self): + """Iterate over all the enabled archivers.""" + for section in self._config.getByCategory('archiver', []): + if not as_boolean(section.enable): + continue + class_path = section['class'] + module_name, class_name = class_path.rsplit('.', 1) + __import__(module_name) + yield getattr(sys.modules[module_name], class_name)() + + @property + def style_configs(self): + """Iterate over all the style configuration sections.""" + for section in self._config.getByCategory('style', []): + yield section + + @property + def header_matches(self): + """Iterate over all spam matching headers. + + Values are 3-tuples of (header, pattern, chain) + """ + matches = self._config.getByCategory('spam.headers', []) + for match in matches: + yield (matches.header, matches.pattern, matches.chain) diff --git a/src/mailman/config/mailman.cfg b/src/mailman/config/mailman.cfg new file mode 100644 index 000000000..2bf528bea --- /dev/null +++ b/src/mailman/config/mailman.cfg @@ -0,0 +1,69 @@ +# Copyright (C) 2008-2009 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman 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 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman 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 +# GNU Mailman. If not, see <http://www.gnu.org/licenses/>. + +# This is the absolute bare minimum base configuration file. User supplied +# configurations are pushed onto this. + +[language.en] + +[qrunner.archive] +class: mailman.queue.archive.ArchiveRunner + +[qrunner.bad] +class: mailman.queue.fake.BadRunner +# The shunt runner is just a placeholder for its switchboard. +start: no + +[qrunner.bounces] +class: mailman.queue.bounce.BounceRunner + +[qrunner.command] +class: mailman.queue.command.CommandRunner + +[qrunner.in] +class: mailman.queue.incoming.IncomingRunner + +[qrunner.lmtp] +class: mailman.queue.lmtp.LMTPRunner + +[qrunner.maildir] +class: mailman.queue.maildir.MaildirRunner +# This is still experimental. +start: no + +[qrunner.news] +class: mailman.queue.news.NewsRunner + +[qrunner.out] +class: mailman.queue.outgoing.OutgoingRunner + +[qrunner.pipeline] +class: mailman.queue.pipeline.PipelineRunner + +[qrunner.retry] +class: mailman.queue.retry.RetryRunner +sleep_time: 15m + +[qrunner.shunt] +class: mailman.queue.fake.ShuntRunner +# The shunt runner is just a placeholder for its switchboard. +start: no + +[qrunner.virgin] +class: mailman.queue.virgin.VirginRunner + +[style.default] diff --git a/src/mailman/config/schema.cfg b/src/mailman/config/schema.cfg new file mode 100644 index 000000000..df20a7370 --- /dev/null +++ b/src/mailman/config/schema.cfg @@ -0,0 +1,589 @@ +# Copyright (C) 2008-2009 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman 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 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman 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 +# GNU Mailman. If not, see <http://www.gnu.org/licenses/>. + +# This is the GNU Mailman configuration schema. It defines the default +# configuration options for the core system and plugins. It uses ini-style +# formats under the lazr.config regime to define all system configuration +# options. See <https://launchpad.net/lazr.config> for details. + +[mailman] +# This address is the "site owner" address. Certain messages which must be +# delivered to a human, but which can't be delivered to a list owner (e.g. a +# bounce from a list owner), will be sent to this address. It should point to +# a human. +site_owner: changeme@example.com + +# This address is used as the from address whenever a message comes from some +# entity to which there is no natural reply recipient. Set this to a real +# human or to /dev/null. It will be appended with the host name of the list +# involved. This address must not bounce and it must not point to a Mailman +# process. +noreply_address: noreply + +# Where all the runtime data will be kept. This directory must exist. +var_dir: /tmp/mailman + +# The default language for this server. +default_language: en + +# When allowing only members to post to a mailing list, how is the sender of +# the message determined? If this variable is set to Yes, then first the +# message's envelope sender is used, with a fallback to the sender if there is +# no envelope sender. Set this variable to No to always use the sender. +# +# The envelope sender is set by the SMTP delivery and is thus less easily +# spoofed than the sender, which is typically just taken from the From: header +# and thus easily spoofed by the end-user. However, sometimes the envelope +# sender isn't set correctly and this will manifest itself by postings being +# held for approval even if they appear to come from a list member. If you +# are having this problem, set this variable to No, but understand that some +# spoofed messages may get through. +use_envelope_sender: no + +# Membership tests for posting purposes are usually performed by looking at a +# set of headers, passing the test if any of their values match a member of +# the list. Headers are checked in the order given in this variable. The +# value From_ means to use the envelope sender. Field names are case +# insensitive. This is a space separate list of headers. +sender_headers: from from_ reply-to sender + +# Mail command processor will ignore mail command lines after designated max. +email_commands_max_lines: 10 + +# Default length of time a pending request is live before it is evicted from +# the pending database. +pending_request_life: 3d + + +[passwords] +# When Mailman generates them, this is the default length of member passwords. +member_password_length: 8 + +# Specify the type of passwords to use, when Mailman generates the passwords +# itself, as would be the case for membership requests where the user did not +# fill in a password, or during list creation, when auto-generation of admin +# passwords was selected. +# +# Set this value to 'yes' for classic Mailman user-friendly(er) passwords. +# These generate semi-pronounceable passwords which are easier to remember. +# Set this value to 'no' to use more cryptographically secure, but harder to +# remember, passwords -- if your operating system and Python version support +# the necessary feature (specifically that /dev/urandom be available). +user_friendly_passwords: yes + + +[qrunner.master] +# Define which process queue runners, and how many of them, to start. + +# The full import path to the class for this queue runner. +class: mailman.queue.runner.Runner + +# The directory path that this queue runner scans. +path: $VAR_DIR/qfiles/$name + +# The number of parallel queue runners. This must be a power of 2. +instances: 1 + +# Whether to start this queue runner or not. +start: yes + +# The maximum number of restarts for this queue runner. When the runner exits +# because of an error or other unexpected problem, it is automatically +# restarted, until the maximum number of restarts has been reached. +max_restarts: 10 + +# The sleep interval for the queue runner. It wakes up once every interval to +# process the files in its slice of the queue directory. +sleep_time: 1s + +[database] +# Use this to set the Storm database engine URL. You generally have one +# primary database connection for all of Mailman. List data and most rosters +# will store their data in this database, although external rosters may access +# other databases in their own way. This string supports standard +# 'configuration' substitutions. +url: sqlite:///$DATA_DIR/mailman.db +debug: no + +[logging.template] +# This defines various log settings. The options available are: +# +# - level -- Overrides the default level; this may be any of the +# standard Python logging levels, case insensitive. +# - format -- Overrides the default format string +# - datefmt -- Overrides the default date format string +# - path -- Overrides the default logger path. This may be a relative +# path name, in which case it is relative to Mailman's LOG_DIR, +# or it may be an absolute path name. You cannot change the +# handler class that will be used. +# - propagate -- Boolean specifying whether to propagate log message from this +# logger to the root "mailman" logger. You cannot override +# settings for the root logger. +# +# In this section, you can define defaults for all loggers, which will be +# prefixed by 'mailman.'. Use subsections to override settings for specific +# loggers. The names of the available loggers are: +# +# - archiver -- All archiver output +# - bounce -- All bounce processing logs go here +# - config -- Configuration issues +# - debug -- Only used for development +# - error -- All exceptions go to this log +# - fromusenet -- Information related to the Usenet to Mailman gateway +# - http -- Internal wsgi-based web interface +# - locks -- Lock state changes +# - mischief -- Various types of hostile activity +# - post -- Information about messages posted to mailing lists +# - qrunner -- qrunner start/stops +# - smtp -- Successful SMTP activity +# - smtp-failure -- Unsuccessful SMTP activity +# - subscribe -- Information about leaves/joins +# - vette -- Information related to admindb activity +format: %(asctime)s (%(process)d) %(message)s +datefmt: %b %d %H:%M:%S %Y +propagate: no +level: info +path: mailman + +[logging.root] + +[logging.archiver] + +[logging.bounce] +path: bounce + +[logging.config] + +[logging.debug] +path: debug +level: debug + +[logging.error] + +[logging.fromusenet] + +[logging.http] + +[logging.locks] + +[logging.mischief] + +[logging.qrunner] + +[logging.smtp] +path: smtp + +# The smtp logger defines additional options for handling the logging of each +# attempted delivery. These format strings specify what information is logged +# for every message, every successful delivery, every refused delivery and +# every recipient failure. To disable a status message, set the value to 'no' +# (without the quotes). +# +# These template strings accept the following set of substitution +# placeholders, if available. +# +# msgid -- the Message-ID of the message in question +# listname -- the fully-qualified list name +# sender -- the sender if available +# recip -- the recipient address if available, or the number of +# recipients being delivered to +# size -- the approximate size of the message in bytes +# seconds -- the number of seconds the operation took +# refused -- the number of refused recipients +# smtpcode -- the SMTP success or failure code +# smtpmsg -- the SMTP success or failure message + +every: $msgid smtp to $listname for $recip recips, completed in $time seconds +success: $msgid post to $listname from $sender, $size bytes +refused: $msgid post to $listname from $sender, $size bytes, $refused failures +failure: $msgid delivery to $recip failed with code $smtpcode, $smtpmsg + + +[logging.subscribe] + +[logging.vette] + + +[domain.master] +# Site-wide domain defaults. To configure an individual +# domain, add a [domain.example_com] section with the overrides. + +# This is the host name for the email interface. +email_host: example.com +# This is the base url for the domain's web interface. It must include the +# url scheme. +base_url: http://example.com +# The contact address for this domain. This is advertised as the human to +# contact when users have problems with the lists in this domain. +contact_address: postmaster@example.com +# A short description of this domain. +description: An example domain. + + +[language.master] +# Template for language definitions. The section name must be [language.xx] +# where xx is the 2-character ISO code for the language. + +# The English name for the language. +description: English (USA) +# And the default character set for the language. +charset: us-ascii +# Whether the language is enabled or not. +enabled: yes + + +[spam.headers.template] +# This section defines basic header matching actions. Each spam.header +# section names a header to match (case-insensitively), a pattern to match +# against the header's value, and the chain to jump to when the match +# succeeds. +# +# The header value should not include the trailing colon. +header: X-Spam +# The pattern is always matched with re.IGNORECASE. +pattern: xyz +# The chain to jump to if the pattern matches. Maybe be any existing chain +# such as 'discard', 'reject', 'hold', or 'accept'. +chain: hold + + +[mta] +# The class defining the interface to the incoming mail transport agent. +incoming: mailman.mta.postfix.LMTP + +# The class defining the interface to the outgoing mail transport agent. +outgoing: mailman.mta.smtp_direct.process + +# How to connect to the outgoing MTA. +smtp_host: localhost +smtp_port: 25 + +# Where the LMTP server listens for connections. +lmtp_host: localhost +lmtp_port: 8025 + +# Ceiling on the number of recipients that can be specified in a single SMTP +# transaction. Set to 0 to submit the entire recipient list in one +# transaction. +max_recipients: 500 + +# Ceiling on the number of SMTP sessions to perform on a single socket +# connection. Some MTAs have limits. Set this to 0 to do as many as we like +# (i.e. your MTA has no limits). Set this to some number great than 0 and +# Mailman will close the SMTP connection and re-open it after this number of +# consecutive sessions. +max_sessions_per_connection: 0 + +# Maximum number of simultaneous subthreads that will be used for SMTP +# delivery. After the recipients list is chunked according to max_recipients, +# each chunk is handed off to the SMTP server by a separate such thread. If +# your Python interpreter was not built for threads, this feature is disabled. +# You can explicitly disable it in all cases by setting max_delivery_threads +# to 0. +max_delivery_threads: 0 + +# How long should messages which have delivery failures continue to be +# retried? After this period of time, a message that has failed recipients +# will be dequeued and those recipients will never receive the message. +delivery_retry_period: 5d + +# These variables control the format and frequency of VERP-like delivery for +# better bounce detection. VERP is Variable Envelope Return Path, defined +# here: +# +# http://cr.yp.to/proto/verp.txt +# +# This involves encoding the address of the recipient as we (Mailman) know it +# into the envelope sender address (i.e. the SMTP `MAIL FROM:' address). +# Thus, no matter what kind of forwarding the recipient has in place, should +# it eventually bounce, we will receive an unambiguous notice of the bouncing +# address. +# +# However, we're technically only "VERP-like" because we're doing the envelope +# sender encoding in Mailman, not in the MTA. We do require cooperation from +# the MTA, so you must be sure your MTA can be configured for extended address +# semantics. +# +# The first variable describes how to encode VERP envelopes. It must contain +# these three string interpolations: +# +# $bounces -- the list-bounces mailbox will be set here +# $mailbox -- the recipient's mailbox will be set here +# $host -- the recipient's host name will be set here +# +# This example uses the default below. +# +# FQDN list address is: mylist@dom.ain +# Recipient is: aperson@a.nother.dom +# +# The envelope sender will be mylist-bounces+aperson=a.nother.dom@dom.ain +# +# Note that your MTA /must/ be configured to deliver such an addressed message +# to mylist-bounces! +verp_delimiter: + +verp_format: ${bounces}+${mailbox}=${host} + +# For nicer confirmation emails, use a VERP-like format which encodes the +# confirmation cookie in the reply address. This lets us put a more user +# friendly Subject: on the message, but requires cooperation from the MTA. +# Format is like verp_format, but with the following substitutions: +# +# $address -- the list-confirm address +# $cookie -- the confirmation cookie +verp_confirm_format: $address+$cookie + +# This is analogous to verp_regexp, but for splitting apart the +# verp_confirm_format. MUAs have been observed that mung +# +# From: local_part@host +# +# into +# +# To: "local_part" <local_part@host> +# +# when replying, so we skip everything up to '<' if any. +verp_confirm_regexp: ^(.*<)?(?P<addr>[^+]+?)\+(?P<cookie>[^@]+)@.*$ + +# Set this to 'yes' to enable VERP-like (more user friendly) confirmations. +verp_confirmations: no + +# Another good opportunity is when regular delivery is personalized. Here +# again, we're already incurring the performance hit for addressing each +# individual recipient. Set this to 'yes' to enable VERPs on all personalized +# regular deliveries (personalized digests aren't supported yet). +verp_personalized_deliveries: no + +# And finally, we can VERP normal, non-personalized deliveries. However, +# because it can be a significant performance hit, we allow you to decide how +# often to VERP regular deliveries. This is the interval, in number of +# messages, to do a VERP recipient address. The same variable controls both +# regular and digest deliveries. Set to 0 to disable occasional VERPs, set to +# 1 to VERP every delivery, or to some number > 1 for only occasional VERPs. +verp_delivery_interval: 0 + +# VERP format and regexp for probe messages. +verp_probe_format: %(bounces)s+%(token)s +verp_probe_regexp: ^(?P<bounces>[^+]+?)\+(?P<token>[^@]+)@.*$ +# Set this 'yes' to activate VERP probe for disabling by bounce. +verp_probes: no + +# This is the maximum number of automatic responses sent to an address because +# of -request messages or posting hold messages. This limit prevents response +# loops between Mailman and misconfigured remote email robots. Mailman +# already inhibits automatic replies to any message labeled with a header +# "Precendence: bulk|list|junk". This is a fallback safety valve so it should +# be set fairly high. Set to 0 for no limit (probably useful only for +# debugging). +max_autoresponses_per_day: 10 + +# Some list posts and mail to the -owner address may contain DomainKey or +# DomainKeys Identified Mail (DKIM) signature headers <http://www.dkim.org/>. +# Various list transformations to the message such as adding a list header or +# footer or scrubbing attachments or even reply-to munging can break these +# signatures. It is generally felt that these signatures have value, even if +# broken and even if the outgoing message is resigned. However, some sites +# may wish to remove these headers by setting this to 'yes'. +remove_dkim_headers: no + +# This variable describe the program to use for regenerating the transport map +# db file, from the associated plain text files. The file being updated will +# be appended to this string (with a separating space), so it must be +# appropriate for os.system(). +postfix_map_cmd: /usr/sbin/postmap + + +[bounces] +# How often should the bounce qrunner process queued detected bounces? +register_bounces_every: 15m + + +[archiver.master] +# To add new archivers, define a new section based on this one, overriding the +# following values. + +# The class implementing the IArchiver interface. +class: mailman.archiving.prototype.Prototype + +# Set this to 'yes' to enable the archiver. +enable: no + +# The base url for the archiver. This is used to to calculate links to +# individual messages in the archive. +base_url: http://archive.example.com/ + +# If the archiver works by getting a copy of the message, this is the address +# to send the copy to. +recipient: archive@archive.example.com + +# If the archiver works by calling a command on the local machine, this is the +# command to call. +command: /bin/echo + + +[archiver.mhonarc] +# This is the stock MHonArc archiver. +class: mailman.archiving.mhonarc.MHonArc + +base_url: http://$hostname/archives/$fqdn_listname + + +[archiver.mail_archive] +# This is the stock mail-archive.com archiver. +class: mailman.archiving.mailarchive.MailArchive + +[archiver.pipermail] +# This is the stock Pipermail archiver. +class: mailman.archiving.pipermail.Pipermail + +# This sets the default `clobber date' policy for the archiver. When a +# message is to be archived either by Pipermail or an external archiver, +# Mailman can modify the Date: header to be the date the message was received +# instead of the Date: in the original message. This is useful if you +# typically receive messages with outrageous dates. Set this to 0 to retain +# the date of the original message, or to 1 to always clobber the date. Set +# it to 2 to perform `smart overrides' on the date; when the date is outside +# allowable_sane_date_skew (either too early or too late), then the received +# date is substituted instead. +clobber_date_policy: 2 +allowable_sane_date_skew: 15d + +# Pipermail archives contain the raw email addresses of the posting authors. +# Some view this as a goldmine for spam harvesters. Set this to 'yes' to +# moderately obscure email addresses, but note that this breaks mailto: URLs +# in the archives too. +obscure_email_addresses: yes + +# When the archive is public, should Pipermail also make the raw Unix mbox +# file publically available? +public_mbox: no + + +[archiver.prototype] +# This is a prototypical sample archiver. +class: mailman.archiving.prototype.Prototype + + +[style.master] +# The style's priority, with 0 being the lowest priority. +priority: 0 + +# The class implementing the IStyle interface, which applies the style. +class: mailman.styles.default.DefaultStyle + + +[scrubber] +# A filter module that converts from multipart messages to "flat" messages +# (i.e. containing a single payload). This is required for Pipermail, and you +# may want to set it to 0 for external archivers. You can also replace it +# with your own module as long as it contains a process() function that takes +# a MailList object and a Message object. It should raise +# Errors.DiscardMessage if it wants to throw the message away. Otherwise it +# should modify the Message object as necessary. +archive_scrubber: mailman.pipeline.scrubber + +# This variable defines what happens to text/html subparts. They can be +# stripped completely, escaped, or filtered through an external program. The +# legal values are: +# 0 - Strip out text/html parts completely, leaving a notice of the removal in +# the message. If the outer part is text/html, the entire message is +# discarded. +# 1 - Remove any embedded text/html parts, leaving them as HTML-escaped +# attachments which can be separately viewed. Outer text/html parts are +# simply HTML-escaped. +# 2 - Leave it inline, but HTML-escape it +# 3 - Remove text/html as attachments but don't HTML-escape them. Note: this +# is very dangerous because it essentially means anybody can send an HTML +# email to your site containing evil JavaScript or web bugs, or other +# nasty things, and folks viewing your archives will be susceptible. You +# should only consider this option if you do heavy moderation of your list +# postings. +# +# Note: given the current archiving code, it is not possible to leave +# text/html parts inline and un-escaped. I wouldn't think it'd be a good idea +# to do anyway. +# +# The value can also be a string, in which case it is the name of a command to +# filter the HTML page through. The resulting output is left in an attachment +# or as the entirety of the message when the outer part is text/html. The +# format of the string must include a $filename substitution variable which +# will contain the name of the temporary file that the program should operate +# on. It should write the processed message to stdout. Set this to +# HTML_TO_PLAIN_TEXT_COMMAND to specify an HTML to plain text conversion +# program. +archive_html_sanitizer: 1 + +# Control parameter whether the scrubber should use the message attachment's +# filename as is indicated by the filename parameter or use 'attachement-xxx' +# instead. The default is set 'no' because the applications on PC and Mac +# begin to use longer non-ascii filenames. +use_attachment_filename: no + +# Use of attachment filename extension per se is may be dangerous because +# viruses fakes it. You can set this 'yes' if you filter the attachment by +# filename extension. +use_attachment_filename_extension: no + + +[digests] +# Headers which should be kept in both RFC 1153 (plain) and MIME digests. RFC +# 1153 also specifies these headers in this exact order, so order matters. +# These are space separated and case insensitive. +mime_digest_keep_headers: + Date From To Cc Subject Message-ID Keywords + In-Reply-To References Content-Type MIME-Version + Content-Transfer-Encoding Precedence Reply-To + Message + +plain_digest_keep_headers: + Message Date From + Subject To Cc + Message-ID Keywords + Content-Type + + +[nntp] +# Set these variables if you need to authenticate to your NNTP server for +# Usenet posting or reading. If no authentication is necessary, specify None +# for both variables. +username: +password: + +# Set this if you have an NNTP server you prefer gatewayed lists to use. +host: + +# This controls how headers must be cleansed in order to be accepted by your +# NNTP server. Some servers like INN reject messages containing prohibited +# headers, or duplicate headers. The NNTP server may reject the message for +# other reasons, but there's little that can be programmatically done about +# that. +# +# These headers (case ignored) are removed from the original message. This is +# a whitespace separate list of headers. +remove_headers: + nntp-posting-host nntp-posting-date x-trace + x-complaints-to xref date-received posted + posting-version relay-version received + +# These headers are left alone, unless there are duplicates in the original +# message. Any second and subsequent headers are rewritten to the second +# named header (case preserved). This is a list of header pairs, one pair per +# line. +rewrite_duplicate_headers: + To X-Original-To + CC X-Original-CC + Content-Transfer-Encoding X-Original-Content-Transfer-Encoding + MIME-Version X-MIME-Version |
