# -*- python -*-
#
# Copyright (C) 2001-2007 Jason R. Mastaler <jason@mastaler.com>
#
# This file is part of TMDA.
#
# TMDA 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.  A copy of this license should
# be included in the file COPYING.
#
# TMDA 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 TMDA; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

"""TMDA configuration variable defaults.

See http://wiki.tmda.net/ConfigurationVariables for an HTMLized
version of the information below.
"""

# Some convenient constants
ON = On = on = YES = Yes = yes = TRUE = true = True
OFF = Off = off = NO = No = no = FALSE = false = False


# NEVER make configuration changes to this file.  ALWAYS make them in
# /etc/tmdarc or ~/.tmda/config instead.

import binascii
import os
import string
import sys

from .Errors import ConfigError


##############################
# General system-wide defaults
##############################

# The current process id of the Python interpreter as a string.
PID = str(os.getpid())

# General exit status codes which should be understood by all MTAs.
# Defined so we can raise exit codes within TMDA modules without
# having to create an MTA instance.
EX_OK = 0
EX_TEMPFAIL = 75

HOMEDIR = os.path.expanduser('~')

# TMDA parent directory.
PARENTDIR = os.path.abspath(os.path.dirname(__file__))


# Look for the global config file in the environment first, and then
# default to /etc/tmdarc.  If one exists, read it before TMDARC. Make
# site-wide configuration changes to this file.
GLOBAL_TMDARC = os.environ.get('GLOBAL_TMDARC')
if not GLOBAL_TMDARC:
    GLOBAL_TMDARC = '/etc/tmdarc'
    if os.path.exists(GLOBAL_TMDARC):
        exec(compile(open(GLOBAL_TMDARC).read(), GLOBAL_TMDARC, 'exec'))

# Look for the user config file in the TMDARC environment var first,
# and if not there, then check if set by GLOBAL_TMDARC, and finally
# default to ~/.tmda/config
_tmdarc = os.environ.get('TMDARC')
if _tmdarc:
    TMDARC = _tmdarc
elif not 'TMDARC' in vars():
    TMDARC = os.path.join(HOMEDIR, '.tmda', 'config')

# CONFIG_EXEC
# If set to False in GLOBAL_TMDARC, the user's TMDARC file will be parsed
# using ConfigParser, otherwise it will evaluated as a sequence of
# Python statements using execfile().
# Default is True (use execfile())
if not 'CONFIG_EXEC' in vars():
    CONFIG_EXEC = True

# Read-in the user's configuration file.
if os.path.exists(TMDARC):
    if CONFIG_EXEC:
        exec(compile(open(TMDARC).read(), TMDARC, 'exec'))
    else:
        import configparser
        cf = configparser.ConfigParser()
        cf.read(TMDARC)
        cf_section = 'TMDA_CONFIG'
        for option in cf.options(cf_section):
            value = cf.get(cf_section, option)
            option = option.upper()
            # Translate options into variables.
            if value in list(string.digits):
                # make sure integer values don't get turned into strings
                exec('%s = %s' % (option, value))
            else:
                exec('%s = "%s"' % (option, value))


from . import Util
from . import Version

TMDA_HOMEPAGE = "(http://tmda.net/)"
TMDA_VERSION = Version.TMDA

############################
# User configurable settings
############################

# Only compute defaults for unset variables to speed startup.

# DATADIR
# Top-level directory which TMDA uses to store its files and
# directories.  TMDA should be free to create files and directories
# under DATADIR if need be.
#
# Examples:
#
# DATADIR = "/full/path/to/.tmda"
# DATADIR = "~/.tmda"
#
# Default is ~/.tmda
if not 'DATADIR' in vars():
    DATADIR = os.path.join(HOMEDIR, '.tmda')

# MAIL_TRANSFER_AGENT
# Defines which mail transfer agent (MTA) software you are running.
# Possible choices are "exim", "postfix", "qmail", or "sendmail".
# Default is qmail
if not 'MAIL_TRANSFER_AGENT' in vars():
    MAIL_TRANSFER_AGENT = "postfix"

# DELIVERY
# The default delivery instruction for successful messages, or TMDA's
# final delivery location.  Only required if you are NOT running
# qmail.  The default value for qmail users is "_qok_" which means
# exit(0) and proceed to the next instruction in the dot-qmail file.
#
# Delivery to qmail-style Maildirs, mboxrd-format mboxes, programs
# (pipe), and forward to an e-mail addresses are supported.
#
# Acceptable syntax and restrictions for delivery instructions are
# discussed in the ``action'' section of the TMDA Filter Specification
# (config-filter.html).  Please read this documentation.
#
# Examples:
# DELIVERY = "~/Maildir/"
# DELIVERY = "~/Mailbox"
# DELIVERY = "/var/mail/jasonrm"
# DELIVERY = ":~/Mailbox"
# DELIVERY = ":/var/spool/mail/jasonrm"
# DELIVERY = "|/usr/bin/maildrop"
# DELIVERY = "|/usr/bin/procmail ~/.procmailrc-tmda"
# DELIVERY = "me@new.job.com"
#
# No default for non-qmail users.
if not 'DELIVERY' in vars():
    if MAIL_TRANSFER_AGENT == 'qmail':
        DELIVERY = "_qok_"
    else:
        raise ConfigError( \
              "non-qmail users must define DELIVERY in " + TMDARC)

# RECIPIENT_DELIMITER
# A single character which specifies the separator between user names
# and address extensions (e.g, user-ext).
# The default under qmail is `-', while the default for Sendmail and
# friends is likely `+'. The default for MMDF is '='.
#
# Default is "-"
if not 'RECIPIENT_DELIMITER' in vars():
    RECIPIENT_DELIMITER = "-"

# ALLOW_MODE_640
# Set this variable to True if you want to allow a mode 640 CRYPT_KEY_FILE.
#
# Default is False (turned off)
if not 'ALLOW_MODE_640' in vars():
    ALLOW_MODE_640 = False

# MAIL_TRANSPORT
# Final delivery method for all outgoing mail (server and client).
# Possible values include:
#
# "smtp"
#    Deliver messages by handing them off to an SMTP server (i.e,
#    smarthost).  Be sure that the "SMTPHOST" variable (see below) is
#    set correctly.
#
# "sendmail"
#    Deliver messages via the command line interface to the sendmail
#    program (e.g, /usr/sbin/sendmail).
#
# Default is "sendmail"
if not 'MAIL_TRANSPORT' in vars():
    MAIL_TRANSPORT = "sendmail"

# SMTPHOST
# SMTP host and optional port, when MAIL_TRANSPORT is "smtp".
# If the hostname or IP address ends with a colon (":") followed by a
# number, that suffix will be stripped off and the number interpreted
# as the port number to use.  Otherwise, the standard SMTP port (25)
# will be used.
#
# Examples:
#
# SMTPHOST = "localhost"
# SMTPHOST = "172.16.78.20:2525"
# SMTPHOST = "mailhost.company.com"
# SMTPHOST = "mailhost.company.com:1234"
#
# Default is "localhost" (port 25 on the local host)
if MAIL_TRANSPORT == 'smtp':
    if not 'SMTPHOST' in vars():
        SMTPHOST = "localhost"

# SMTPAUTH_USERNAME
# The username to authenticate with if your SMTP server requires
# authentication.  You must also define SMTPAUTH_PASSWORD if you use
# this option.
#
# Examples:
#
# SMTPAUTH_USERNAME = "johndoe"
#
# No default.
    if not 'SMTPAUTH_USERNAME' in vars():
        SMTPAUTH_USERNAME = None

