diff --git a/mailman3/Dockerfile b/mailman3/Dockerfile new file mode 100644 index 0000000..495e433 --- /dev/null +++ b/mailman3/Dockerfile @@ -0,0 +1,40 @@ +######################################### +# Dockerfile to setup GNU Mailman Suite +######################################### + +FROM python:2.7 + +# File Author / Maintainer +MAINTAINER Joshua Bird + +RUN apt-get update +RUN apt-get install -y nginx + +RUN apt-get install -y rsync bash +RUN apt-get install -y vim +RUN apt-get install -y git python3.4-dev python-dev python-pip python-virtualenv +RUN apt-get install -y nodejs npm && \ + npm install -g less && \ + ln -s /usr/bin/nodejs /usr/bin/node +RUN apt-get install -y ruby-full rubygems +RUN gem install sass +RUN apt-get install -y postgresql +RUN DEBIAN_FRONTEND=noninteractive apt-get -y install postfix +RUN apt-get install -y libsasl2-modules + +# get mailman-bundler +WORKDIR /mailman3 +RUN git clone https://gitlab.com/mailman/mailman-bundler.git +RUN pip install zc.buildout +WORKDIR /mailman3/mailman-bundler + + +RUN buildout +RUN virtualenv venv +RUN . venv/bin/activate + +# Expose ports +EXPOSE 8000 +EXPOSE 8001 + +ENTRYPOINT /mailman3/scripts/run diff --git a/mailman3/README.md b/mailman3/README.md new file mode 100644 index 0000000..7ff30c2 --- /dev/null +++ b/mailman3/README.md @@ -0,0 +1,28 @@ +# mailman3 + +Dockerfile and configuration as applicable for the OSF. + +> #### Incomplete + +> - Move postgres to an external container +> - Consolidate configuration options for mailman3, mailman-bundler, and postfix + +## Information + +This container is configured here for production. +- Mailman is set up to use gunicorn as the WSGI server. +- The web interface, the union of HyperKitty and Postorious, listens on the container's port `8000`. `docker-compose.yml` maps that to the host's port `18000` to avoid collision with OSF services. +- The API Listens on the container's port `8001`, and requires credentials. These are configured in `config/mailman3/mailman-bundler/venv-3.4/lib/python3.4/site-packages/mailman/config/schema.cfg`. This will likely change in order to promote this Docker configuration's ease of use. + +Check out the Mailman Docs for more information about this application: http://pythonhosted.org/mailman/README.html, or look at the API client for ideas on how to interact with mailman: http://mailmanclient.readthedocs.io/en/latest/ + + +## Setup + +- Ensure docker and docker-compose are configured and installed correctly +- `# docker-compose up` +- To run in the background, wait until the server is running, and then `^C`, +- `# docker-compose start` + + + diff --git a/mailman3/config/etc/nginx/sites-enabled/default b/mailman3/config/etc/nginx/sites-enabled/default new file mode 100644 index 0000000..f38e583 --- /dev/null +++ b/mailman3/config/etc/nginx/sites-enabled/default @@ -0,0 +1,14 @@ +server { + listen 18000; + + server_name mailman.local; + + location /static { + autoindex on; + root /var/spool/mailman-web; + } + + location / { + proxy_pass http://localhost:8000; + } +} diff --git a/mailman3/config/etc/postfix/dynamicmaps.cf b/mailman3/config/etc/postfix/dynamicmaps.cf new file mode 100644 index 0000000..8aedda3 --- /dev/null +++ b/mailman3/config/etc/postfix/dynamicmaps.cf @@ -0,0 +1,7 @@ +# Postfix dynamic maps configuration file. +# +#type location of .so file open function (mkmap func) +#==== ================================ ============= ============ +tcp /usr/lib/postfix/dict_tcp.so dict_tcp_open +sqlite /usr/lib/postfix/dict_sqlite.so dict_sqlite_open +mysql /usr/lib/postfix/dict_mysql.so dict_mysql_open diff --git a/mailman3/config/etc/postfix/main.cf b/mailman3/config/etc/postfix/main.cf new file mode 100644 index 0000000..84386fa --- /dev/null +++ b/mailman3/config/etc/postfix/main.cf @@ -0,0 +1,200 @@ + + +### Verify these directory settings - they are critical to Postfix operation. +command_directory = /usr/sbin +daemon_directory = /usr/lib/postfix + +### Interface to listen on +inet_interfaces = all + + + +### smtp banner +mail_name = OSF Mail Daemon +smtpd_banner = $mail_name. All Spam Is Reported. ESMTP + +### Who delivers the mail (never root for security). +#mail_owner = postfix +#setgid_group = postdrop + +### Default user to deliver mail to (NEVER ENABLE) +luser_relay = + +### The myorigin parameter specifies the domain that appears in mail that is posted on/through this machine. +append_dot_mydomain = no +append_at_myorigin = yes + +### alias's +alias_maps = hash:/etc/aliases +alias_database = hash:/etc/aliases + +### Whitelist of accepted recipients. $alias_maps means only addreses in +### /etc/aliases are accepted to be locally delivered. +# local_recipient_maps = $alias_maps + +### the internet hostname of this mail system +myhostname = mechanysm +mydomain = mechanysm.com +myorigin = $myhostname + +virtual_transport = lmtp:unix:private/dovecot-lmtp +virtual_mailbox_domains = energy-foundation.org npenergyfoundation.org npenergychoice.org discourse.mechanysm.com mechanysm.com +virtual_mailbox_base = /var/mail +virtual_mailbox_maps = hash:/etc/postfix/vmaps +virtual_minimum_uid = 100 +virtual_uid_maps = static:7788 +virtual_gid_maps = static:7788 + +### The mydestination parameter specifies what domains this machine will deliver locally, instead +### of forwarding to another machine. The default is to receive mail for the machine itself. +mydestination = lists.mechanysm.com + +### External Networks to accept RELAYED mail from. +#mynetworks = 0.0.0.0/0 +mynetworks_style = host + +### Where to send mail that is delivered locally. +#mailbox_command = procmail -a "$EXTENSION" + +### How much of the message in bytes will be bounced back to the sender. +bounce_size_limit = 1000 + +### No limit on mailbox size. +mailbox_size_limit = 0 + +### Message Restrictions +# header_checks = regexp:/etc/postfix/header_checks + +### Limit sent/recieved emails to 100 Megs "(header+body+attachment)x(mime-encoding) <= 100 meg" +message_size_limit = 102400000 + +### How long do messages stay in the queue before being sent back to the sender. (in days) +### By default, postfix attempts to resend the message every (1000 secs)x(# attempts)x(days). +bounce_queue_lifetime = 4h +maximal_queue_lifetime = 4h +delay_warning_time = 1h + +### Parallel delivery force (local=2 and dest=20 are aggressive) +local_destination_concurrency_limit = 2 +default_destination_concurrency_limit = 20 + +### Max flow rate (1 sec delay per 50 emails/sec over the number of emails delivered/sec) +in_flow_delay = 1s + +### Require strict RFC 821-style envelope addresses +strict_rfc821_envelopes = yes + +### Limit the info given to outside servers +show_user_unknown_table_name = no + +### no one needs to ask our server who is on it +disable_vrfy_command = yes + +### clients must send a HELO (or EHLO) command at the beginning of an SMTP session. +#smtpd_helo_required = yes + +### Notification and delimiter +biff = no +recipient_delimiter = + + +#### user%domain != user@domain +allow_percent_hack = no + +#### user!domain != user@domain +swap_bangpath = no + +#smtpd_sasl_type = dovecot +#smtpd_sasl_path = private/auth +#smtpd_sasl_auth_enable = no + +smtpd_tls_cert_file = /etc/ssl/lists.mechanysm.com.crt +smtpd_tls_key_file = /etc/ssl/lists.mechanysm.com.key +#smtpd_tls_CAfile = /etc/ssl/cacert.pem +smtpd_tls_auth_only = yes +#smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache +#smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache +smtpd_tls_security_level = none +smtpd_tls_protocols = !SSLv2, !SSLv3 +tls_random_source = dev:/dev/urandom + +smtpd_tls_loglevel = 3 + +local_recipient_maps = proxy:unix:passwd.byname $alias_maps + +### Tarpit until RCPT TO: to reject the email for nagios compatability +#smtpd_delay_reject = yes + +### Tarpit those bots/clients/spammers who send errors or scan for accounts +#smtpd_error_sleep_time = 20 +#smtpd_soft_error_limit = 1 +#smtpd_hard_error_limit = 3 +#smtpd_junk_command_limit = 2 + +### Reject codes == 554 +#access_map_reject_code = 554 +#invalid_hostname_reject_code = 554 +#maps_rbl_reject_code = 554 +#multi_recipient_bounce_reject_code = 554 +#non_fqdn_reject_code = 554 +#plaintext_reject_code = 554 +#reject_code = 554 +#relay_domains_reject_code = 554 +#unknown_address_reject_code = 554 +#unknown_client_reject_code = 450 +#unknown_hostname_reject_code = 450 +#unknown_local_recipient_reject_code = 554 +#unknown_relay_recipient_reject_code = 554 +#unknown_virtual_alias_reject_code = 554 +#unknown_virtual_mailbox_reject_code = 554 +#unverified_recipient_reject_code = 554 +#unverified_sender_reject_code = 554 + +### SMTP Restrictions +smtpd_client_restrictions = +# permit_mynetworks, +# permit_sasl_authenticated, +# reject_invalid_hostname, +# reject_rbl_client zen.spamhaus.org, +# reject_unknown_client, + permit + +#smtpd_helo_restrictions = +# permit + +smtpd_recipient_restrictions = + #permit_sasl_authenticated, + #permit_mynetworks, + #reject_unauth_destination + permit + +#smtpd_sender_restrictions = +# permit_mynetworks, +# permit_sasl_authenticated, +# reject_non_fqdn_sender, +# reject_unknown_sender_domain, +# reject_unknown_address + +#smtpd_etrn_restrictions = +# permit_mynetworks, +# reject + +#smtpd_data_restrictions = +# reject_unauth_pipelining, +# reject_multi_recipient_bounce, +# permit + +##################### END ##################################################### +readme_directory = /usr/share/doc/postfix +html_directory = /usr/share/doc/postfix/html +smtpd_relay_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, permit + +transport_maps = hash:/mailman3/mailman-bundler/var/data/postfix_lmtp +local_recipient_maps = hash:/mailman3/mailman-bundler/var/data/postfix_lmtp +relay_domains = hash:/mailman3/mailman-bundler/var/data/postfix_domains + +smtp_sasl_auth_enable = yes +smtp_sasl_password_maps = static:halcyonchimera:8426133AWasdpiybG568 +smtp_sasl_security_options = noanonymous +smtp_tls_security_level = encrypt +header_size_limit = 4096000 +relayhost = [smtp.sendgrid.net]:587 diff --git a/mailman3/config/etc/postfix/master.cf b/mailman3/config/etc/postfix/master.cf new file mode 100644 index 0000000..55fc363 --- /dev/null +++ b/mailman3/config/etc/postfix/master.cf @@ -0,0 +1,119 @@ +# +# Postfix master process configuration file. For details on the format +# of the file, see the master(5) manual page (command: "man 5 master"). +# +# Do not forget to execute "postfix reload" after editing this file. +# +# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (yes) (never) (100) +# ========================================================================== +smtp inet n - - - - smtpd -v + -o smtpd_tls_cert_file=/etc/ssl/certs/energy-foundation.pem + -o smtpd_tls_key_file=/etc/ssl/private/energy-foundation.key +#smtp inet n - - - 1 postscreen +smtpd pass - - - - - smtpd -v + -o smtpd_tls_wrappermode=yes + -o smtpd_tls_cert_file=/etc/ssl/certs/energy-foundation.pem + -o smtpd_tls_key_file=/etc/ssl/private/energy-foundation.key +#dnsblog unix - - - - 0 dnsblog +#tlsproxy unix - - - - 0 tlsproxy +submission inet n - n - - smtpd -v +# -o syslog_name=postfix/submission +# -o smtpd_tls_security_level=encrypt +# -o smtpd_sasl_auth_enable=yes +# -o smtpd_client_restrictions=permit_sasl_authenticated,reject +# -o smtpd_recipient_restrictions=check_relay_domain, permit_sasl_authenticated, reject +# -o milter_macro_daemon_name=ORIGINATING +# -o smtpd_tls_wrappermode=no +# -o smtpd_sasl_auth_enable=yes +# -o smtpd_sasl_type=dovecot +# -o milter_macro_daemon_name=ORIGINATING +#628 inet n - - - - qmqpd +pickup fifo n - - 60 1 pickup +cleanup unix n - - - 0 cleanup +qmgr fifo n - n 300 1 qmgr +#qmgr fifo n - n 300 1 oqmgr +tlsmgr unix - - n 1000? 1 tlsmgr +rewrite unix - - - - - trivial-rewrite +bounce unix - - - - 0 bounce +defer unix - - - - 0 bounce +trace unix - - - - 0 bounce +verify unix - - - - 1 verify +flush unix n - - 1000? 0 flush +proxymap unix - - n - - proxymap +proxywrite unix - - n - 1 proxymap +smtp unix - - - - - smtp -v +relay unix - - - - - smtp +# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 +showq unix n - - - - showq +error unix - - - - - error +retry unix - - - - - error +discard unix - - - - - discard +local unix - n n - - local +virtual unix - n n - - virtual +lmtp unix - - - - - lmtp +anvil unix - - - - 1 anvil +scache unix - - - - 1 scache +# +# ==================================================================== +# Interfaces to non-Postfix software. Be sure to examine the manual +# pages of the non-Postfix software to find out what options it wants. +# +# Many of the following services use the Postfix pipe(8) delivery +# agent. See the pipe(8) man page for information about ${recipient} +# and other message envelope options. +# ==================================================================== +# +# maildrop. See the Postfix MAILDROP_README file for details. +# Also specify in main.cf: maildrop_destination_recipient_limit=1 +# +maildrop unix - n n - - pipe + flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient} +# +# ==================================================================== +# +# Recent Cyrus versions can use the existing "lmtp" master.cf entry. +# +# Specify in cyrus.conf: +# lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4 +# +# Specify in main.cf one or more of the following: +# mailbox_transport = lmtp:inet:localhost +# virtual_transport = lmtp:inet:localhost +# +# ==================================================================== +# +# Cyrus 2.1.5 (Amos Gouaux) +# Also specify in main.cf: cyrus_destination_recipient_limit=1 +# +#cyrus unix - n n - - pipe +# user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user} +# +# ==================================================================== +# Old example of delivery via Cyrus. +# +#old-cyrus unix - n n - - pipe +# flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user} +# +# ==================================================================== +# +# See the Postfix UUCP_README file for configuration details. +# +uucp unix - n n - - pipe + flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) +# +# Other external delivery methods. +# +ifmail unix - n n - - pipe + flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient) +bsmtp unix - n n - - pipe + flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient +scalemail-backend unix - n n - 2 pipe + flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension} +mailman unix - n n - - pipe + flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py + ${nexthop} ${user} + +#dovecot unix - n n - - pipe +# flags=DRhu user=email:email argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient} -n -m ${extension} diff --git a/mailman3/config/etc/postfix/post-install b/mailman3/config/etc/postfix/post-install new file mode 100755 index 0000000..7e79c92 --- /dev/null +++ b/mailman3/config/etc/postfix/post-install @@ -0,0 +1,869 @@ +#!/bin/sh + +# To view the formatted manual page of this file, type: +# POSTFIXSOURCE/mantools/srctoman - post-install | nroff -man + +#++ +# NAME +# post-install +# SUMMARY +# Postfix post-installation script +# SYNOPSIS +# postfix post-install [name=value] command ... +# DESCRIPTION +# The post-install script performs the finishing touch of a Postfix +# installation, after the executable programs and configuration +# files are installed. Usage is one of the following: +# .IP o +# While installing Postfix from source code on the local machine, the +# script is run by the postfix-install script to update selected file +# or directory permissions and to update Postfix configuration files. +# .IP o +# While installing Postfix from a pre-built package, the script is run +# by the package management procedure to set all file or directory +# permissions and to update Postfix configuration files. +# .IP o +# The script can be used to change installation parameter settings such +# as mail_owner or setgid_group after Postfix is already installed. +# .IP o +# The script can be used to upgrade configuration files and to upgrade +# file/directory permissions of a secondary Postfix instance. +# .IP o +# At Postfix start-up time, the script is run from "postfix check" to +# create missing queue directories. +# .PP +# The post-install script is controlled by installation parameters. +# Specific parameters are described at the end of this document. +# All installation parameters must be specified ahead of time via +# one of the methods described below. +# +# Arguments +# .IP create-missing +# Create missing queue directories with ownerships and permissions +# according to the contents of $daemon_directory/postfix-files +# and optionally in $daemon_directory/postfix-files.d/*, using +# the mail_owner and setgid_group parameter settings from the +# command line, process environment or from the installed +# main.cf file. +# +# This is required at Postfix start-up time. +# .IP set-permissions +# Set all file/directory ownerships and permissions according to the +# contents of $daemon_directory/postfix-files and optionally +# in $daemon_directory/postfix-files.d/*, using the mail_owner +# and setgid_group parameter settings from the command line, +# process environment or from the installed main.cf file. +# Implies create-missing. +# +# This is required when installing Postfix from a pre-built package, +# or when changing the mail_owner or setgid_group installation parameter +# settings after Postfix is already installed. +# .IP upgrade-permissions +# Update ownership and permission of existing files/directories as +# specified in $daemon_directory/postfix-files and optionally +# in $daemon_directory/postfix-files.d/*, using the mail_owner +# and setgid_group parameter settings from the command line, +# process environment or from the installed main.cf file. +# Implies create-missing. +# +# This is required when upgrading an existing Postfix instance. +# .IP upgrade-configuration +# Edit the installed main.cf and master.cf files, in order to account +# for missing services and to fix deprecated parameter settings. +# +# This is required when upgrading an existing Postfix instance. +# .IP upgrade-source +# Short-hand for: upgrade-permissions upgrade-configuration. +# +# This is recommended when upgrading Postfix from source code. +# .IP upgrade-package +# Short-hand for: set-permissions upgrade-configuration. +# +# This is recommended when upgrading Postfix from a pre-built package. +# .IP first-install-reminder +# Remind the user that they still need to configure main.cf and the +# aliases file, and that newaliases still needs to be run. +# +# This is recommended when Postfix is installed for the first time. +# MULTIPLE POSTFIX INSTANCES +# .ad +# .fi +# Multiple Postfix instances on the same machine can share command and +# daemon program files but must have separate configuration and queue +# directories. +# +# To create a secondary Postfix installation on the same machine, +# copy the configuration files from the primary Postfix instance to +# a secondary configuration directory and execute: +# +# postfix post-install config_directory=secondary-config-directory \e +# .in +4 +# queue_directory=secondary-queue-directory \e +# .br +# create-missing +# .PP +# This creates secondary Postfix queue directories, sets their access +# permissions, and saves the specified installation parameters to the +# secondary main.cf file. +# +# Be sure to list the secondary configuration directory in the +# alternate_config_directories parameter in the primary main.cf file. +# +# To upgrade a secondary Postfix installation on the same machine, +# execute: +# +# postfix post-install config_directory=secondary-config-directory \e +# .in +4 +# upgrade-permissions upgrade-configuration +# INSTALLATION PARAMETER INPUT METHODS +# .ad +# .fi +# Parameter settings can be specified through a variety of +# mechanisms. In order of decreasing precedence these are: +# .IP "command line" +# Parameter settings can be given as name=value arguments on +# the post-install command line. These have the highest precedence. +# Settings that override the installed main.cf file are saved. +# .IP "process environment" +# Parameter settings can be given as name=value environment +# variables. +# Settings that override the installed main.cf file are saved. +# .IP "installed configuration files" +# If a parameter is not specified via the command line or via the +# process environment, post-install will attempt to extract its +# value from the already installed Postfix main.cf configuration file. +# These settings have the lowest precedence. +# INSTALLATION PARAMETER DESCRIPTION +# .ad +# .fi +# The description of installation parameters is as follows: +# .IP config_directory +# The directory for Postfix configuration files. +# .IP daemon_directory +# The directory for Postfix daemon programs. This directory +# should not be in the command search path of any users. +# .IP command_directory +# The directory for Postfix administrative commands. This +# directory should be in the command search path of adminstrative users. +# .IP queue_directory +# The directory for Postfix queues. +# .IP data_directory +# The directory for Postfix writable data files (caches, etc.). +# .IP sendmail_path +# The full pathname for the Postfix sendmail command. +# This is the Sendmail-compatible mail posting interface. +# .IP newaliases_path +# The full pathname for the Postfix newaliases command. +# This is the Sendmail-compatible command to build alias databases +# for the Postfix local delivery agent. +# .IP mailq_path +# The full pathname for the Postfix mailq command. +# This is the Sendmail-compatible command to list the mail queue. +# .IP mail_owner +# The owner of the Postfix queue. Its numerical user ID and group ID +# must not be used by any other accounts on the system. +# .IP setgid_group +# The group for mail submission and for queue management commands. +# Its numerical group ID must not be used by any other accounts on the +# system, not even by the mail_owner account. +# .IP html_directory +# The directory for the Postfix HTML files. +# .IP manpage_directory +# The directory for the Postfix on-line manual pages. +# .IP sample_directory +# The directory for the Postfix sample configuration files. +# This feature is obsolete as of Postfix 2.1. +# .IP readme_directory +# The directory for the Postfix README files. +# SEE ALSO +# postfix-install(1) Postfix primary installation script. +# FILES +# $config_directory/main.cf, Postfix installation parameters. +# $daemon_directory/postfix-files, installation control file. +# $daemon_directory/postfix-files.d/*, optional control files. +# $config_directory/install.cf, obsolete configuration file. +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# AUTHOR(S) +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +#-- + +umask 022 + +PATH=/bin:/usr/bin:/usr/sbin:/usr/etc:/sbin:/etc:/usr/contrib/bin:/usr/gnu/bin:/usr/ucb:/usr/bsd +SHELL=/bin/sh +IFS=" +" +BACKUP_IFS="$IFS" +debug=: +#debug=echo +MOST_PARAMETERS="command_directory daemon_directory data_directory + html_directory mail_owner mailq_path manpage_directory + newaliases_path queue_directory readme_directory sample_directory + sendmail_path setgid_group" +NON_SHARED="config_directory queue_directory data_directory" + +USAGE="Usage: $0 [name=value] command + create-missing Create missing queue directories. + upgrade-source When installing or upgrading from source code. + upgrade-package When installing or upgrading from pre-built package. + first-install-reminder Remind of mandatory first-time configuration steps. + name=value Specify an installation parameter". + +# Process command-line options and parameter settings. Work around +# brain damaged shells. "IFS=value command" should not make the +# IFS=value setting permanent. But some broken standard allows it. + +create=; set_perms=; upgrade_perms=; upgrade_conf=; first_install_reminder= +obsolete=; keep_list=; + +for arg +do + case $arg in + *=*) IFS= eval $arg; IFS="$BACKUP_IFS";; + create-missing) create=1;; + set-perm*) create=1; set_perms=1;; + upgrade-perm*) create=1; upgrade_perms=1;; + upgrade-conf*) upgrade_conf=1;; + upgrade-source) create=1; upgrade_conf=1; upgrade_perms=1;; + upgrade-package) create=1; upgrade_conf=1; set_perms=1;; + first-install*) first_install_reminder=1;; + *) echo "$0: Error: $USAGE" 1>&2; exit 1;; + esac + shift +done + +# Sanity checks. + +test -n "$create$upgrade_conf$first_install_reminder" || { + echo "$0: Error: $USAGE" 1>&2 + exit 1 +} + +# Bootstrapping problem. + +if [ -n "$command_directory" ] +then + POSTCONF="$command_directory/postconf" +else + POSTCONF="postconf" +fi + +$POSTCONF -d mail_version >/dev/null 2>/dev/null || { + echo $0: Error: no $POSTCONF command found. 1>&2 + echo Re-run this command as $0 command_directory=/some/where. 1>&2 + exit 1 +} + +# Also used to require license etc. files only in the default instance. + +def_config_directory=`$POSTCONF -d -h config_directory` || exit 1 +test -n "$config_directory" || + config_directory="$def_config_directory" + +test -d "$config_directory" || { + echo $0: Error: $config_directory is not a directory. 1>&2 + exit 1 +} + +# If this is a secondary instance, don't touch shared files. +# XXX Solaris does not have "test -e". + +instances=`test ! -f $def_config_directory/main.cf || + $POSTCONF -c $def_config_directory -h multi_instance_directories | + sed 's/,/ /'` || exit 1 + +update_shared_files=1 +for name in $instances +do + case "$name" in + "$def_config_directory") ;; + "$config_directory") update_shared_files=; break;; + esac +done + +test -f $daemon_directory/postfix-files || { + echo $0: Error: $daemon_directory/postfix-files is not a file. 1>&2 + exit 1 +} + +# SunOS5 fmt(1) truncates lines > 1000 characters. + +fake_fmt() { + sed ' + :top + /^\( *\)\([^ ][^ ]*\) */{ + s//\1\2\ +\1/ + P + D + b top + } + ' | fmt +} + +case `uname -s` in +HP-UX*) FMT=cat;; +SunOS*) FMT=fake_fmt;; + *) FMT=fmt;; +esac + +# If a parameter is not set via the command line or environment, +# try to use settings from installed configuration files. + +# Extract parameter settings from the obsolete install.cf file, as +# a transitional aid. + +grep setgid_group $config_directory/main.cf >/dev/null 2>&1 || { + test -f $config_directory/install.cf && { + for name in sendmail_path newaliases_path mailq_path setgid manpages + do + eval junk=\$$name + case "$junk" in + "") eval unset $name;; + esac + eval : \${$name="\`. $config_directory/install.cf; echo \$$name\`"} \ + || exit 1 + done + : ${setgid_group=$setgid} + : ${manpage_directory=$manpages} + } +} + +# Extract parameter settings from the installed main.cf file. + +test -f $config_directory/main.cf && { + for name in $MOST_PARAMETERS + do + eval junk=\$$name + case "$junk" in + "") eval unset $name;; + esac + eval : \${$name=\`$POSTCONF -c $config_directory -h $name\`} || exit 1 + done +} + +# Sanity checks + +case $manpage_directory in + no) echo $0: Error: manpage_directory no longer accepts \"no\" values. 1>&2 + echo Try again with \"$0 manpage_directory=/pathname ...\". 1>&2; exit 1;; +esac + +case $setgid_group in + no) echo $0: Error: setgid_group no longer accepts \"no\" values. 1>&2 + echo Try again with \"$0 setgid_group=groupname ...\" 1>&2; exit 1;; +esac + +for path in "$daemon_directory" "$command_directory" "$queue_directory" \ + "$sendmail_path" "$newaliases_path" "$mailq_path" "$manpage_directory" +do + case "$path" in + /*) ;; + *) echo $0: Error: \"$path\" should be an absolute path name. 1>&2; exit 1;; + esac +done + +for path in "$html_directory" "$readme_directory" +do + case "$path" in + /*) ;; + no) ;; + *) echo $0: Error: \"$path\" should be \"no\" or an absolute path name. 1>&2; exit 1;; + esac +done + +# Find out what parameters were not specified via command line, +# via environment, or via installed configuration files. + +missing= +for name in $MOST_PARAMETERS +do + eval test -n \"\$$name\" || missing="$missing $name" +done + +# All parameters must be specified at this point. + +test -n "$non_interactive" -a -n "$missing" && { + cat <&2 +$0: Error: some required installation parameters are not defined. + +- Either the parameters need to be given in the $config_directory/main.cf +file from a recent Postfix installation, + +- Or the parameters need to be specified through the process +environment. + +- Or the parameters need to be specified as name=value arguments +on the $0 command line, + +The following parameters were missing: + + $missing + +EOF + exit 1 +} + +POSTCONF="$command_directory/postconf" + +# Save settings, allowing command line/environment override. + +override= +for name in $MOST_PARAMETERS +do + eval test \"\$$name\" = \"`$POSTCONF -c $config_directory -h $name`\" || { + override=1 + break + } +done + +test -n "$override" && { + $POSTCONF -c $config_directory -e \ + "daemon_directory = $daemon_directory" \ + "command_directory = $command_directory" \ + "queue_directory = $queue_directory" \ + "data_directory = $data_directory" \ + "mail_owner = $mail_owner" \ + "setgid_group = $setgid_group" \ + "sendmail_path = $sendmail_path" \ + "mailq_path = $mailq_path" \ + "newaliases_path = $newaliases_path" \ + "html_directory = $html_directory" \ + "manpage_directory = $manpage_directory" \ + "sample_directory = $sample_directory" \ + "readme_directory = $readme_directory" \ + || exit 1 +} + +# Use file/directory status information in $daemon_directory/postfix-files. + +test -n "$create" && { + postfix_files_d=$daemon_directory/postfix-files.d + for postfix_file in $daemon_directory/postfix-files \ + `test -d $postfix_files_d && { find $postfix_files_d -type f | sort; }` + do + exec <$postfix_file || exit 1 + while IFS=: read path type owner group mode flags junk + do + IFS="$BACKUP_IFS" + set_permission= + # Skip comments. Skip shared files, if updating a secondary instance. + case $path in + [$]*) case "$update_shared_files" in + 1) $debug keep non-shared or shared $path;; + *) non_shared= + for name in $NON_SHARED + do + case $path in + "\$$name"*) non_shared=1; break;; + esac + done + case "$non_shared" in + 1) $debug keep non-shared $path;; + *) $debug skip shared $path; continue;; + esac;; + esac;; + *) continue;; + esac + # Skip hard links and symbolic links. + case $type in + [hl]) continue;; + [df]) ;; + *) echo unknown type $type for $path in $postfix_file 1>&2; exit 1;; + esac + # Expand $name, and canonicalize null fields. + for name in path owner group flags + do + eval junk=\${$name} + case $junk in + [$]*) eval $name=$junk;; + -) eval $name=;; + *) ;; + esac + done + # Skip uninstalled files. + case $path in + no|no/*) continue;; + esac + # Pick up the flags. + case $flags in *u*) upgrade_flag=1;; *) upgrade_flag=;; esac + case $flags in *c*) create_flag=1;; *) create_flag=;; esac + case $flags in *r*) recursive="-R";; *) recursive=;; esac + case $flags in *o*) obsolete_flag=1;; *) obsolete_flag=;; esac + case $flags in *[1i]*) test ! -r "$path" -a "$config_directory" != \ + "$def_config_directory" && continue;; esac + # Flag obsolete objects. XXX Solaris 2..9 does not have "test -e". + if [ -n "$obsolete_flag" ] + then + test -r $path -a "$type" != "d" && obsolete="$obsolete $path" + continue; + else + keep_list="$keep_list $path" + fi + # Create missing directories with proper owner/group/mode settings. + if [ -n "$create" -a "$type" = "d" -a -n "$create_flag" -a ! -d "$path" ] + then + mkdir $path || exit 1 + set_permission=1 + # Update all owner/group/mode settings. + elif [ -n "$set_perms" ] + then + set_permission=1 + # Update obsolete owner/group/mode settings. + elif [ -n "$upgrade_perms" -a -n "$upgrade_flag" ] + then + set_permission=1 + fi + test -n "$set_permission" && { + chown $recursive $owner $path || exit 1 + test -z "$group" || chgrp $recursive $group $path || exit 1 + # Don't "chmod -R"; queue file status is encoded in mode bits. + if [ "$type" = "d" -a -n "$recursive" ] + then + find $path -type d -exec chmod $mode "{}" ";" + else + chmod $mode $path + fi || exit 1 + } + done + IFS="$BACKUP_IFS" + done +} + +# Upgrade existing Postfix configuration files if necessary. + +test -n "$upgrade_conf" && { + + # Postfix 2.0. + # Add missing relay service to master.cf. + + grep '^relay' $config_directory/master.cf >/dev/null || { + echo Editing $config_directory/master.cf, adding missing entry for relay service + cat >>$config_directory/master.cf </dev/null || { + echo Editing $config_directory/master.cf, adding missing entry for flush service + cat >>$config_directory/master.cf </dev/null || { + echo Editing $config_directory/master.cf, adding missing entry for trace service + cat >>$config_directory/master.cf </dev/null || { + echo Editing $config_directory/master.cf, adding missing entry for verify service + cat >>$config_directory/master.cf </dev/null && { + echo Editing $config_directory/master.cf, setting verify process limit to 1 + ed $config_directory/master.cf </dev/null && { + echo Editing $config_directory/master.cf, making the pickup service unprivileged + ed $config_directory/master.cf </dev/null && { + echo Editing $config_directory/master.cf, making the $name service public + ed $config_directory/master.cf </dev/null) || missing="$missing defer" + (echo "$found" | grep deferred>/dev/null)|| missing="$missing deferred" + test -n "$missing" && { + echo fixing main.cf hash_queue_names for missing $missing + $POSTCONF -c $config_directory -e hash_queue_names="$found$missing" || + exit 1 + } + + # Turn on safety nets for new features that could bounce mail that + # would be accepted by a previous Postfix version. + + # [The "unknown_local_recipient_reject_code = 450" safety net, + # introduced with Postfix 2.0 and deleted after Postfix 2.3.] + + # Postfix 2.0. + # Add missing proxymap service to master.cf. + + grep '^proxymap.*proxymap' $config_directory/master.cf >/dev/null || { + echo Editing $config_directory/master.cf, adding missing entry for proxymap service + cat >>$config_directory/master.cf </dev/null || { + echo Editing $config_directory/master.cf, adding missing entry for anvil service + cat >>$config_directory/master.cf </dev/null || { + echo Editing $config_directory/master.cf, adding missing entry for scache service + cat >>$config_directory/master.cf </dev/null || { + echo Editing $config_directory/master.cf, adding missing entry for discard service + cat >>$config_directory/master.cf <unix service. + + grep "^tlsmgr[ ]*fifo[ ]" \ + $config_directory/master.cf >/dev/null && { + echo Editing $config_directory/master.cf, updating the tlsmgr from fifo to unix service + ed $config_directory/master.cf </dev/null || { + echo Editing $config_directory/master.cf, adding missing entry for tlsmgr service + cat >>$config_directory/master.cf </dev/null || { + echo Editing $config_directory/master.cf, adding missing entry for retry service + cat >>$config_directory/master.cf </dev/null || { + echo Editing $config_directory/master.cf, adding missing entry for proxywrite service + cat >>$config_directory/master.cf </dev/null && { + echo Editing $config_directory/master.cf, setting proxywrite process limit to 1 + ed $config_directory/master.cf </dev/null || { + echo Editing $config_directory/master.cf, adding missing entry for postscreen TCP service + cat >>$config_directory/master.cf </dev/null || { + echo Editing $config_directory/master.cf, adding missing entry for smtpd unix-domain service + cat >>$config_directory/master.cf </dev/null || { + echo Editing $config_directory/master.cf, adding missing entry for dnsblog unix-domain service + cat >>$config_directory/master.cf </dev/null || { + echo Editing $config_directory/master.cf, adding missing entry for tlsproxy unix-domain service + cat >>$config_directory/master.cf <&2 + echo Do not run directly. 1>&2 + exit 1 +esac + +LOGGER="$command_directory/postlog -t $MAIL_LOGTAG/postfix-script" +INFO="$LOGGER -p info" +WARN="$LOGGER -p warn" +ERROR="$LOGGER -p error" +FATAL="$LOGGER -p fatal" +PANIC="$LOGGER -p panic" + +if [ "X${1#quiet-}" != "X${1}" ]; then + INFO=: + x=${1#quiet-} + shift + set -- $x "$@" +fi + +umask 022 +SHELL=/bin/sh + +# +# Can't do much without these in place. +# +cd $command_directory || { + $FATAL no Postfix command directory $command_directory! + exit 1 +} +cd $daemon_directory || { + $FATAL no Postfix daemon directory $daemon_directory! + exit 1 +} +test -f master || { + $FATAL no Postfix master program $daemon_directory/master! + exit 1 +} +cd $config_directory || { + $FATAL no Postfix configuration directory $config_directory! + exit 1 +} +cd $queue_directory || { + $FATAL no Postfix queue directory $queue_directory! + exit 1 +} +def_config_directory=`$command_directory/postconf -dh config_directory` || { + $FATAL cannot execute $command_directory/postconf! + exit 1 +} + +# If this is a secondary instance, don't touch shared files. + +instances=`test ! -f $def_config_directory/main.cf || + $command_directory/postconf -c $def_config_directory \ + -h multi_instance_directories | sed 's/,/ /'` || { + $FATAL cannot execute $command_directory/postconf! + exit 1 +} + +check_shared_files=1 +for name in $instances +do + case "$name" in + "$def_config_directory") ;; + "$config_directory") check_shared_files=; break;; + esac +done + +# +# Parse JCL +# +case $1 in + +start_msg) + + echo "Start postfix" + ;; + +stop_msg) + + echo "Stop postfix" + ;; + +quick-start) + + $daemon_directory/master -t 2>/dev/null || { + $FATAL the Postfix mail system is already running + exit 1 + } + $daemon_directory/postfix-script quick-check || { + $FATAL Postfix integrity check failed! + exit 1 + } + $INFO starting the Postfix mail system + $daemon_directory/master & + ;; + +start) + + $daemon_directory/master -t 2>/dev/null || { + $FATAL the Postfix mail system is already running + exit 1 + } + if [ -f $queue_directory/quick-start ] + then + rm -f $queue_directory/quick-start + else + $daemon_directory/postfix-script check-fatal || { + $FATAL Postfix integrity check failed! + exit 1 + } + # Foreground this so it can be stopped. All inodes are cached. + $daemon_directory/postfix-script check-warn + fi + $INFO starting the Postfix mail system + # NOTE: wait in foreground process to get the initialization status. + $daemon_directory/master -w || { + $FATAL "mail system startup failed" + exit 1 + } + ;; + +drain) + + $daemon_directory/master -t 2>/dev/null && { + $FATAL the Postfix mail system is not running + exit 1 + } + $INFO stopping the Postfix mail system + kill -9 `sed 1q pid/master.pid` + ;; + +quick-stop) + + $daemon_directory/postfix-script stop + touch $queue_directory/quick-start + ;; + +stop) + + $daemon_directory/master -t 2>/dev/null && { + $FATAL the Postfix mail system is not running + exit 0 + } + $INFO stopping the Postfix mail system + kill `sed 1q pid/master.pid` + for i in 5 4 3 2 1 + do + $daemon_directory/master -t && exit 0 + $INFO waiting for the Postfix mail system to terminate + sleep 1 + done + $WARN stopping the Postfix mail system with force + pid=`awk '{ print $1; exit 0 } END { exit 1 }' pid/master.pid` && + kill -9 -$pid + ;; + +abort) + + $daemon_directory/master -t 2>/dev/null && { + $FATAL the Postfix mail system is not running + exit 0 + } + $INFO aborting the Postfix mail system + kill `sed 1q pid/master.pid` + ;; + +reload) + + $daemon_directory/master -t 2>/dev/null && { + $FATAL the Postfix mail system is not running + exit 1 + } + $INFO refreshing the Postfix mail system + $command_directory/postsuper active || exit 1 + kill -HUP `sed 1q pid/master.pid` + $command_directory/postsuper & + ;; + +flush) + + cd $queue_directory || { + $FATAL no Postfix queue directory $queue_directory! + exit 1 + } + $command_directory/postqueue -f + ;; + +check) + + $daemon_directory/postfix-script check-fatal || exit 1 + $daemon_directory/postfix-script check-warn + exit 0 + ;; + +status) + + $daemon_directory/master -t 2>/dev/null && { + $INFO the Postfix mail system is not running + exit 1 + } + $INFO the Postfix mail system is running: PID: `sed 1q pid/master.pid` + exit 0 + ;; + +quick-check) + # This command is NOT part of the public interface. + + $SHELL $daemon_directory/post-install create-missing || { + $WARN unable to create missing queue directories + exit 1 + } + + # Look for incomplete installations. + + test -f $config_directory/master.cf || { + $FATAL no $config_directory/master.cf file found + exit 1 + } + exit 0 + ;; + +check-fatal) + # This command is NOT part of the public interface. + + $daemon_directory/postfix-script quick-check + + # See if all queue files are in the right place. This is slow. + # We must scan all queues for mis-named queue files before the + # mail system can run. + + $command_directory/postsuper || exit 1 + exit 0 + ;; + +check-warn) + # This command is NOT part of the public interface. + + todo="$config_directory $queue_directory $queue_directory/pid" + test -n "$check_shared_files" && todo="$daemon_directory $todo" + + for dir in $todo + do + ls -lLd $dir | (grep " root " >/dev/null || + $WARN not owned by root: $dir) + done + + # Some people break Postfix's security model. + ls -lLd $queue_directory | egrep '^.....(w|...w)' >/dev/null && \ + $WARN group or other writable: $queue_directory + + todo="$config_directory/*" + test -n "$check_shared_files" && todo="$daemon_directory/* $todo" + + find $todo ! -user root \ + -exec $WARN not owned by root: {} \; + + todo="$config_directory/." + test -n "$check_shared_files" && todo="$daemon_directory/. $todo" + + find $todo \ + \( -perm -020 -o -perm -002 \) -type f \ + -exec $WARN group or other writable: {} \; + + find $data_directory/. ! -user $mail_owner \ + -exec $WARN not owned by $mail_owner: {} \; + + ls -lLd $data_directory | egrep '^.....(w|...w)' >/dev/null && \ + $WARN group or other writable: $data_directory + + find `ls -d $queue_directory/* | \ + egrep '/(saved|incoming|active|defer|deferred|bounce|hold|trace|corrupt|public|private|flush)$'` \ + ! \( -type p -o -type s \) ! -user $mail_owner \ + -exec $WARN not owned by $mail_owner: {} \; + + todo="$queue_directory/public $queue_directory/maildrop" + test -n "$check_shared_files" && + todo="$command_directory/postqueue $command_directory/postdrop $todo" + + find $todo \ + -prune ! -group $setgid_group \ + -exec $WARN not owned by group $setgid_group: {} \; + + test -n "$check_shared_files" && + find $command_directory/postqueue $command_directory/postdrop \ + -prune ! -perm -02111 \ + -exec $WARN not set-gid or not owner+group+world executable: {} \; + + for name in `ls -d $queue_directory/* | \ + egrep '/(bin|etc|lib|usr)$'` ; \ + do \ + find $name ! -user root \ + -exec $WARN not owned by root: {} \; ; \ + done + + # WARNING: this should not descend into the maildrop directory. + # maildrop is the least trusted Postfix directory. + + find $queue_directory/maildrop/. -prune ! -user $mail_owner \ + -exec $WARN not owned by $mail_owner: $queue_directory/maildrop \; + + for dir in bin etc lib sbin usr + do + test -d $dir && find $dir -type f -print | while read path + do + test -f /$path && { + cmp -s $path /$path || + $WARN $queue_directory/$path and /$path differ + } + done + done + + find corrupt -type f -exec $WARN damaged message: {} \; + + # XXX also: look for weird stuff, weird permissions, etc. + + test -n "$check_shared_files" -a -f /usr/sbin/sendmail -a \ + -f /usr/lib/sendmail && { + cmp -s /usr/sbin/sendmail /usr/lib/sendmail || { + $WARN /usr/lib/sendmail and /usr/sbin/sendmail differ + $WARN Replace one by a symbolic link to the other + } + } + exit 0 + ;; + +set-permissions|upgrade-configuration) + $daemon_directory/post-install create-missing "$@" + ;; + +post-install) + # Currently not part of the public interface. + shift + $daemon_directory/post-install "$@" + ;; + +/*) + # Currently not part of the public interface. + "$@" + ;; + +*) + $ERROR "unknown command: '$1'" + $FATAL "usage: postfix start (or stop, reload, abort, flush, check, status, set-permissions, upgrade-configuration)" + exit 1 + ;; + +esac diff --git a/mailman3/config/etc/postfix/sasl/smtpd.conf b/mailman3/config/etc/postfix/sasl/smtpd.conf new file mode 100644 index 0000000..b445546 --- /dev/null +++ b/mailman3/config/etc/postfix/sasl/smtpd.conf @@ -0,0 +1,2 @@ +mech_list: plain login cram-md5 digest-md5 +pwcheck_method: saslauthd diff --git a/mailman3/config/etc/postfix/vhosts b/mailman3/config/etc/postfix/vhosts new file mode 100644 index 0000000..3aa2ad4 --- /dev/null +++ b/mailman3/config/etc/postfix/vhosts @@ -0,0 +1 @@ +mechanysm.com diff --git a/mailman3/config/etc/postfix/vmaps b/mailman3/config/etc/postfix/vmaps new file mode 100644 index 0000000..4e80417 --- /dev/null +++ b/mailman3/config/etc/postfix/vmaps @@ -0,0 +1 @@ +postmaster@mechanysm.com mechanysm.com/postmaster/ diff --git a/mailman3/config/mailman3/mailman-bundler/buildout.cfg b/mailman3/config/mailman3/mailman-bundler/buildout.cfg new file mode 100644 index 0000000..886e507 --- /dev/null +++ b/mailman3/config/mailman3/mailman-bundler/buildout.cfg @@ -0,0 +1,88 @@ +# +# Buildout configuration for Mailman + Postorius + HyperKitty +# + +[configuration] +# Choose 'testing' or 'production' +deployment = production + + + +# You shouldn't need to edit anything below +[buildout] +parts = + main + mailman + templates +develop = . +versions = versions + + +[versions] +mailman = 3.0.3 +mailman-hyperkitty = 1.0.0 +postorius = 1.0.3 +hyperkitty = 1.0.3 + + +[main] +recipe = zc.recipe.egg +eggs = + mailman-bundler + ${mailman-web:eggs} +dependent-scripts = true +interpreter = python +initialization = + import os + os.environ['MAILMAN_CONFIG_FILE'] = '${buildout:directory}/deployment/mailman.cfg' + os.environ['DJANGO_SETTINGS_MODULE'] = '${mailman-web:project}.${mailman-web:settings}' + + +[mailman] +recipe = collective.recipe.cmd +python3-version = 3.4 +on_install = true +venv-dir = ${buildout:directory}/venv-${mailman:python3-version} +cmds = + virtualenv -p python${mailman:python3-version} ${mailman:venv-dir} + ${mailman:venv-dir}/bin/pip install mailman==${versions:mailman} mailman-hyperkitty==${versions:mailman-hyperkitty} +uninstall_cmds = + rm -rf ${mailman:venv-dir} + + +[mailman-web] +recipe = djangorecipe +project = mailman_web +eggs = + Django < 1.9 + postorius + hyperkitty + Whoosh + mock + beautifulsoup4 +control-script = mailman-web-django-admin +wsgi = true +wsgi-script = mailman-web.wsgi +settings = ${configuration:deployment} +test = + postorius + hyperkitty + + +[templates] +recipe = z3c.recipe.filetemplate +source-directory = templates +interpreted-options = + venv-directory = sys.prefix + venv-sitelib-directory = __import__('distutils').sysconfig.get_python_lib() + + +[gunicorn] +recipe = zc.recipe.egg +eggs = + gunicorn + ${mailman-web:eggs} +dependent-scripts = true +initialization = + import os + os.environ['DJANGO_SETTINGS_MODULE'] = '${mailman-web:project}.${mailman-web:settings}' diff --git a/mailman3/config/mailman3/mailman-bundler/mailman_web/production.py b/mailman3/config/mailman3/mailman-bundler/mailman_web/production.py new file mode 100644 index 0000000..f0fcdd3 --- /dev/null +++ b/mailman3/config/mailman3/mailman-bundler/mailman_web/production.py @@ -0,0 +1,402 @@ +#-*- coding: utf-8 -*- +""" +Django settings for HyperKitty + Postorius +""" + +import os +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +VAR_DIR = "/var/spool" + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'change-that-at-install-time' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = False + +TEMPLATE_DEBUG = DEBUG + +ADMINS = ( + ('Mailman Admin', 'root@localhost'), +) + +# Hosts/domain names that are valid for this site; required if DEBUG is False +# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts +ALLOWED_HOSTS = ["localhost", "mechanysm.com", "*"] +# And for BrowserID too, see +# http://django-browserid.rtfd.org/page/user/settings.html#django.conf.settings.BROWSERID_AUDIENCES +BROWSERID_AUDIENCES = [ "http://localhost", "http://localhost:8000", "http://mechanysm.com:18000", "http://mechanysm.com:8000" ] + +# Mailman API credentials +MAILMAN_REST_API_URL = 'http://mailman.local:8001' +MAILMAN_REST_API_USER = 'apollo' +MAILMAN_REST_API_PASS = 'FPbM!!yfU!GaQpPSkYl3' +MAILMAN_ARCHIVER_KEY = 'SecretArchiverAPIKey' +MAILMAN_ARCHIVER_FROM = ('127.0.0.1', '::1', '::ffff:127.0.0.1') + +# Application definition + +INSTALLED_APPS = ( + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + #'django.contrib.sites', + 'django.contrib.messages', + 'django.contrib.staticfiles', + # Uncomment the next line to enable the admin: + 'django.contrib.admin', + # Uncomment the next line to enable admin documentation: + # 'django.contrib.admindocs', + 'hyperkitty', + 'social.apps.django_app.default', + 'rest_framework', + 'django_gravatar', + 'crispy_forms', + 'paintstore', + 'compressor', + 'django_browserid', + 'haystack', + 'django_extensions', + 'postorius', +) + + +MIDDLEWARE_CLASSES = ( + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + # Uncomment the next line for simple clickjacking protection: + # 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'hyperkitty.middleware.SSLRedirect', + 'hyperkitty.middleware.TimezoneMiddleware', +) + +ROOT_URLCONF = 'mailman_web.urls' + + +# +# Postorius +# + +# CSS theme for postorius +MAILMAN_THEME = "default" + +## Email confirmation / address activation +# Add a from-address for email-confirmation: +# EMAIL_CONFIRMATION_FROM = 'postmaster@example.org' + +# These can be set to override the defaults but are not mandatory: +# EMAIL_CONFIRMATION_TEMPLATE = 'postorius/address_confirmation_message.txt' +# EMAIL_CONFIRMATION_SUBJECT = 'Confirmation needed' + + + +# Database +# https://docs.djangoproject.com/en/1.6/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql_psycopg2', # Last part is one of 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'. + 'NAME': 'mailmanweb', # Example, change as needed + 'USER': 'mailmanweb', # Example, change as needed + 'PASSWORD': 'change-this-password', # Example, obviously + 'HOST': '127.0.0.1', # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP. + 'PORT': '', # Set to empty string for default. + } +} + + +# If you're behind a proxy, use the X-Forwarded-Host header +# See https://docs.djangoproject.com/en/1.5/ref/settings/#use-x-forwarded-host +#USE_X_FORWARDED_HOST = True +# And if your proxy does your SSL encoding for you, set SECURE_PROXY_SSL_HEADER +# see https://docs.djangoproject.com/en/1.5/ref/settings/#secure-proxy-ssl-header +#SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') + +# Internationalization +# https://docs.djangoproject.com/en/1.6/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'America/Chicago' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.6/howto/static-files/ + +# Absolute filesystem path to the directory that will hold user-uploaded files. +# Example: "/var/www/example.com/media/" +MEDIA_ROOT = '' + +# URL that handles the media served from MEDIA_ROOT. Make sure to use a +# trailing slash. +# Examples: "http://example.com/media/", "http://media.example.com/" +MEDIA_URL = '' + +# Absolute path to the directory static files should be collected to. +# Don't put anything in this directory yourself; store your static files +# in apps' "static/" subdirectories and in STATICFILES_DIRS. +# Example: "/var/www/example.com/static/" +#STATIC_ROOT = '' +STATIC_ROOT = os.path.join(VAR_DIR, "mailman-web", "static") + +# URL prefix for static files. +# Example: "http://example.com/static/", "http://static.example.com/" +STATIC_URL = '/static/' + +# Additional locations of static files +STATICFILES_DIRS = ( + # Put strings here, like "/home/html/static" or "C:/www/django/static". + # Always use forward slashes, even on Windows. + # Don't forget to use absolute paths, not relative paths. +) + +# List of finder classes that know how to find static files in +# various locations. +STATICFILES_FINDERS = ( + 'django.contrib.staticfiles.finders.FileSystemFinder', + 'django.contrib.staticfiles.finders.AppDirectoriesFinder', +# 'django.contrib.staticfiles.finders.DefaultStorageFinder', + 'compressor.finders.CompressorFinder', +) + + +TEMPLATE_CONTEXT_PROCESSORS = ( + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + "django.core.context_processors.debug", + "django.core.context_processors.i18n", + "django.core.context_processors.media", + "django.core.context_processors.static", + "django.core.context_processors.csrf", + "django.core.context_processors.request", + "django.core.context_processors.tz", + "django.contrib.messages.context_processors.messages", + "social.apps.django_app.context_processors.backends", + "social.apps.django_app.context_processors.login_redirect", + "hyperkitty.context_processors.export_settings", + "hyperkitty.context_processors.postorius_info", + "postorius.context_processors.postorius", +) + +TEMPLATE_DIRS = ( + # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". + # Always use forward slashes, even on Windows. + # Don't forget to use absolute paths, not relative paths. +) + +# Django 1.6+ defaults to a JSON serializer, but it won't work with django-openid, see +# https://bugs.launchpad.net/django-openid-auth/+bug/1252826 +SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer' + + +LOGIN_URL = 'hk_user_login' +LOGOUT_URL = 'hk_user_logout' +LOGIN_REDIRECT_URL = 'hk_root' + +# Use the email username as identifier, but truncate it because +# the User.username field is only 30 chars long. +def username(email): + return email.rsplit('@', 1)[0][:30] +BROWSERID_USERNAME_ALGO = username +BROWSERID_VERIFY_CLASS = "django_browserid.views.Verify" + + + +# +# Social auth +# + +AUTHENTICATION_BACKENDS = ( + #'social.backends.open_id.OpenIdAuth', + # http://python-social-auth.readthedocs.org/en/latest/backends/google.html + 'social.backends.google.GoogleOpenId', + #'social.backends.google.GoogleOAuth2', + #'social.backends.twitter.TwitterOAuth', + 'social.backends.yahoo.YahooOpenId', + 'django_browserid.auth.BrowserIDBackend', + 'django.contrib.auth.backends.ModelBackend', +) + +# http://python-social-auth.readthedocs.org/en/latest/pipeline.html#authentication-pipeline +SOCIAL_AUTH_PIPELINE = ( + 'social.pipeline.social_auth.social_details', + 'social.pipeline.social_auth.social_uid', + 'social.pipeline.social_auth.auth_allowed', + 'social.pipeline.social_auth.social_user', + 'social.pipeline.user.get_username', + # Associates the current social details with another user account with + # a similar email address. Disabled by default, enable with care: + # http://python-social-auth.readthedocs.org/en/latest/use_cases.html#associate-users-by-email + #'social.pipeline.social_auth.associate_by_email', + 'social.pipeline.user.create_user', + 'social.pipeline.social_auth.associate_user', + 'social.pipeline.social_auth.load_extra_data', + 'social.pipeline.user.user_details', + 'hyperkitty.lib.mailman.add_user_to_mailman', +) + + + +# +# Gravatar +# https://github.com/twaddington/django-gravatar +# +# Gravatar base url. +#GRAVATAR_URL = 'http://cdn.libravatar.org/' +# Gravatar base secure https url. +#GRAVATAR_SECURE_URL = 'https://seccdn.libravatar.org/' +# Gravatar size in pixels. +#GRAVATAR_DEFAULT_SIZE = '80' +# An image url or one of the following: 'mm', 'identicon', 'monsterid', 'wavatar', 'retro'. +#GRAVATAR_DEFAULT_IMAGE = 'mm' +# One of the following: 'g', 'pg', 'r', 'x'. +#GRAVATAR_DEFAULT_RATING = 'g' +# True to use https by default, False for plain http. +#GRAVATAR_DEFAULT_SECURE = True + +# +# django-compressor +# https://pypi.python.org/pypi/django_compressor +# +COMPRESS_PRECOMPILERS = ( + ('text/x-scss', 'sass {infile} {outfile}'), + ('text/x-sass', 'sass {infile} {outfile}'), +) +COMPRESS_OFFLINE = True +# needed for debug mode +#INTERNAL_IPS = ('127.0.0.1',) + +# Django Crispy Forms +CRISPY_TEMPLATE_PACK = 'bootstrap3' +CRISPY_FAIL_SILENTLY = not DEBUG + +# Compatibility with Bootstrap 3 +from django.contrib.messages import constants as messages +MESSAGE_TAGS = { + messages.ERROR: 'danger' +} + + +# +# Full-text search engine +# +HAYSTACK_CONNECTIONS = { + 'default': { + 'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine', + 'PATH': os.path.join(VAR_DIR, "mailman-web", "fulltext_index"), + }, +} + + +# A sample logging configuration. The only tangible logging +# performed by this configuration is to send an email to +# the site admins on every HTTP 500 error when DEBUG=False. +# See http://docs.djangoproject.com/en/dev/topics/logging for +# more details on how to customize your logging configuration. +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'filters': { + 'require_debug_false': { + '()': 'django.utils.log.RequireDebugFalse' + } + }, + 'handlers': { + 'mail_admins': { + 'level': 'ERROR', + 'filters': ['require_debug_false'], + 'class': 'django.utils.log.AdminEmailHandler' + }, + 'file':{ + 'level': 'INFO', + #'class': 'logging.handlers.RotatingFileHandler', + 'class': 'logging.handlers.WatchedFileHandler', + 'filename': '/var/log/mailman-web/mailman-web.log', + 'formatter': 'verbose', + }, + }, + 'loggers': { + #'django.request': { + # 'handlers': ['mail_admins'], + # 'level': 'ERROR', + # 'propagate': True, + #}, + 'django.request': { + 'handlers': ['file'], + 'level': 'INFO', + 'propagate': True, + }, + 'django': { + 'handlers': ['file'], + 'level': 'INFO', + 'propagate': True, + }, + 'hyperkitty': { + 'handlers': ['file'], + 'level': 'INFO', + 'propagate': True, + }, + 'postorius': { + 'handlers': ['file'], + 'level': 'INFO', + 'propagate': True, + }, + }, + 'formatters': { + 'verbose': { + 'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s' + }, + 'simple': { + 'format': '%(levelname)s %(message)s' + }, + }, + 'root': { + 'handlers': ['file'], + 'level': 'INFO', + }, +} + + +## Cache: use the local memcached server +#CACHES = { +# 'default': { +# 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', +# 'LOCATION': '127.0.0.1:11211', +# } +#} + + + +# +# HyperKitty-specific +# + +APP_NAME = 'Mailing-list archives' + +# Allow authentication with the internal user database? +# By default, only a login through Persona or your email provider is allowed. +USE_INTERNAL_AUTH = True + +# Use SSL when logged in. You need to enable the SSLRedirect middleware for +# this feature to work. +USE_SSL = False + +# Only display mailing-lists from the same virtual host as the webserver +FILTER_VHOST = False + +# This is for development purposes +USE_MOCKUPS = False + + +try: + from settings_local import * +except ImportError: + pass diff --git a/mailman3/config/mailman3/mailman-bundler/venv-3.4/lib/python3.4/site-packages/mailman/config/schema.cfg b/mailman3/config/mailman3/mailman-bundler/venv-3.4/lib/python3.4/site-packages/mailman/config/schema.cfg new file mode 100644 index 0000000..d138c08 --- /dev/null +++ b/mailman3/config/mailman3/mailman-bundler/venv-3.4/lib/python3.4/site-packages/mailman/config/schema.cfg @@ -0,0 +1,843 @@ +# Copyright (C) 2008-2016 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 . + +# 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 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 is the local-part of an email address used in the From field whenever a +# message comes from some entity to which there is no natural reply recipient. +# Mailman will append '@' and the host name of the list involved. This +# address must not bounce and it must not point to a Mailman process. +noreply_address: noreply + +# The default language for this server. +default_language: en + +# 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 + +# A callable to run with no arguments early in the initialization process. +# This runs before database initialization. +pre_hook: + +# A callable to run with no arguments late in the initialization process. +# This runs after adapters are initialized. +post_hook: + +# Which paths.* file system layout to use. +layout: here + +# Can MIME filtered messages be preserved by list owners? +filtered_messages_are_preservable: no + +# How should text/html parts be converted to text/plain when the mailing list +# is set to convert HTML to plaintext? This names a command to be called, +# where the substitution variable $filename is filled in by Mailman, and +# contains the path to the temporary file that the command should read from. +# The command should print the converted text to stdout. +html_to_plain_text_command: /usr/bin/lynx -dump $filename + + +[shell] +# `mailman shell` (also `withlist`) gives you an interactive prompt that you +# can use to interact with an initialized and configured Mailman system. Use +# --help for more information. This section allows you to configure certain +# aspects of this interactive shell. + +# Customize the interpreter prompt. +prompt: >>> + +# Banner to show on startup. +banner: Welcome to the GNU Mailman shell + +# Use IPython as the shell, which must be found on the system. Valid values +# are `no`, `yes`, and `debug` where the latter is equivalent to `yes` except +# that any import errors will be displayed to stderr. +use_ipython: no + +# Set this to allow for command line history if readline is available. This +# can be as simple as $var_dir/history.py to put the file in the var directory. +history_file: + + +[paths.master] +# Important directories for Mailman operation. These are defined here so that +# different layouts can be supported. For example, a developer layout would +# be different from a FHS layout. Most paths are based off the var_dir, and +# often just setting that will do the right thing for all the other paths. +# You might also have to set spool_dir though. +# +# Substitutions are allowed, but must be of the form $var where 'var' names a +# configuration variable in the paths.* section. Substitutions are expanded +# recursively until no more $-variables are present. Beware of infinite +# expansion loops! +# +# This is the root of the directory structure that Mailman will use to store +# its run-time data. +var_dir: /var/tmp/mailman +# This is where the Mailman queue files directories will be created. +queue_dir: $var_dir/queue +# This is the directory containing the Mailman 'runner' and 'master' commands +# if set to the string '$argv', it will be taken as the directory containing +# the 'mailman' command. +bin_dir: $argv +# All list-specific data. +list_data_dir: $var_dir/lists +# Directory where log files go. +log_dir: $var_dir/logs +# Directory for system-wide locks. +lock_dir: $var_dir/locks +# Directory for system-wide data. +data_dir: $var_dir/data +# Directory for configuration files and such. +etc_dir: $var_dir/etc +# Directory containing Mailman plugins. +ext_dir: $var_dir/ext +# Directory where the default IMessageStore puts its messages. +messages_dir: $var_dir/messages +# Directory for archive backends to store their messages in. Archivers should +# create a subdirectory in here to store their files. +archive_dir: $var_dir/archives +# Root directory for site-specific template override files. +template_dir: $var_dir/templates +# There are also a number of paths to specific file locations that can be +# defined. For these, the directory containing the file must already exist, +# or be one of the directories created by Mailman as per above. +# +# This is where PID file for the master runner is stored. +pid_file: $var_dir/master.pid +# Lock file. +lock_file: $lock_dir/master.lck + + +[devmode] +# Setting enabled to true enables certain safeguards and other behavior +# changes that make developing Mailman easier. For example, it forces the +# SMTP RCPT TO recipients to be a test address so that no messages are +# accidentally sent to real addresses. +enabled: no + +# Set this to an address to force the SMTP RCPT TO recipents when devmode is +# enabled. This way messages can't be accidentally sent to real addresses. +recipient: + +# This gets set by the testing layers so that the runner subprocesses produce +# predictable dates and times. +testing: no + +# Time-outs for starting up various test subprocesses, such as the LMTP and +# REST servers. This is only used for the test suite, so if you're seeing +# test failures, try increasing the wait time. +wait: 60s + + +[passwords] +# Where can we find the passlib configuration file? The path can be either a +# file system path or a Python import path. If the value starts with python: +# then it is a Python import path, otherwise it is a file system path. File +# system paths must be absolute since no guarantees are made about the current +# working directory. Python paths should not include the trailing .cfg, which +# the file must end with. +configuration: python:mailman.config.passlib + +# When Mailman generates them, this is the default length of passwords. +password_length: 8 + + +[runner.master] +# Define which runners, and how many of them, to start. + +# The full import path to the class for this runner. +class: mailman.core.runner.Runner + +# The queue directory path that this runner scans. This is ignored for +# runners that don't manage a queue directory. +path: $QUEUE_DIR/$name + +# The number of parallel runners. This must be a power of 2. This is ignored +# for runners that don't manage a queue directory. +instances: 1 + +# Whether to start this runner or not. +start: yes + +# The maximum number of restarts for this 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 runner. It wakes up once every interval to +# process the files in its slice of the queue directory. Some runners may +# ignore this. +sleep_time: 1s + +[database] +# The class implementing the IDatabase. +class: mailman.database.sqlite.SQLiteDatabase + +# 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 +# - database -- Database logging (SQLAlchemy and Alembic) +# - 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 +# - runner -- Runner process start/stops +# - smtp -- Successful SMTP activity +# - smtp-failure -- Unsuccessful SMTP activity +# - subscribe -- Information about leaves/joins +# - vette -- Message vetting information +format: %(asctime)s (%(process)d) %(message)s +datefmt: %b %d %H:%M:%S %Y +propagate: no +level: info +path: mailman.log + +[logging.root] + +[logging.archiver] + +[logging.bounce] +path: bounce.log + +[logging.config] + +[logging.database] +level: warn + +[logging.debug] +path: debug.log +level: info + +[logging.error] + +[logging.fromusenet] + +[logging.http] + +[logging.locks] + +[logging.mischief] + +[logging.runner] + +[logging.smtp] +path: smtp.log + +# 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] + + +[webservice] +# The hostname at which admin web service resources are exposed. +hostname: mailman.local + +# The port at which the admin web service resources are exposed. +port: 8001 + +# Whether or not requests to the web service are secured through SSL. +use_https: no + +# Whether or not to show tracebacks in an HTTP response for a request that +# raised an exception. +show_tracebacks: yes + +# The API version number for the current (highest) API. +api_version: 3.0 + +# The administrative username. +admin_user: apollo + +# The administrative password. +admin_pass: FPbM!!yfU!GaQpPSkYl3 + +[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 + +# Language charsets as imported from Mailman 2.1 defaults +# Ref: http://www.lingoes.net/en/translator/langcode.htm +[language.ar] +description: Arabic +charset: utf-8 +enabled: yes + +[language.ast] +description: Asturian +charset: iso-8859-1 +enabled: yes + +[language.ca] +description: Catalan +charset: utf-8 +enabled: yes + +[language.cs] +description: Czech +charset: iso-8859-2 +enabled: yes + +[language.da] +description: Danish +charset: iso-8859-1 +enabled: yes + +[language.de] +description: German +charset: iso-8859-1 +enabled: yes + +[language.el] +description: Greek +charset: iso-8859-7 +enabled: yes + +[language.es] +description: Spanish +charset: iso-8859-1 +enabled: yes + +[language.et] +description: Estonian +charset: iso-8859-15 +enabled: yes + +[language.eu] +# Basque +description: Euskara +charset: iso-8859-15 +enabled: yes + +[language.fi] +description: Finnish +charset: iso-8859-1 +enabled: yes + +[language.fr] +description: French +charset: iso-8859-1 +enabled: yes + +[language.gl] +description: Galician +charset: utf-8 +enabled: yes + +[language.he] +description: Hebrew +charset: utf-8 +enabled: yes + +[language.hr] +description: Croatian +charset: iso-8859-2 +enabled: yes + +[language.hu] +description: Hungarian +charset: iso-8859-2 +enabled: yes + +[language.ia] +description: Interlingua +charset: iso-8859-15 +enabled: yes + +[language.it] +description: Italian +charset: iso-8859-1 +enabled: yes + +[language.ja] +description: Japanese +charset: euc-jp +enabled: yes + +[language.ko] +description: Korean +charset: euc-kr +enabled: yes + +[language.lt] +description: Lithuanian +charset: iso-8859-13 +enabled: yes + +[language.nl] +description: Dutch +charset: iso-8859-1 +enabled: yes + +[language.no] +description: Norwegian +charset: iso-8859-1 +enabled: yes + +[language.pl] +description: Polish +charset: iso-8859-2 +enabled: yes + +[language.pt] +description: Protuguese +charset: iso-8859-1 +enabled: yes + +[language.pt_BR] +description: Protuguese (Brazil) +charset: iso-8859-1 +enabled: yes + +[language.ro] +description: Romanian +charset: iso-8859-2 +enabled: yes + +[language.ru] +description: Russian +charset: koi8-r +enabled: yes + +[language.sk] +description: Slovak +charset: utf-8 +enabled: yes + +[language.sl] +description: Slovenian +charset: iso-8859-2 +enabled: yes + +[language.sr] +description: Serbian +charset: utf-8 +enabled: yes + +[language.sv] +description: Swedish +charset: iso-8859-1 +enabled: yes + +[language.tr] +description: Turkish +charset: iso-8859-9 +enabled: yes + +[language.uk] +description: Ukrainian +charset: utf-8 +enabled: yes + +[language.vi] +description: Vietnamese +charset: utf-8 +enabled: yes + +[language.zh_CN] +description: Chinese +charset: utf-8 +enabled: yes + +[language.zh_TW] +description: Chinese (Taiwan) +charset: utf-8 +enabled: yes + + +[antispam] +# This section defines basic antispam detection settings. + +# This value contains lines which specify RFC 822 headers in the email to +# check for spamminess. Each line contains a `key: value` pair, where the key +# is the header to check and the value is a Python regular expression to match +# against the header's value. E.g.: +# +# X-Spam: (yes|maybe) +# +# The header value and regular expression are always matched +# case-insensitively. +header_checks: + +# The chain to jump to if any of the header patterns matches. This must be +# the name of an existing chain such as 'discard', 'reject', 'hold', or +# 'accept', otherwise 'hold' will be used. +jump_chain: hold + + +[mta] +# The class defining the interface to the incoming mail transport agent. +incoming: mailman.mta.postfix.LMTP + +# The callable implementing delivery to the outgoing mail transport agent. +# This must accept three arguments, the mailing list, the message, and the +# message metadata dictionary. +outgoing: mailman.mta.deliver.deliver + +# How to connect to the outgoing MTA. If smtp_user and smtp_pass is given, +# then Mailman will attempt to log into the MTA when making a new connection. +smtp_host: localhost +smtp_port: 25 +smtp_user: +smtp_pass: + +# Where the LMTP server listens for connections. Use 127.0.0.1 instead of +# localhost for Postfix integration, because Postfix only consults DNS +# (e.g. not /etc/hosts). +lmtp_host: 127.0.0.1 +lmtp_port: 8024 + +# 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 Mailman knows it into +# the envelope sender address (i.e. RFC 5321 MAIL FROM). 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, which get filled in by Mailman: +# +# $bounces -- the list's -bounces robot address will be set here +# $local -- the recipient address's local mailbox part will be set here +# $domain -- the recipient address's domain 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}+${local}=${domain} + +# 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 regular expression unambiguously decodes VERP addresses, which will be +# placed in the To: (or other, depending on the MTA) header of the bounce +# message by the bouncing MTA. Getting this right is critical -- and tricky. +# Learn your Python regular expressions. It must define exactly three named +# groups, `bounces`, `local` and `domain`, with the same definition as above. +# It will be compiled case-insensitively. +verp_regexp: ^(?P[^+]+?)\+(?P[^=]+)=(?P[^@]+)@.*$ + +# 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" +# +# when replying, so we skip everything up to '<' if any. +verp_confirm_regexp: ^(.*<)?(?P[^+]+?)\+(?P[^@]+)@.*$ + +# 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+$token@$domain +verp_probe_regexp: ^(?P[^+]+?)\+(?P[^@]+)@.*$ +# 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 . +# 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 + +# Where can we find the mail server specific configuration file? The path can +# be either a file system path or a Python import path. If the value starts +# with python: then it is a Python import path, otherwise it is a file system +# path. File system paths must be absolute since no guarantees are made about +# the current working directory. Python paths should not include the trailing +# .cfg, which the file must end with. +configuration: python:mailman.config.postfix + + +[bounces] +# How often should the bounce runner 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: + +# Set this to 'yes' to enable the archiver. +enable: no + +# Additional configuration for the archiver. The path can be either a file +# system path or a Python import path. If the value starts with python: then +# it is a Python import path, otherwise it is a file system path. File system +# paths must be absolute since no guarantees are made about the current +# working directory. Python paths should not include the trailing .cfg, which +# the file must end with. +configuration: changeme + +# When sending the message to the archiver, you have the option of +# "clobbering" the Date: header, specifically to make it more sane. Some +# archivers can't handle dates that are wildly off from reality. This does +# not change the Date: header for any other delivery vector except this +# specific archive. +# +# When the original Date header is clobbered, it will always be stored in +# X-Original-Date. The new Date header will always be set to the date at +# which the messages was received by the Mailman server, in UTC. +# +# Your options here are: +# * never -- Leaves the original Date header alone. +# * always -- Always override the Date header. +# * maybe -- Override the Date only if it is outside the clobber_skew period. +clobber_date: maybe +clobber_skew: 1d + +[archiver.mhonarc] +# This is the stock MHonArc archiver. +class: mailman.archiving.mhonarc.MHonArc +configuration: python:mailman.config.mhonarc + +[archiver.mail_archive] +# This is the stock mail-archive.com archiver. +class: mailman.archiving.mailarchive.MailArchive +configuration: python:mailman.config.mail_archive + +[archiver.prototype] +# This is a prototypical sample archiver. +class: mailman.archiving.prototype.Prototype + + +[styles] +# Python import paths inside which components are searched for which implement +# the IStyle interface. Use one path per line. +paths: + mailman.styles + +# The default style to apply if nothing else was requested. The value is the +# name of an existing style. If no such style exists, no style will be +# applied. +default: legacy-default + + +[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 List-Post + +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. Leave these blank if no authentication is +# necessary. +user: +password: + +# Host and port of the NNTP server to connect to. Leave these blank to use +# the default localhost:119. +host: +port: + +# 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 diff --git a/mailman3/config/var/log/mailman-web/mailman-web.log b/mailman3/config/var/log/mailman-web/mailman-web.log new file mode 100644 index 0000000..e69de29 diff --git a/mailman3/docker-compose.yml b/mailman3/docker-compose.yml new file mode 100644 index 0000000..30f4b7d --- /dev/null +++ b/mailman3/docker-compose.yml @@ -0,0 +1,8 @@ +mailman: + build: . + ports: + - '0.0.0.0:18000:18000' + - '0.0.0.0:8001:8001' + volumes: + - ./config/:/mailman3/config + - ./scripts/:/mailman3/scripts diff --git a/mailman3/scripts/run b/mailman3/scripts/run new file mode 100755 index 0000000..dea63ab --- /dev/null +++ b/mailman3/scripts/run @@ -0,0 +1,60 @@ +#! /bin/bash + +echo '================================================================================' +echo '' +echo 'Mailman3 Server for The Open Science Framework' +echo 'Maintained by Joshua Bird' +echo '================================================================================' +echo '' +echo 'Starting Postgresql Server' +/etc/init.d/postgresql start +echo '' +apt-get install -y sudo +sudo -u postgres createdb mailmanweb +sudo -u postgres psql -c "CREATE USER mailmanweb WITH PASSWORD 'change-this-password';" +sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE mailmanweb TO mailmanweb;" +echo '' +echo '================================================================================' +echo '' +echo 'Configuring Hostnames' +echo `awk 'END{print $1}' /etc/hosts` mailman.local >> /etc/hosts +echo '' +echo '================================================================================' + + +cd /mailman3/mailman-bundler +rsync -av /mailman3/config/ / +/etc/init.d/nginx start +pip install psycopg2 +buildout + +echo '================================================================================' +echo '' +echo 'Applying Configuration' +echo '' +buildout install gunicorn +./bin/mailman-post-update +./bin/mailman start --force + +apt-get install -y expect +expect <