aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem.moulin@fripost.org>2012-09-23 20:43:08 +0200
committerGuilhem Moulin <guilhem.moulin@fripost.org>2012-09-23 20:43:08 +0200
commit0a4b5d24845fb86bade3ab3c38a6202862d6caad (patch)
tree5bba357bda9c8cda0c3671d387967de4a4374650
parent858333c888ce15b16147e11d30ee1ae5403f7d5d (diff)
List creation via a Postfix local alias.
-rwxr-xr-xcgi-bin/index.cgi48
-rwxr-xr-xcgi-bin/index.fcgi47
-rw-r--r--config.in8
-rw-r--r--default.in15
-rw-r--r--misc/mklist/INSTALL56
-rw-r--r--misc/mklist/README17
-rwxr-xr-xmisc/mklist/mklist.pl95
7 files changed, 182 insertions, 104 deletions
diff --git a/cgi-bin/index.cgi b/cgi-bin/index.cgi
deleted file mode 100755
index 5efa469..0000000
--- a/cgi-bin/index.cgi
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/perl
-
-use 5.010_000;
-use strict;
-use warnings;
-use utf8;
-
-=head1 NAME
-
-index.cgi -
-
-=cut
-
-use lib 'lib';
-use Fripost::Panel::Interface;
-
-# TODO: Try out Fast CGI
-#use CGI::Fast();
-#
-#while (my $q = new CGI::Fast){
-# my $app = new WebApp(QUERY => $q);
-# $app->run();
-#}
-
-my @config = 'default.in';
-push @config, 'config.in' if -f 'config.in';
-
-my $cgi = Fripost::Panel::Interface->new(
- PARAMS => { cfg_file => [ @config ], format => 'equal' }
-);
-$cgi->run();
-
-=head1 AUTHOR
-
-Guilhem Moulin C<< <guilhem at fripost.org> >>
-
-=head1 COPYRIGHT
-
-Copyright 2012 Guilhem Moulin.
-
-=head1 LICENSE
-
-This program is free software; you can redistribute it and/or modify it
-under the same terms as perl itself.
-
-=cut
-
-__END__
diff --git a/cgi-bin/index.fcgi b/cgi-bin/index.fcgi
new file mode 100755
index 0000000..8e551d8
--- /dev/null
+++ b/cgi-bin/index.fcgi
@@ -0,0 +1,47 @@
+#!/usr/bin/perl
+
+use 5.010_000;
+use strict;
+use warnings;
+use utf8;
+
+=head1 NAME
+
+index.fcgi -
+
+=cut
+
+use CGI::Fast ();
+use File::Spec::Functions 'catfile';
+use lib 'lib';
+use Fripost::Panel::Interface;
+
+
+my $config_dir = '/etc/fripost-panel';
+my @config = catfile ('./', 'default.in');
+push @config, catfile ($config_dir, 'config.in') if -f catfile ($config_dir, 'config.in');
+
+while (my $q = CGI::Fast::->new){
+ my $cgi = Fripost::Panel::Interface::->new(
+ QUERY => $q,
+ PARAMS => { cfg_file => [ @config ], format => 'equal' }
+ );
+ $cgi->run();
+}
+
+=head1 AUTHOR
+
+Guilhem Moulin C<< <guilhem at fripost.org> >>
+
+=head1 COPYRIGHT
+
+Copyright 2012 Guilhem Moulin.
+
+=head1 LICENSE
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as perl itself.
+
+=cut
+
+__END__
diff --git a/config.in b/config.in
index 1a245f7..c2011d1 100644
--- a/config.in
+++ b/config.in
@@ -20,3 +20,11 @@ ldap_authcPW = panel
# The minimum password length.
password_min_length = 12
+
+# GnuPG private key and passphrase.
+gpg_private_key_id = ECFA6E43
+gpg_private_key_passphrase = xxxxxxxxxxxx
+
+# URL prefixes of the admin web interface for the list managers.
+listurl_mailman = http://smtp.fripost.org/cgi-bin/mailman/admin/
+listurl_schleuder = http://smtp.fripost.org/
diff --git a/default.in b/default.in
index ef32710..ec6a4c7 100644
--- a/default.in
+++ b/default.in
@@ -4,13 +4,8 @@
# which overrides the below.
-
-# Non absolute paths are be relative to this directory.
-pwd = ./
-
-
# Directory for templates
-tmpl_path = template/
+tmpl_path = ./template/
# Session configuration
@@ -32,11 +27,15 @@ cgi-bin = /cgi-bin/
# A timeout for idle connections, after which the user is automatically
# logged out
-timeout = 30m
+timeout = 15m
# The minimum password length.
password_min_length = 8
# LDAP configuration
-ldap_uri =ldap://127.0.0.1:389
+ldap_uri = ldap://127.0.0.1:389
+
+
+# GnuPG home
+gpghome = /etc/fripost-panel/gnupg/
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<mklist.pl> {B<mailman>|B<schleuder>} < email
+B<mklist.pl> {B<mailman>|B<schleuder>} [size] < email
=cut
@@ -21,23 +21,27 @@ B<mklist.pl> {B<mailman>|B<schleuder>} < 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 $?;
}