# SMTPAUTH_PASSWORD
# The password to authenticate with if your SMTP server requires
# authentication.  You must also define SMTPAUTH_USERNAME if you use
# this option.
#
# Examples:
#
# SMTPAUTH_PASSWORD = "6Yu_9iKzs"
#
# No default.
    if 'SMTPAUTH_PASSWORD' in vars():
        SMTPAUTH_PASSWORD = None

# SMTPSSL
# Set this variable to True to put the SMTP connection in TLS (Transport
# Layer Security) mode. All SMTP commands that follow will be
# encrypted.  Your Python's socket module must be compiled with SSL
# support.
#
# Default is False (turned off)
    if not 'SMTPSSL' in vars():
        SMTPSSL = False

# SMTPSSL_KEYFILE
# When SMTPSSL is enabled, this is the optional name of a PEM
# formatted file that contains your private key.
#
# No default.
    if SMTPSSL and not 'SMTPSSL_KEYFILE' in vars():
        SMTPSSL_KEYFILE = None

# SMTPSSL_CERTFILE
# When SMTPSSL is enabled, this is the optional name of a PEM
# formatted certificate chain file.  Warning: This does not do any
# certificate verification.
#
# No default.
    if SMTPSSL and not 'SMTPSSL_CERTFILE' in vars():
        SMTPSSL_CERTFILE = None

# SMTP_MAX_SESSIONS_PER_CONNECTION
# An integer specifying a ceiling on the number of SMTP sessions to
# perform on a single socket connection, when MAIL_TRANSPORT is
# "smtp".  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 TMDA will close the SMTP connection and re-open it
# after this number of consecutive sessions.
#
# Default is 0
    if not 'SMTP_MAX_SESSIONS_PER_CONNECTION' in vars():
        SMTP_MAX_SESSIONS_PER_CONNECTION = 0

# SENDMAIL_PROGRAM
# The path to the sendmail program, or sendmail compatibility
# interface when MAIL_TRANSPORT is "sendmail".
#
# Defaults to one of the two standard locations (/usr/lib/sendmail,
# /usr/sbin/sendmail).
if not 'SENDMAIL_PROGRAM' in vars() and MAIL_TRANSPORT == 'sendmail':
    for sendmail in ('/usr/sbin/sendmail', '/usr/lib/sendmail'):
        if os.path.exists(sendmail):
            SENDMAIL_PROGRAM = sendmail
            break

# USEVIRTUALDOMAINS
# Set this variable to False if want to turn off TMDA's qmail virtualdomains
# support.  This should obviously only be done if you are not running
# any qmail virtualdomains, but it will improve performance.
#
# Default is True (turned on)
if not 'USEVIRTUALDOMAINS' in vars():
    USEVIRTUALDOMAINS = True

# VIRTUALDOMAINS
# virtualdomains defaults to /var/qmail/control/virtualdomains, but
# this lets you override it in case it is installed elsewhere.  Used
# for virtualdomain processing in tmda-filter.
#
# Default is /var/qmail/control/virtualdomains
if not 'VIRTUALDOMAINS' in vars():
    VIRTUALDOMAINS = "/var/qmail/control/virtualdomains"

# BOUNCE_ENV_SENDER
# The envelope sender of a bounce message.
#
# Example:
# BOUNCE_ENV_SENDER = "devnull@domain.dom"
#
# Default is "<>", a null envelope sender.
if not 'BOUNCE_ENV_SENDER' in vars():
    BOUNCE_ENV_SENDER = '<>'

# BARE_APPEND
# Filename to which a recipient's e-mail address should be
# automatically appended if the outgoing <action> is in the form
# 'bare=append'.
#
# Examples:
#
# BARE_APPEND = "/full/path/to/whitelist"
# BARE_APPEND = "~/.tmda/lists/whitelist"
#
# No default
if not 'BARE_APPEND' in vars():
    BARE_APPEND = None

# CGI_SETTINGS
# Filename for saving various tmda-cgi settings.  This filename can
# include a full path, otherwise it is relative the user's config file.
#
# Examples:
#
# CGI_SETTINGS = "/home/jim/.tmda/MyCGISettings"
# CGI_SETTINGS = "~/.tmda/MyCGISettings"
#
# Default is "tmda-cgi.ini".
if not 'CGI_SETTINGS' in vars():
    CGI_SETTINGS = "tmda-cgi.ini"

# CGI_URL
# Absolute URL of your tmda-cgi installation.
#
# Example:
# CGI_URL = "http://www.domain.dom/cgi-bin/tmda.cgi"
#
# No default.
if not 'CGI_URL' in vars():
    CGI_URL = None

# CGI_VIRTUALUSER
# Set this variable to True if you wish to enable tmda-cgi's "virtual
# user" support (http://tmda.sourceforge.net/tmda-cgi/virtual.html).
#
# Default is False (disabled)
if not 'CGI_VIRTUALUSER' in vars():
    CGI_VIRTUALUSER = False

# CONFIRM_ADDRESS
# An optional e-mail address to use for creating confirmation
# addresses.  Normally, the recipient address is used, but in some
# virtual domain or forwarding scenarios, you may wish to have
# confirmation address be based on a fixed address regardless of the
# recipient address.
#
# Example:
# CONFIRM_ADDRESS = "webmaster@domain.dom"
#
# No default
if not 'CONFIRM_ADDRESS' in vars():
    CONFIRM_ADDRESS = None

# CONFIRM_APPEND
# Filename to which a sender's e-mail address should be automatically
# appended once they confirm a message.  This can be used to implement
# "auto-whitelisting" functionality.
#
# Examples:
#
# CONFIRM_APPEND = "/full/path/to/whitelist"
# CONFIRM_APPEND = "~/.tmda/lists/whitelist"
#
# No default
if not 'CONFIRM_APPEND' in vars():
    CONFIRM_APPEND = None

# CONFIRM_CC
# An optional e-mail address which will be sent a copy of any message
# that triggers a confirmation request.
#
# Example:
# CONFIRM_CC = "jdoe-confirms@domain.dom"
#
# No default.
if not 'CONFIRM_CC' in vars():
    CONFIRM_CC = None

# CONFIRM_ACCEPT_NOTIFY
# Set this variable to False if you do not want to generate any
# confirmation acceptance notices.  These are the notices returned to
# senders when they confirm their original message by e-mail.  Their
# content is based on the confirm_accept.txt template.
#
# Default is True (turned on)
if not 'CONFIRM_ACCEPT_NOTIFY' in vars():
    CONFIRM_ACCEPT_NOTIFY = True

# CONFIRM_ACCEPT_CC
# An optional e-mail address which will be sent a copy of the
# confirmation acceptance messages people send you.
#
# Example:
# CONFIRM_ACCEPT_CC = "jdoe-confirm-replies@domain.dom"
#
# No default.
if not 'CONFIRM_ACCEPT_CC' in vars():
    CONFIRM_ACCEPT_CC = None

# CONFIRM_MAX_MESSAGE_SIZE
# This is the largest size (in bytes) that a message can be before the
# its body is excluded from the confirmation request/acceptance
# notice.  Set this to None to allow any size message.
#
# Default is 50000
if not 'CONFIRM_MAX_MESSAGE_SIZE' in vars():
    CONFIRM_MAX_MESSAGE_SIZE = 50000

# TEMPLATE_DIR
# Full path to a directory containing custom TMDA templates.  Any
# templates found in this directory will be used, otherwise the
# default templates will be used.
#
# Examples:
#
# TEMPLATE_DIR = "/full/path/to/templates/"
# TEMPLATE_DIR = "~/.tmda/templates/"
#
# No default.
if not 'TEMPLATE_DIR' in vars():
    TEMPLATE_DIR = None

