From 0a4b5d24845fb86bade3ab3c38a6202862d6caad Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Sun, 23 Sep 2012 20:43:08 +0200 Subject: List creation via a Postfix local alias. --- misc/mklist/INSTALL | 56 ++++++++++++++++++++++++++++++ misc/mklist/README | 17 +++++++++ misc/mklist/mklist.pl | 95 +++++++++++++++++++++++++-------------------------- 3 files changed, 120 insertions(+), 48 deletions(-) create mode 100644 misc/mklist/INSTALL create mode 100644 misc/mklist/README (limited to 'misc') diff --git a/misc/mklist/INSTALL b/misc/mklist/INSTALL new file mode 100644 index 0000000..660bcf9 --- /dev/null +++ b/misc/mklist/INSTALL @@ -0,0 +1,56 @@ +sudo apt-get install libmail-gnupg-perl libmime-tools-perl libconfig-auto-perl + +Also, Fripost's schema (module Fripost::Schema) needs to be found in the +library path. + + addgroup mklist + adduser list mklist + adduser schleuder mklist + mkdir -m 0700 -p /etc/mklist/gnupg-{mailman,schleuder} + chown 'list:list' /etc/mklist/gnupg-mailman + chown 'schleuder:schleuder' /etc/mklist/gnupg-schleuder + cp ./config /etc/mklist/ + + mkdir /etc/postfix-lists/{mailman,schleuder} + chown list:list /etc/postfix-lists/mailman + chown schleuder:schleuder /etc/postfix-lists/schleuder + +To add a key: + + ggp --homedir /etc/mklist/gnupg --import < /path/to/pubkey.pub + +for each list manager. For instance, + + sudo -u www-data gpg --homedir /etc/fripost-panel/gnupg/ -a --export ECFA6E43 | sudo -u list gpg --homedir /etc/mklist/gnupg-mailman/ --import + sudo -u www-data gpg --homedir /etc/fripost-panel/gnupg/ -a --export ECFA6E43 | sudo -u schleuder gpg --homedir /etc/mklist/gnupg-schleuder/ --import + +(Don't forget to whitelist the key ID in the configuration file.) + + +Postfix's lookup table (/etc/postfix-lists/transport_mklist) + + mklist#fripost.org+mailman@lists.fripost.org mklist-mailman: + mklist#fripost.org+schleuder@lists.fripost.org mklist-schleuder: + +Postfix's master.cf + + mklist-mailman unix - n n - - pipe + flags=FR directory=/opt/fripost-panel/ user=list:list + argv=/opt/fripost-panel/misc/mklist/mklist.pl mailman ${size} + + mklist-schleuder unix - n n - - pipe + flags=FR directory=/opt/fripost-panel/ user=schleuder:schleuder + argv=/opt/fripost-panel/misc/mklist/mklist.pl schleuder ${size} + +Postfix's main.cf + transport_maps = cdb:$config_directory/transport_mklist + cdb:$config_directory/mailman/transport + cdb:$config_directory/schleuder/transport + + mklist-mailman_destination_concurrency_limit = 1 + mklist-mailman_destination_recpipient_limit = 1 + mklist-mailman_time_limit = 10m + + mklist-schleuder_destination_concurrency_limit = 1 + mklist-schleuder_destination_recpipient_limit = 1 + mklist-schleuder_time_limit = 2h diff --git a/misc/mklist/README b/misc/mklist/README new file mode 100644 index 0000000..0454713 --- /dev/null +++ b/misc/mklist/README @@ -0,0 +1,17 @@ +This is the script that should be used to finalize list creation. +Living alongside with the list managers, Postfix should feed it (pipe) +with emails to mklist+{mailman,schleuder}@lists.fripost.org . + +The email's body must have the following format: + + listname + admin + password + +Also, the email should have a valid GPG-signature. The list of GPG +fingerprints allowed to create lists can be found in the configuration +file. + +Upon GPG-verification, the script orders the list manager to create a +new list with the given credentials, and updates the LDAP directory +(removes the 'pending' status and adds list commands entries). diff --git a/misc/mklist/mklist.pl b/misc/mklist/mklist.pl index 105178a..37c05e5 100755 --- a/misc/mklist/mklist.pl +++ b/misc/mklist/mklist.pl @@ -9,11 +9,11 @@ our $VERSION = '0.01'; =head1 NAME -mklist.pl - Create a new list +mklist.pl - Create a new list =head1 SYNOPSIS -B {B|B} < email +B {B|B} [size] < email =cut @@ -21,23 +21,27 @@ B {B|B} < email ####################################################################### # -use Mail::GnuPG; -use MIME::Parser; -use File::Spec::Functions; +use File::Spec::Functions qw/catfile catdir/; use Fcntl qw/:flock SEEK_END/; use POSIX qw/setuid setgid/; use Pod::Usage; use Config::Auto; -use lib '../../../panel/lib'; +use lib 'lib'; +use Mail::GnuPG; +use MIME::Parser; use Fripost::Schema; my $transport = shift; pod2usage(2) unless defined $transport and grep { $transport eq $_} qw/mailman schleuder/; - use Cwd; +my $configdir = catdir('/','etc','mklist'); +my $config = Config::Auto::parse( catfile($configdir, 'config'), + format => "equal" ); -my $config = Config::Auto::parse( './config', format => "equal" ); +my $size = shift; +die "Email size $size is bigger than the maximum authorized (".$config->{max_size}.").\n" + if defined $config->{max_size} and defined $size and $size > $config->{max_size}; # Drop root privileges unless ($<) { @@ -66,7 +70,7 @@ my ($list, $owner, $password); $msg->mime_type eq 'multipart/signed' and $msg->parts; - my $gpg = Mail::GnuPG::->new; + my $gpg = Mail::GnuPG::->new( keydir => catdir($configdir,'gnupg-'.$transport) ); die "Error: The message is not GPG/MIME signed.\n" unless $gpg->is_signed( $msg ); @@ -78,7 +82,7 @@ my ($list, $owner, $password); die "Error: 0x$key ($addr) is not authorized to create lists.\n" unless grep { $key eq $_ } - (ref $config->{authorized_pubkeys} eq 'ARRAY' ? + (ref $config->{authorized_pubkeys} eq 'ARRAY' ? @{$config->{authorized_pubkeys}} : $config->{authorized_pubkeys} ); @@ -100,7 +104,7 @@ my ($l,$d) = split /\@/, $list, 2; ####################################################################### # # Ensure that the root DN has been created, otherwise doing the below is -# useless. +# useless. { # It's pointless to have a global variable here, since after the list @@ -116,34 +120,32 @@ my ($l,$d) = split /\@/, $list, 2; # # Create the list -#if ($transport eq 'mailman') { -# system ( '/var/lib/mailman/bin/newlist', '-q' -# , '-u', 'smtp.fripost.org' # TODO: that should be $mydestination -# , $list -# , $owner -# , $password -# ); -# die "newlist exited with status $?\n" if $?; -#} -# -#elsif ($transport eq 'schleuder') { -# system ( '/usr/bin/schleuder-newlist' -# , $list -# , '-email', $list -# , '-realname', $l -# , '-nointeractive' -# , '-adminaddress', $owner -# , '-initmember', $owner -# , '-initmemberkey', # TODO: that needs to be a file -# ); -# die "schleuder-newlist exited with status $?\n" if $?; -# system ( '/usr/bin/ruby', '/opt/webschleuder/contrib/enable_webschleuder.rb' -# , $list -# , $password -# ); -# # TODO: try not to use the password in the command argument -# die "enable_webschleuder exited with status $?\n" if $?; -#} +if ($transport eq 'mailman') { + system ( '/var/lib/mailman/bin/newlist', '-q' + , '-u', 'smtp.fripost.org' # TODO: that should be $mydestination + , $list + , $owner + , $password + ); + die "newlist died with status $?\n" if $?; +} + +elsif ($transport eq 'schleuder') { + system ( '/usr/bin/schleuder-newlist' + , $list + , '-email', $list + , '-realname', $l + , '-nointeractive' + , '-adminaddress', $owner + ); + die "schleuder-newlist died with status $?\n" if $?; + my $pid = open PW, '|-', '/opt/webschleuder/contrib/enable_webschleuder.rb', $list + or die "Cannot open: $!"; + print PW $password or die "Cannot print: $!"; + close PW; + my $r = $? >> 8; + die "enable_webschleuder died with status $r\n" if $r; +} # List the commands that are to be added to the LDAP directory and the lookup table. my @cmds = $transport eq 'mailman' ? qw/admin bounces confirm join leave owner request subscribe unsubscribe/ : @@ -167,9 +169,7 @@ my @cmds = $transport eq 'mailman' ? qw/admin bounces confirm join leave owner r # Create/update the Postfix lookup table. { - - my $db = File::Spec::Functions::catfile( $config->{postfix_data_dir}, - 'transport_'.$transport ); + my $db = catfile( $config->{postfix_data_dir}, $transport, 'transport' ); my $new = not (-e $db); open my $fh, '>>', $db or die "Cannot open $db: $!"; flock $fh, LOCK_EX or die "Cannot lock $db: $!"; @@ -178,17 +178,16 @@ my @cmds = $transport eq 'mailman' ? qw/admin bounces confirm join leave owner r print $fh "# Do not modify this file! Use $0 to create lists instead.\n" or die "Cannot print: $!"; } - - - print $fh "\n# ".$list." - ".localtime."\n"; + + print $fh "\n# ".$list." - ".(localtime)."\n"; &print_transport($fh, undef); foreach (@cmds) { &print_transport($fh, $_); } - + close $fh or die "Cannot close $db: $!"; - + # Compile the lookup table (Postfix takes care of the race condition here). system ('/usr/sbin/postmap', '-c', $config->{postfix_config_dir}, $db); - die "postmap exited with status $?\n" if $?; + die "postmap died with status $?\n" if $?; } -- cgit v1.2.3