# TEMPLATE_DIR_MATCH_RECIPIENT
# Set this variable to True if you want to use specific templates for
# different recipient addresses.  Be sure to set TEMPLATE_DIR as well.
#
# The TEMPLATE_DIR_MATCH_RECIPIENT feature enables TMDA to search for
# customized template files based on the recipient address.  To continue
# with the example given for TEMPLATE_DIR_MATCH_SENDER, if a message
# arrives for foo-lists-guitar@bar.baz.de then TMDA will search for
# template files in the following directories:
#
#  foo-lists-guitars@bar.baz.de/
#
#  foo-lists@bar.baz.de/
#
#  foo@bar.baz.de/
#
#  bar.baz.de/
#
#  baz.de/
#
#  de/
#
# This example assumes that RECIPIENT_DELIMITER is set to `-'.  This
# feature also works for *-confirm-* addresses.
#
# When both TEMPLATE_DIR_MATCH_RECIPIENT and TEMPLATE_DIR_MATCH_SENDER
# are enabled, the TEMPLATE_DIR_MATCH_RECIPIENT directories are searched
# after the sender directories.
#
# Default is False (turned off)

if not 'TEMPLATE_DIR_MATCH_RECIPIENT' in vars():
    TEMPLATE_DIR_MATCH_RECIPIENT = False

# TEMPLATE_DIR_MATCH_SENDER
# Set this variable to True if you want to use sender specific template
# directory matching. Make sure you also have TEMPLATE_DIR set.
#
# With this feature enabled, TMDA will look for templates in a
# subdirectory of TEMPLATE_DIR that matches the sender address, and
# then increasingly general portions of the domain part of the address.
#
# For example, if mail arrives from foo@bar.baz.de, TMDA will look for
# templates in these subdirectories of TEMPLATE_DIR, in this order:
#
#  foo@bar.baz.de/
#
#  bar.baz.de/
#
#  baz.de/
#
#  de/
#
# If no sender based templates can be found, TEMPLATE_DIR itself and
# then the default locations will be tried.
#
# Default is False (turned off)
if not 'TEMPLATE_DIR_MATCH_SENDER' in vars():
    TEMPLATE_DIR_MATCH_SENDER = False

# TEMPLATE_EMAIL_HEADERS
# A list containing the names of headers in your templates that
# contain an e-mail address.  This is necessary so that the e-mail
# address will avoid being RFC 2047 encoded when handling
# internationalized headers.
#
# Example:
# TEMPLATE_EMAIL_HEADERS = ["from", "reply-to"]
#
# Default is "From:" and "Reply-To:".
if not 'TEMPLATE_EMAIL_HEADERS' in vars():
    TEMPLATE_EMAIL_HEADERS = ['from', 'reply-to']

# TEMPLATE_ENCODED_HEADERS
# A list containing the names of headers in your templates that might
# contain an RFC 2047 encoded string.  This is necessary so that they
# can be decoded first when handling internationalized headers.
#
# Example:
# TEMPLATE_ENCODED_HEADERS = ["subject"]
#
# Default is "Subject:".
if not 'TEMPLATE_ENCODED_HEADERS' in vars():
    TEMPLATE_ENCODED_HEADERS = ['subject']

# DATED_TEMPLATE_VARS
# Set this variable to True if you want to use 'dated' address variables
# in your templates.
#
# Default is False (turned off)
if not 'DATED_TEMPLATE_VARS' in vars():
    DATED_TEMPLATE_VARS = False

# SENDER_TEMPLATE_VARS
# Set this variable to True if you want to use 'sender' address variables
# in your templates.
#
# Default is False (turned off)
if not 'SENDER_TEMPLATE_VARS' in vars():
    SENDER_TEMPLATE_VARS = False

# FILTER_INCOMING
# Filter file which controls how incoming messages are tagged.
# Look for the filter-file in the environment first.
#
# Default is ~/.tmda/filters/incoming
env_FILTER_INCOMING = os.environ.get('TMDA_FILTER_INCOMING')
if env_FILTER_INCOMING:
    FILTER_INCOMING = env_FILTER_INCOMING
elif not 'FILTER_INCOMING' in vars():
    FILTER_INCOMING = os.path.join(DATADIR, 'filters', 'incoming')

# FILTER_OUTGOING
# Filter file which controls how outgoing messages are tagged.
# Look for the filter-file in the environment first.
#
# Default is ~/.tmda/filters/outgoing
env_FILTER_OUTGOING = os.environ.get('TMDA_FILTER_OUTGOING')
if env_FILTER_OUTGOING:
    FILTER_OUTGOING = env_FILTER_OUTGOING
elif not 'FILTER_OUTGOING' in vars():
    FILTER_OUTGOING = os.path.join(DATADIR, 'filters', 'outgoing')

# FILTER_BOUNCE_CC
# An optional e-mail address which will be sent a copy of any message
# that bounces because of a match in FILTER_INCOMING.
#
# Example:
# FILTER_BOUNCE_CC = "jdoe-bounces@domain.dom"
#
# No default.
if not 'FILTER_BOUNCE_CC' in vars():
    FILTER_BOUNCE_CC = None

# FILTER_DROP_CC
# An optional e-mail address which will be sent a copy of any message
# that is dropped because of a match in FILTER_INCOMING.
#
# Example:
# FILTER_DROP_CC = "jdoe-drops@domain.dom"
#
# No default.
if not 'FILTER_DROP_CC' in vars():
    FILTER_DROP_CC = None

# ACTION_HEADER_INCOMING
# Set this variable to True if you want TMDA to add an `X-TMDA-Action'
# header to your delivered incoming messages. The value of this header
# is the same as the "Actn:" field in a LOGFILE_INCOMING entry. e.g,
#
# X-TMDA-Action: OK (from johndoe* ok)
#
# NOTE: This will not work if you are running qmail and have not set
# the DELIVERY variable.
#
# Default is False (turned off)
if not 'ACTION_HEADER_INCOMING' in vars():
    ACTION_HEADER_INCOMING = False

# ACTION_INCOMING
# Specifies how incoming messages should be disposed of by default if
# they didn't match FILTER_INCOMING and were not sent to a tagged
# address.
# Possible values include:
#
# "bounce"
#    bounce the message - uses the bounce_incoming.txt template.
# "drop"
#    silently drop the message
# "ok"
#    deliver the message
# "confirm"
#    request confirmation for the message
# "hold"
#    silently hold message in pending queue
#
# Default is confirm
if not 'ACTION_INCOMING' in vars():
    ACTION_INCOMING = "confirm"

# ACTION_FAIL_DATED
# Specifies how incoming messages should be disposed of if they are sent
# to a dated address that does not properly verify.
# Possible values include:
#
# "bounce"
#    bounce the message - uses the bounce_fail_dated.txt template.
# "drop"
#    silently drop the message
# "ok"
#    deliver the message
# "confirm"
#    request confirmation for the message
# "hold"
#    silently hold message in pending queue
#
# Default is confirm
if not 'ACTION_FAIL_DATED' in vars():
    ACTION_FAIL_DATED = "confirm"

# ACTION_EXPIRED_DATED
# Specifies how incoming messages should be disposed of if they are
# sent to an expired dated address. You can specify a single action to
# take by setting this variable to a string, in which case possible
# values include:
#
# "bounce"
#    bounce the message - uses the bounce_expired_dated.txt template.
# "drop"
#    silently drop the message
# "ok"
#    deliver the message
# "confirm"
#    request confirmation for the message
# "hold"
#    silently hold message in pending queue
#
# This can also be a dictionary if you want to handle different ages
# of expired dated messages in different ways.
#
# Examples:
#
# ACTION_EXPIRED_DATED = {
#     'default':'confirm', # default is to confirm, unless
#     '1w':     'bounce',  # ...it expired more than 1w ago, then bounce
#     '30d':    'hold',    # ...it expired more than 30d ago, then hold
#     '1Y':     'drop'}    # ...it expired more than 1Y ago, then drop
#
# Default is "confirm"
if not 'ACTION_EXPIRED_DATED' in vars():
    ACTION_EXPIRED_DATED = "confirm"

# ACTION_FAIL_SENDER
# Specifies how incoming messages should be disposed of if they are sent
# to a sender address, but were not sent from the correct sender, and
# fail to verify.
# Possible values include:
#
# "bounce"
#    bounce the message - uses the bounce_fail_sender.txt template.
# "drop"
#    silently drop the message
# "ok"
#    deliver the message
# "confirm"
#    request confirmation for the message
# "hold"
#    silently hold message in pending queue
#
# Default is confirm
if not 'ACTION_FAIL_SENDER' in vars():
    ACTION_FAIL_SENDER = "confirm"

# ACTION_FAIL_KEYWORD
# Specifies how incoming messages should be disposed of if they are
# sent to a keyword address that fails to verify.
# Possible values include:
#
# "bounce"
#    bounce the message - uses the bounce_fail_keyword.txt template.
# "drop"
#    silently drop the message
# "ok"
#    deliver the message
# "confirm"
#    request confirmation for the message
# "hold"
#    silently hold message in pending queue
#
# Default is confirm
if not 'ACTION_FAIL_KEYWORD' in vars():
    ACTION_FAIL_KEYWORD = "confirm"

# ACTION_INVALID_CONFIRMATION
# Specifies how confirmation messages should be disposed of if they
# are sent to a confirmation address that fails to verify.
# Possible values include:
#
# "bounce"
#    bounce the message - uses the bounce_invalid_confirmation.txt template.
# "drop"
#    silently drop the message
# "ok"
#    deliver the message
# "confirm"
#    request confirmation for the message
# "hold"
#    silently hold message in pending queue
#
# Default is bounce
if not 'ACTION_INVALID_CONFIRMATION' in vars():
    ACTION_INVALID_CONFIRMATION = "bounce"

# ACTION_MISSING_PENDING
# Specifies how confirmation messages should be disposed of if the
# message to be confirmed can not be located on disk.  This might be
# the case if you hand-released the message before the sender tried to
# confirm it by e-mail, or if the sender sent multiple confirmation
# replies.
# Possible values include:
#
# "bounce"
#    bounce the message - uses the bounce_missing_pending.txt template.
# "drop"
#    silently drop the message
# "ok"
#    deliver the message
# "confirm"
#    request confirmation for the message
# "hold"
#    silently hold message in pending queue
#
# Default is bounce
if not 'ACTION_MISSING_PENDING' in vars():
    ACTION_MISSING_PENDING = "bounce"

# ACTION_OUTGOING
# Specifies how outgoing messages should be tagged by default if there
# are no matches in FILTER_OUTGOING and no X-TMDA header.
# Possible values include:
#
# "bare[=append]"
#    don't tag
#
# "dated[=timeout_interval]"
#    tag with a dated address
#
# "sender[=sender_address]"
#    tag with a sender address
#
# "exp=full_address"
#    tag with explicit address
#
# "kw=keyword"
#    tag with a keyword address
#
# Default is dated
if not 'ACTION_OUTGOING' in vars():
    ACTION_OUTGOING = "dated"

# FINGERPRINT
# A list containing one or more message headers whose values should be
# used to create a "fingerprint" for the message.  If the header value
# is 'body' (all-lowercase), the message body content is used instead
# of a header value.  The fingerprint is a SHA-1 HMAC digest
# represented as a base64-encoded string.  This fingerprint will be
# added to your outgoing client-side messages (i.e, messages sent with
# tmda-sendmail) in an `X-TMDA-Fingerprint' header prior to injection.
#
# Examples:
#
# FINGERPRINT = ["message-id"]
# FINGERPRINT = ["message-id", "from", "date"]
# FINGERPRINT = ["message-id", "body"]
#
# Things to keep in mind, especially if verifying these fingerprints
# with non-TMDA code.
#
# * CRYPT_KEY is converted from hex into raw binary before it is
#   used to create the HMAC object.
# * The order of header names in the FINGERPRINT list is important;
#   updates are made in the order listed.
# * If a listed header doesn't exist in the message, no update attempt
#   will be made for that header.
# * For a listed header, only the header value (i.e, text after the
#   colon) is used.  Additionally, leading and trailing whitespace (but
#   not internal whitespace) is stripped from that value.
#
# For example, if the listed headers consisted of:
#
# Message-ID: <20011212192455.A7060@nightshade.la.mastaler.com>
# From: "Jason R. Mastaler" <jason-dated-1008901496.5356ec@mastaler.com>
# Date: Wed, 12 Dec 2001 19:24:55 -0700
#
# The strings which are used to create the HMAC digest are the header
# values only (right hand side of Header:).
#
# The following header would then be added to the outgoing message:
#
# X-TMDA-Fingerprint: vDBoOHtIUE6VniJguxJ+w2fR5bU
#
# No default
if not 'FINGERPRINT' in vars():
    FINGERPRINT = None

# FULLNAME
# Your full name.
#
# Example:
# FULLNAME = "John Doe"
#
# Default comes from your environment or the password file.
if not 'FULLNAME' in vars():
    FULLNAME = Util.getfullname()

# HMAC_BYTES
# An integer which determines the length of the HMACs used in TMDA's
# "cookies".  Read the `CRYPTO' file for more information.  Changing
# this value will will invalidate all previously generated HMACs.
#
# Default is 3 (24-bit HMACs)
if not 'HMAC_BYTES' in vars():
    HMAC_BYTES = 3

# HOSTNAME
# The right-hand side of your email address (after `@').  Used only in
# cases where TMDA can't determine this itself.
#
# Example:
# HOSTNAME = "domain.dom"
#
# Defaults to the fully qualified domain name of the localhost.
if not 'HOSTNAME' in vars():
    HOSTNAME = Util.gethostname()

# LOGFILE_DEBUG
# Filename which uncaught exceptions should be written to.
#
# Examples:
#
# LOGFILE_DEBUG = "/path/to/logs/tmda.debug"
# LOGFILE_DEBUG = "~/.tmda/logs/debug"
#
# No default.
if not 'LOGFILE_DEBUG' in vars():
    LOGFILE_DEBUG = None

# LOGFILE_INCOMING
# Filename which incoming delivery (i.e, tmda-filter) summaries should
# be written to.
#
# Examples:
#
# LOGFILE_INCOMING = "/path/to/logs/tmda.in"
# LOGFILE_INCOMING = "~/.tmda/logs/incoming"
#
# No default.
if not 'LOGFILE_INCOMING' in vars():
    LOGFILE_INCOMING = None

# LOGFILE_OUTGOING
# Filename which outgoing message (i.e, tmda-sendmail) summaries
# should be written to.
#
# Examples:
#
# LOGFILE_OUTGOING = "/path/to/logs/tmda.out"
# LOGFILE_OUTGOING = "~/.tmda/logs/outgoing"
#
# No default.
if not 'LOGFILE_OUTGOING' in vars():
    LOGFILE_OUTGOING = None

# MESSAGE_FROM_STYLE
# Specifies how `From' and `Resent-From' headers should look when
# tagging outgoing messages with tmda-sendmail.  There are two valid
# values:
#
# "address"
#      Just the address - king@grassland.com
#
# "angles"
#      Elvis Parsley <king@grassland.com>
#
# Default is "angles".
if not 'MESSAGE_FROM_STYLE' in vars():
    MESSAGE_FROM_STYLE = 'angles'

# MESSAGE_TAG_HEADER_STYLE
# Specifies how headers (other than `From' and `Resent-From') should
# look when tagging outgoing messages with tmda-sendmail.  These are
# the headers such as Reply-To which are defined using the `tag'
# action in your FILTER_OUTGOING file.
#
# The valid values and default value is identical to that of
# MESSAGE_FROM_STYLE.
if not 'MESSAGE_TAG_HEADER_STYLE' in vars():
    MESSAGE_TAG_HEADER_STYLE = 'angles'

# MAX_AUTORESPONSES_PER_DAY
# An integer specifying the maximum number of automatic responses sent
# to a given sender address in a day.  This includes _all_
# auto-responses sent by TMDA (confirmation requests, confirmation
# acceptance notices, failure notices, etc.)
#
# This limit prevents response loops between TMDA and misconfigured
# remote auto-responders.  TMDA already inhibits automatic replies to
# any message that looks like a mailing list message or a bounce
# message.  This is a fallback safety valve so it should be set fairly
# high.  Set to 0 for no limit.
#
# Default is 50
if not 'MAX_AUTORESPONSES_PER_DAY' in vars():
    MAX_AUTORESPONSES_PER_DAY = 50

# RESPONSE_DIR
# Full path to a directory containing auto-response rate-limiting
# information.  Only consulted if MAX_AUTORESPONSES_PER_DAY != 0
#
# Default is ~/.tmda/responses
if not 'RESPONSE_DIR' in vars() and MAX_AUTORESPONSES_PER_DAY != 0:
    RESPONSE_DIR = os.path.join(DATADIR, 'responses')

# AUTORESPONSE_INCLUDE_SENDER_COPY
# An integer which controls whether a copy of the sender's message is
# included or not when sending an auto response.  Available options:
#
# 0 - do not include any portion of the sender's message.
# 1 - include only the headers from the sender's message.
# 2 - include the sender's entire message.
#
# 2 is *highly* recommended. Not only to give the sender a clear
# indication of which message is being responded to, but also to
# preserve the message for the sender in case she didn't save a copy
# when sending it.
#
# Default is 2
if not 'AUTORESPONSE_INCLUDE_SENDER_COPY' in vars():
    AUTORESPONSE_INCLUDE_SENDER_COPY = 2

# DB_CONNECTION
# Python DB API Connection object. This is specific to the database
# and should be created in the ~/.tmda/config file.  This is typically
# created by importing the appropriate module and calling the connect()
# function.
#
# Example:
# import MySQLdb
# DB_CONNECTION = MySQLdb.connect("...")
#
# Default is None
if not 'DB_CONNECTION' in vars():
    DB_CONNECTION = None

# DB_CONFIRM_APPEND
# SQL INSERT statement to be used to insert confirmed sender addresses
# into a SQL database. The Python DB API will take care of properly
# quoting parameters that are strings.
# Requires a valid DB_CONNECTION object.
#
# Available substition parameters are:
#
# %(recipient)s  - USERNAME@HOSTNAME
# %(username)s   - USERNAME
# %(hostname)s   - HOSTNAME
# %(sender)s     - sender's address (envelope sender or X-Primary-Address)
#
# Examples:
#
# DB_CONFIRM_APPEND = """
#  INSERT INTO whitelist (user_email, address)
#       VALUES (%(recipient)s, %(sender)s)"""
#
# DB_CONFIRM_APPEND = """
#  INSERT INTO wildcard_list (uid, address, action)
#       SELECT uid, %(sender)s, 'accept'
#         FROM users
#        WHERE users.email = %(recipient)s"""
#
# Default is None
if not 'DB_CONFIRM_APPEND' in vars():
    DB_CONFIRM_APPEND = None

# DB_BARE_APPEND
# SQL INSERT statement to be used to insert recipient addresses into
# a SQL database if the outgoing <action> was 'bare=append'. The Python
# DB API will take care of properly quoting parameters that are strings.
# Requires a valid DB_CONNECTION object.
#
# Available substition parameters are:
#
# %(recipient)s  - recipient's email address
# %(username)s   - USERNAME (of TMDA user)
# %(hostname)s   - HOSTNAME (of TMDA user)
# %(sender)s     - USERNAME@HOSTNAME (address of TMDA user)
# %(fromheader)s - address of TMDA user in From: header field
#
# Examples:
#
# DB_BARE_APPEND = """
#  INSERT INTO whitelist (user_email, address)
#       VALUES (%(sender)s, %(recipient)s)"""
#
# Default is None
if not 'DB_BARE_APPEND' in vars():
    DB_BARE_APPEND = None

# PENDING_DIR
# Full path to the directory containing messages pending confirmation
# (aka, the "pending queue").  If this directory doesn't exist, it
# will automatically be created by TMDA with 0700 permissions when the
# first message arrives.
#
# Default is ~/.tmda/pending/
if not 'PENDING_DIR' in vars():
    PENDING_DIR = os.path.join(DATADIR, 'pending')

# PENDING_QUEUE_FORMAT
# A string specifying the format of TMDA's pending queue where
# unconfirmed messages are stored.
# Possible values include:
#
# "original"
#      A custom TMDA format where messages are stored one per file in a
#      directory (PENDING_DIR).  Offers high performance, but can only
#      be browsed with TMDA tools like 'tmda-pending' and 'tmda-cgi'.
#
# "maildir"
#      Maildir is a specific one-file-per-message organization that
#      was introduced with the qmail system by D.J. Bernstein.  For
#      more information, see http://wiki.tmda.net/TmdaPendingAsMaildir
#
# Default is "original".
if not 'PENDING_QUEUE_FORMAT' in vars():
    PENDING_QUEUE_FORMAT = 'original'

# PENDING_LIFETIME
# A time interval describing how long a message can live in the
# pending queue before it's subject to automated deletion by
# tmda-filter (a feature controlled by the PENDING_CLEANUP_ODDS
# setting).
#
# Time intervals can be expressed in seconds (s), minutes (m), hours
# (h), days (d), weeks (w), months (M), or years (Y).
#
# Examples:
#
# PENDING_LIFETIME = "24h" # messages can live for 24 hours
# PENDING_LIFETIME = "1M"  # messages can live for 1 month
#
# Default is 14d (14 day lifetime)
if not 'PENDING_LIFETIME' in vars():
    PENDING_LIFETIME = '14d'

# PENDING_CLEANUP_ODDS
# A floating point number which describes the odds that tmda-filter
# will automatically clean the pending queue of expired messages upon
# receipt of an incoming message.  The lifetime of a message in the
# pending queue is controlled by the PENDING_LIFETIME setting.
#
# If you wish to disable this feature in order to clean the queue by
# hand, or through cron, set this value to 0.0.  If you wish to
# trigger a cleanup every time a message arrives, set it to 1.0.
#
# The closer this value gets to 1.0, the fewer messages you'll have in
# your pending queue beyond PENDING_LIFETIME, but at some additional
# expense upon delivery.
#
# Examples:
#
# PENDING_CLEANUP_ODDS = 0.0   # 0% chance
# PENDING_CLEANUP_ODDS = 1.0   # 100% chance
# PENDING_CLEANUP_ODDS = 0.025 # 2.5% chance
#
# Default is 0.01, or 1% chance of cleanup for every message received,
# or cleanup approximately once per 100 messages received.
if not 'PENDING_CLEANUP_ODDS' in vars():
    PENDING_CLEANUP_ODDS = 0.01

# PENDING_CACHE
# Path to the cache file used when tmda-pending is invoked with the
# --cache option.
#
# Default is ~/.tmda/.pendingcache
if not 'PENDING_CACHE' in vars():
    PENDING_CACHE = os.path.join(DATADIR, '.pendingcache')

# PENDING_CACHE_LEN
# An integer which specifies the maximum number of entries held by
# PENDING_CACHE.  Make sure this is greater than the number of
# messages kept in your pending queue, or else you'll start seeing
# previously viewed messages again.
#
# Default is 5000
if not 'PENDING_CACHE_LEN' in vars():
    PENDING_CACHE_LEN = 5000

# PENDING_BLACKLIST_APPEND
# Filename to which a sender's e-mail address should be appended
# when a message is "blacklisted" by tmda-pending.
#
# Examples:
#
# PENDING_BLACKLIST_APPEND = "/full/path/to/blacklist"
# PENDING_BLACKLIST_APPEND = "~/.tmda/lists/blacklist"
#
# No default
if not 'PENDING_BLACKLIST_APPEND' in vars():
    PENDING_BLACKLIST_APPEND = None

# DB_PENDING_BLACKLIST_APPEND
# SQL INSERT statement to be used to insert blacklisted sender addresses
# into a SQL database. The Python DB API will take care of properly
# quoting parameters that are strings.
#
# Requires a valid DB_CONNECTION object.
#
# Available substitution parameters are:
#
# %(recipient)s  - USERNAME@HOSTNAME
# %(username)s   - USERNAME
# %(hostname)s   - HOSTNAME
# %(sender)s     - sender's address (envelope sender or X-Primary-Address)
#
# Examples:
#
# DB_PENDING_BLACKLIST_APPEND = """
#  INSERT INTO blacklist (user_email, address)
#       VALUES (%(recipient)s, %(sender)s)"""
#
# DB_PENDING_BLACKLIST_APPEND = """
#  INSERT INTO wildcard_list (uid, address, action)
#       SELECT uid, %(sender)s, 'drop'
#         FROM users
#        WHERE users.email = %(recipient)s"""
#
# Default is None
if not 'DB_PENDING_BLACKLIST_APPEND' in vars():
    DB_PENDING_BLACKLIST_APPEND = None

# PENDING_DELETE_APPEND
# Filename to which a sender's e-mail address should be automatically
# appended when a message is "deleted" by tmda-pending.  tmda-filter's
# automated pending queue cleanup feature (see PENDING_CLEANUP_ODDS)
# also respects this setting.
#
# Examples:
#
# PENDING_DELETE_APPEND = "/full/path/to/blacklist"
# PENDING_DELETE_APPEND = "~/.tmda/lists/blacklist"
#
# No default
if not 'PENDING_DELETE_APPEND' in vars():
    PENDING_DELETE_APPEND = None

# DB_PENDING_DELETE_APPEND
# SQL INSERT statement to be used to insert deleted sender addresses
# into a SQL database. The Python DB API will take care of properly
# quoting parameters that are strings.
#
# Requires a valid DB_CONNECTION object.
#
# Available substitution parameters are:
#
# %(recipient)s  - USERNAME@HOSTNAME
# %(username)s   - USERNAME
# %(hostname)s   - HOSTNAME
# %(sender)s     - sender's address (envelope sender or X-Primary-Address)
#
# Examples:
#
# DB_PENDING_DELETE_APPEND = """
#  INSERT INTO blacklist (user_email, address)
#       VALUES (%(recipient)s, %(sender)s)"""
#
# DB_PENDING_DELETE_APPEND = """
#  INSERT INTO wildcard_list (uid, address, action)
#       SELECT uid, %(sender)s, 'confirm'
#         FROM users
#        WHERE users.email = %(recipient)s"""
#
# Default is None
if not 'DB_PENDING_DELETE_APPEND' in vars():
    DB_PENDING_DELETE_APPEND = None

# PENDING_RELEASE_APPEND
# Filename to which a sender's e-mail address should be automatically
# appended when a message is "released" by tmda-pending.
#
# Examples:
#
# PENDING_RELEASE_APPEND = "/full/path/to/whitelist"
# PENDING_RELEASE_APPEND = "~/.tmda/lists/whitelist"
#
# No default
if not 'PENDING_RELEASE_APPEND' in vars():
    PENDING_RELEASE_APPEND = None

# DB_PENDING_RELEASE_APPEND
# SQL INSERT statement to be used to insert released sender addresses
# into a SQL database. The Python DB API will take care of properly
# quoting parameters that are strings.
#
# Requires a valid DB_CONNECTION object.
#
# Available substitution parameters are:
#
# %(recipient)s  - USERNAME@HOSTNAME
# %(username)s   - USERNAME
# %(hostname)s   - HOSTNAME
# %(sender)s     - sender's address (envelope sender or X-Primary-Address)
#
# Examples:
#
# DB_PENDING_RELEASE_APPEND = """
#  INSERT INTO whitelist (user_email, address)
#       VALUES (%(recipient)s, %(sender)s)"""
#
# DB_PENDING_RELEASE_APPEND = """
#  INSERT INTO wildcard_list (uid, address, action)
#       SELECT uid, %(sender)s, 'accept'
#         FROM users
#        WHERE users.email = %(recipient)s"""
#
# Default is None
if not 'DB_PENDING_RELEASE_APPEND' in vars():
    DB_PENDING_RELEASE_APPEND = None

# PENDING_WHITELIST_APPEND
# Filename to which a sender's e-mail address should be appended
# when a message is "whitelisted" by tmda-pending.
#
# Examples:
#
# PENDING_WHITELIST_APPEND = "/full/path/to/whitelist"
# PENDING_WHITELIST_APPEND = "~/.tmda/lists/whitelist"
#
# No default
if not 'PENDING_WHITELIST_APPEND' in vars():
    PENDING_WHITELIST_APPEND = None

# DB_PENDING_WHITELIST_APPEND
# SQL INSERT statement to be used to insert whitelisted sender addresses
# into a SQL database. The Python DB API will take care of properly
# quoting parameters that are strings.
#
# Requires a valid DB_CONNECTION object.
#
# Available substitution parameters are:
#
# %(recipient)s  - USERNAME@HOSTNAME
# %(username)s   - USERNAME
# %(hostname)s   - HOSTNAME
# %(sender)s     - sender's address (envelope sender or X-Primary-Address)
#
# Examples:
#
# DB_PENDING_WHITELIST_APPEND = """
#  INSERT INTO whitelist (user_email, address)
#       VALUES (%(recipient)s, %(sender)s)"""
#
# DB_PENDING_WHITELIST_APPEND = """
#  INSERT INTO wildcard_list (uid, address, action)
#       SELECT uid, %(sender)s, 'accept'
#         FROM users
#        WHERE users.email = %(recipient)s"""
#
# Default is None
if not 'DB_PENDING_WHITELIST_APPEND' in vars():
    DB_PENDING_WHITELIST_APPEND = None

# PENDING_WHITELIST_RELEASE
# An option detailing the action taken when 'Whitelist' is the
# current action in tmda-pending or tmda-cgi
#
# Available options:
#
# 0 - 'Whitelist' does not release any messages, only appends
#     the envelope sender to PENDING_WHITELIST_APPEND
#
# 1 - 'Whitelist' releases the current message and also appends
#     the envelope sender to PENDING_WHITELIST_APPEND
#
# Default is 1
if not 'PENDING_WHITELIST_RELEASE' in vars():
    PENDING_WHITELIST_RELEASE = 1

# ADDED_HEADERS_CLIENT
# A Python dictionary containing one or more header:value string pairs
# that should be added to _all_ outgoing client-side messages (i.e,
# messages sent with tmda-sendmail) prior to injection.  Listed
# headers and their values are case-sensitive.
#
# As the examples below illustrate, the full power of Python is
# available to create these headers -- just make sure both the header
# and its value end up as strings.
#
# Examples:
#
# ADDED_HEADERS_CLIENT = {"X-Fact" : "Father Hennepin Discovered Niagra Falls"}
# import time, os, random
# ADDED_HEADERS_CLIENT = {
#     "X-Localtime" : time.asctime(),
#     "X-Favorite-Author" : "James Joyce",
#     "X-OperatingSystem" : os.uname()[0],
#     "Organization" : os.environ.get("ORGANIZATION"),
#     "X-Uptime" : os.popen("/usr/bin/uptime").read().strip(),
#     "X-Now-Reading" : random.choice(open
#                                     ("/home/jasonrm/.now-reading").
#                                     readlines()).strip()
#     }
#
# No default
if not 'ADDED_HEADERS_CLIENT' in vars():
    ADDED_HEADERS_CLIENT = None

# ADDED_HEADERS_SERVER
# A Python dictionary containing one or more header:value string pairs
# that should be added to _all_ outgoing server-side messages (i.e,
# messages sent with tmda-filter) prior to injection.  Listed
# headers and their values are case-sensitive.
#
# See ADDED_HEADERS_CLIENT (above) for some examples.
#
# No default
if not 'ADDED_HEADERS_SERVER' in vars():
    ADDED_HEADERS_SERVER = None

# PRIMARY_ADDRESS_MATCH
# An integer which controls how closely the address in the
# ``X-Primary-Address'' header of an incoming messages must match the
# envelope sender address before it's honored.
#
# If the match is close enough, this address will be used for
# CONFIRM_APPEND instead of the envelope sender, and also added to the
# list of addresses checked against FILTER_INCOMING.
#
# This option is available to limit cases of abuse where a sender
# attempts to "whitelist" an address not his own by using an external
# address in an ``X-Primary-Address'' header.
#
# Available options:
#
# 0 - Never a match. Equivalent to disabling X-Primary-Address recognition.
#
# 1 - Identical addresses match. e.g, king@grassland.com and
# king@grassland.com.
#
# 2 - Usernames and hostnames must match. e.g, king@grassland.com and
# king-dated-1037839131.65d080@grassland.com.
#
# 3 - Usernames and domains must match. e.g, king@grassland.com and
# king-dated-1037839131.65d080@memphis.grassland.com.
#
# 4 - Hostnames must match. e.g, king@grassland.com and
# elvis@grassland.com.
#
# 5 - Domains must match. e.g, king@grassland.com and
# elvis@memphis.grassland.com.
#
# 6 - Always a match. e.g, king@grassland.com and elvis@parsely.com.
#
# Default is 5
if not 'PRIMARY_ADDRESS_MATCH' in vars():
    PRIMARY_ADDRESS_MATCH = 5

# PURGED_HEADERS_CLIENT
# A list containing one or more message headers that should be removed
# from outgoing client-side messages (i.e, messages sent with
# tmda-sendmail) prior to injection.  Listed headers are
# case-insensitive, and the purging will only be attempted if the
# header actually exists.
#
# NOTE: PURGED_HEADERS_CLIENT is run _after_ ADDED_HEADERS (see above).
#
# Examples:
#
# PURGED_HEADERS_CLIENT = ["bcc", "resent-bcc", "x-mailer"]
# PURGED_HEADERS_CLIENT = ["bcc", "resent-bcc", "x-mailer", "user-agent"]
#
# Default is "Bcc:" and "Resent-Bcc"
if not 'PURGED_HEADERS_CLIENT' in vars():
    PURGED_HEADERS_CLIENT = ["bcc", "resent-bcc"]

# PURGED_HEADERS_SERVER
# A list containing one or more message headers that should be removed
# from _all_ outgoing server-side messages (i.e, messages sent with
# tmda-filter) prior to injection.  Listed headers are case-insensitive
# and the purging will only be attempted if the header actually exists.
#
# See PURGED_HEADERS_CLIENT (above) for some examples.
#
# No default
if not 'PURGED_HEADERS_SERVER' in vars():
    PURGED_HEADERS_SERVER = None

# PURGED_HEADERS_DELIVERY
# A list containing one or more message headers that should be removed
# from _all_ delivered messages (i.e, messages stored in an mbox or a
# maildir, forwarded or passed to a program by TMDA).  Listed headers
# are case-insensitive and the purging will only be attempted if the
# header actually exists.
#
# See PURGED_HEADERS_CLIENT (above) for some examples.
#
# No default
if not 'PURGED_HEADERS_DELIVERY' in vars():
    PURGED_HEADERS_DELIVERY = None

# RECIPIENT_HEADER
# A string containing the name of a header (case-insensitive) whose
# contents will be taken as the envelope recipient of the message.
# The header should contain one fully-qualified e-mail address.  This
# can be used in rare cases when you need to override the RECIPIENT
# environment variable, which is how TMDA normally determines the
# envelope recipient address. If EXT isn't set, the address extension
# will also be extracted from RECIPIENT_HEADER.
#
# Example:
#
# RECIPIENT_HEADER = 'x-originally-to'
#
# Then, if the message contains the following header:
#
# X-Originally-To: webmaster@domain.dom
#
# TMDA will take webmaster@domain.dom as the envelope recipient of the
# message rather than the value of RECIPIENT.
#
# WARNING: If you enable this feature, make sure that the method you
# are using to add the header will overwrite or replace an existing
# header of the same name (such as reformail/formail's -i and -I
# options do).  Otherwise the envelope recipient will be invalid which
# will break the confirmation process.
#
# No default
if not 'RECIPIENT_HEADER' in vars():
    RECIPIENT_HEADER = None

# TAGS_CONFIRM
# A list of one or more strings used to identify a confirmation
# address.  The first element in the list will be used when
# generating a new confirmation address.
#
# Example:
#
# TAGS_CONFIRM = ['confirm', 'c']
#
# Default is 'confirm'
if not 'TAGS_CONFIRM' in vars():
    TAGS_CONFIRM = ['confirm']

# TAGS_DATED
# A list of one or more strings used to identify a dated address.  The
# first element in the list will be used by `tmda-address' when
# generating a new dated address.
#
# Example:
#
# TAGS_DATED = ['dated', 'd', 'exp', 'expires']
#
# Default is 'dated'
if not 'TAGS_DATED' in vars():
    TAGS_DATED = ['dated']

# TAGS_KEYWORD
# A list of one or more strings used to identify a keyword address.
# The first element in the list will be used by `tmda-address' when
# generating a new keyword address.
#
# Example:
#
# TAGS_KEYWORD = ['keyword', 'key', 'kw']
#
# Default is 'keyword'
if not 'TAGS_KEYWORD' in vars():
    TAGS_KEYWORD = ['keyword']

# TAGS_SENDER
# A list of one or more strings to identify a sender address.  The
# first element in the list will be used by `tmda-address' when
# generating a new sender address.
#
# Example:
#
# TAGS_SENDER = ['sender', 's']
#
# Default is 'sender'
if not 'TAGS_SENDER' in vars():
    TAGS_SENDER = ['sender']

# TERSE_SUMMARY_HEADERS
# A list containing one or more message headers that should be
# displayed by tmda-pending's `--terse option'.  Listed headers are
# case-insensitive.  'from_name' and 'from_address' can be used to
# specify the Fullname and e-mail address from the message's "From:"
# header.
#
# Examples:
#
# TERSE_SUMMARY_HEADERS = ["return-path"]
# TERSE_SUMMARY_HEADERS = ["from_name", "from_address", "subject"]
#
# Default is the Fullname followed by Subject.
if not 'TERSE_SUMMARY_HEADERS' in vars():
    TERSE_SUMMARY_HEADERS = ['from_name', 'subject']

# TMDAINJECT
# A string containing one or more of the following letters which toggle
# on certain behaviors in tmda-inject (which is used by both
# tmda-sendmail and tmda-ofmipd):
#
# 'd' - Add a new Date field to the message, clobbering any
#       existing Date fields.  Normally tmda-inject only adds a
#       Date field if the incoming message lacks one.
#
# 'i' - Add a new Message-ID field to the message, clobbering any
#       existing Message-ID fields.  Normally tmda-inject only adds a
#       Message-ID field if the incoming message lacks one.
#
# Examples:
#
# TMDAINJECT = "i"
# TMDAINJECT = "di"
#
# No default.
if not 'TMDAINJECT' in vars():
    TMDAINJECT = None

# MAIL_FOLLOWUP_TO
# Inspired by qmail-inject's QMAILMFTFILE feature, MAIL_FOLLOWUP_TO
# automatically adds a Mail-Followup-To field for messages sent to
# mailing lists.  It works for both tmda-sendmail and tmda-ofmipd.
#
# MAIL_FOLLOWUP_TO can either be a list of mailing list addresses, or
# a string pointing to a file containing mailing list addresses, one
# per line.  If To or Cc in the message includes one of those
# addresses (without regard to case), tmda-inject adds a
# Mail-Followup-To field with all the To+Cc addresses.  tmda-inject
# does not add Mail-Followup-To to a message that already has one, or
# if the address file does not exist.
#
# See http://cr.yp.to/proto/replyto.html for more on Mail-Followup-To.
#
# Examples:
#
# MAIL_FOLLOWUP_TO = "/path/to/lists.txt"
# MAIL_FOLLOWUP_TO = "~/.lists"
# MAIL_FOLLOWUP_TO = ["tmda-users@tmda.net", "postfix-users@postfix.org"]
#
# No default.
if not 'MAIL_FOLLOWUP_TO' in vars():
    MAIL_FOLLOWUP_TO = None

# SUMMARY_HEADERS
# A list containing one or more message headers that should be
# displayed by tmda-pending's interactive mode. Listed headers are
# case-insensitive.
#
# Examples:
#
# SUMMARY_HEADERS = ['from', 'subject', 'x-spam-status']
# SUMMARY_HEADERS = ['date', 'from', 'to', 'subject']
#
# Default is Date, From, To, and Subject.
if not 'SUMMARY_HEADERS' in vars():
    SUMMARY_HEADERS = ['date', 'from', 'to', 'subject']

# DATED_TIMEOUT
# The timeout interval for 'dated' addresses.  The available units are
# (Y=years, M=months, w=weeks, d=days, h=hours, m=minutes, s=seconds).
#
# Default is 5d (5 days).
if not 'DATED_TIMEOUT' in vars():
    DATED_TIMEOUT = "5d"

# USERNAME
# The left-hand side of your e-mail address (before `@').
#
# Example:
# USERNAME = "jdoe"
#
# Defaults to your UNIX username.
if not 'USERNAME' in vars():
    USERNAME = Util.getusername()

# TIMEOUT_UNITS
# Dictionary that contains translations of timeout unit strings. This
# dictionary must contains the keys Y,M,w,d,h,m,s with respective
# internationalized strings as values.
#
# Examples:
#
# TIMEOUT_UNITS = {
#       'Y' : "anos",
#       'M' : "meses",
#       'w' : "semanas",
#       'd' : "dias",
#       'h' : "horas",
#       'm' : "minutos",
#       's' : "segundos"}
#
# Default is English values.
if not 'TIMEOUT_UNITS' in vars():
    TIMEOUT_UNITS = {
        'Y' : "years",
        'M' : "months",
        'w' : "weeks",
        'd' : "days",
        'h' : "hours",
        'm' : "minutes",
        's' : "seconds"
        }

# X_TMDA_IN_SUBJECT
# With this variable set to True, tmda-inject will parse the Subject
# header looking for `X-TMDA' actions, and then remove them before
# sending the message.  This is useful for users that desire the
# `X-TMDA' override behavior, but don't use an MUA which easily allows
# addition of arbitrary headers (e.g, Outlook).
#
# The Subject header should contain `X-TMDA' followed by whitespace
# followed by the desired action followed by the real subject.  Case
# is insensitive.
#
# Examples:
#
# Subject: X-TMDA dated Re: You're fired!
# Subject:     X-TMDA dated=5M Re: You're fired!
# Subject: X-TMDA   sender      Re: You're fired!
#
# In all cases, the resulting subject will simply be:
#
# Subject: Re: You're fired!
#
# Default is False (turned off)
if not 'X_TMDA_IN_SUBJECT' in vars():
    X_TMDA_IN_SUBJECT = False

# CRYPT_KEY_FILE
# File which contains your unique TMDA secret key generated by the
# `tmda-keygen' program.  The key should be unquoted in the file.
# This file must be chmod 400 or 600, unless ALLOW_MODE_640 is on.
# Default is ~/.tmda/crypt_key
if not 'CRYPT_KEY_FILE' in vars():
    CRYPT_KEY_FILE = os.path.join(DATADIR, 'crypt_key')

###################################
# END of user configurable settings
###################################

# Variables that should be run through os.path.expanduser() since they
# contain pathnames.  Remember to remove variables from this dict when
# removing them from the code above.
_path_vars = {
    'BARE_APPEND': None,
    'CGI_SETTINGS': None,
    'CONFIRM_APPEND': None,
    'CRYPT_KEY_FILE': None,
    'DATADIR': None,
    'DELIVERY': None,
    'FILTER_INCOMING': None,
    'FILTER_OUTGOING': None,
    'GLOBAL_TMDARC': None,
    'LOGFILE_DEBUG': None,
    'LOGFILE_INCOMING': None,
    'LOGFILE_OUTGOING': None,
    'MAIL_FOLLOWUP_TO': None,
    'PENDING_BLACKLIST_APPEND': None,
    'PENDING_CACHE': None,
    'PENDING_DELETE_APPEND': None,
    'PENDING_DIR': None,
    'PENDING_RELEASE_APPEND': None,
    'PENDING_WHITELIST_APPEND': None,
    'RESPONSE_DIR': None,
    'SENDMAIL_PROGRAM': None,
    'TEMPLATE_DIR': None,
    'VIRTUALDOMAINS': None
    }

_defaults = globals()
for var in _path_vars:
    if var in _defaults and isinstance(_defaults[var], str):
        _defaults[var] = os.path.expanduser(_defaults[var])

# Finish processing CRYPT_KEY_FILE/CRYPT_KEY
if os.path.exists(CRYPT_KEY_FILE):
    if os.name == 'posix':
        crypt_key_filemode = Util.getfilemode(CRYPT_KEY_FILE)
        if crypt_key_filemode not in (0o400, 0o600):
            if ALLOW_MODE_640 and crypt_key_filemode == 0o640:
                pass
            else:
                raise ConfigError( \
                      CRYPT_KEY_FILE + " must be chmod 400 or 600!")
else:
    if os.environ.get('TMDA_CGI_MODE') == 'no-su':
        pass
    else:
        raise ConfigError("Can't find key file: " + CRYPT_KEY_FILE)

# Read key from CRYPT_KEY_FILE, and then convert it from hex back into
# raw binary.  Hex has only 4 bits of entropy per byte as opposed to 8.
try:
    CRYPT_KEY = binascii.unhexlify(open(CRYPT_KEY_FILE).read().strip())
except IOError:
    if os.environ.get('TMDA_CGI_MODE') == 'no-su':
        pass
    else:
        raise

