diff options
-rw-r--r-- | INSTALL | 14 | ||||
-rwxr-xr-x | bin/fripost-panel | 25 | ||||
-rwxr-xr-x | bin/ldap-krb5 | 25 | ||||
-rw-r--r-- | config.in | 11 | ||||
-rw-r--r-- | default.in | 2 | ||||
-rw-r--r-- | lib/Fripost/Panel/Interface.pm | 19 | ||||
-rw-r--r-- | lib/Fripost/Panel/Login.pm | 2 | ||||
-rw-r--r-- | lib/Fripost/Schema.pm | 7 | ||||
-rw-r--r-- | lib/Fripost/Schema/Alias.pm | 2 | ||||
-rw-r--r-- | lib/Fripost/Schema/Domain.pm | 2 | ||||
-rw-r--r-- | lib/Fripost/Schema/List.pm | 6 | ||||
-rw-r--r-- | lib/Fripost/Schema/Local.pm | 2 | ||||
-rw-r--r-- | lib/Fripost/Schema/Mailbox.pm | 2 | ||||
-rw-r--r-- | lib/Fripost/Schema/Misc.pm | 7 | ||||
-rwxr-xr-x | misc/mklist/mklist.pl | 9 | ||||
-rw-r--r-- | template/list-locals.html | 2 |
16 files changed, 62 insertions, 75 deletions
@@ -24,15 +24,16 @@ apt-get install libnet-ldap-perl \ # Configuration -mkdir -p /etc/fripost-panel/gnupg -chown www-data:www-data /etc/fripost-panel/gnupg && chmod 0700 /etc/fripost-panel/gnupg -cp ./config.in /etc/fripost-panel/ -chown www-data:www-data /etc/fripost-panel/config.in && chmod 0600 /etc/fripost-panel/config.in +sudo adduser --system fpanel --home /var/lib/fripost-panel --shell /bin/false --group www-data +sudo mkdir -p /etc/fripost-panel/ /var/lib/fripost-panel/gnupg +sudo chown fpanel:nogroup /var/lib/fripost-panel/gnupg && sudo chmod 0700 -R /var/lib/fripost-panel/ +sudo -u fpanel cp ./config.in /etc/fripost-panel/ && sudo chmod 0600 /etc/fripost-panel/config.in +sudo chown -R fpanel:www-data /etc/fripost-panel/ # Edit /etc/fripost-panel/config.in # Create a GPG key -sudo -u www-data gpg --homedir /etc/fripost-panel/gnupg/ --gen-key +sudo -u fpanel gpg --homedir /var/lib/fripost-panel/gnupg/ --gen-key # (1) RSA and RSA (default) # What keysize do you want? (2048) 4096 # Real name: Fripost Admin Panel @@ -40,3 +41,6 @@ sudo -u www-data gpg --homedir /etc/fripost-panel/gnupg/ --gen-key # Comment: # You selected this USER-ID: # "Fripost Admin Panel <AdminWebPanel@fripost.org>" + +# Kerberos +# TODO diff --git a/bin/fripost-panel b/bin/fripost-panel index 0046a4d..feb0008 100755 --- a/bin/fripost-panel +++ b/bin/fripost-panel @@ -7,9 +7,11 @@ PANEL_DIR=/opt/fripost-panel SOCKET_DIR=/var/run/fcgi -USER=www-data -PRINCIPAL=AdminWebPanel/fripost.org@FRIPOST.ORG -KEYTAB=/etc/fripost-panel/keytab +USER=fpanel +GROUP=www-data +PRINCIPAL=AdminWebPanel@FRIPOST.ORG +REALM=FRIPOST.ORG +KEYTAB=/var/lib/fripost-panel/keytab CGI=./cgi-bin/index.fcgi if [ $(id -u) -ne 0 ]; then @@ -17,27 +19,32 @@ if [ $(id -u) -ne 0 ]; then exit 1 fi -KSTART="k5start -b -f ${KEYTAB} -S ldap -I $(hostname --fqdn) -u ${PRINCIPAL} -q -K 60" +KSTART="k5start -b -f ${KEYTAB} -S ldap -I $(hostname --fqdn) -r ${REALM} -u ${PRINCIPAL} -q -l 61m -K 59" start () { test -x "${PANEL_DIR}/cgi-bin/index.fcgi" || exit 0 - pgrep -U "${USER}" -G "${USER}" -fx "/usr/bin/perl ${CGI}" >/dev/null && return 0 - pgrep -U "${USER}" -G "${USER}" -fx "${KSTART}" >/dev/null || sudo -u "${USER}" ${KSTART} || exit 1 + pgrep -U "${USER}" -G "${GROUP}" -fx "/usr/bin/perl ${CGI}" >/dev/null && return 0 + pgrep -U "${USER}" -G "${GROUP}" -fx "${KSTART}" >/dev/null || sudo -u "${USER}" ${KSTART} || exit 1 export FCGI_SOCKET_PATH="${SOCKET_DIR}/fripost-panel.socket" export FCGI_LISTEN_QUEUE=128 start-stop-daemon --start --background \ - --chuid "${USER}:${USER}" \ + --chuid "${USER}:${GROUP}" \ -d "${PANEL_DIR}" \ -m -p "${SOCKET_DIR}/fripost-panel.pid" \ + -k 0077 \ --exec ${CGI} + # Dirty, but it's safer than changing the umask to 0007 + sleep 1 + # The web server needs to talk and listen to the panel. + chmod 'ug+rwx,o=' "${FCGI_SOCKET_PATH}" || exit 1 } stop () { - pkill -U "${USER}" -G "${USER}" -fx "${KSTART}" || exit 1 + pkill -U "${USER}" -G "${GROUP}" -fx "${KSTART}" start-stop-daemon --stop -u "${USER}" \ - --chuid "${USER}:${USER}" \ + --chuid "${USER}:${GROUP}" \ -p "${SOCKET_DIR}/fripost-panel.pid" \ --retry=TERM/5/KILL/1 } diff --git a/bin/ldap-krb5 b/bin/ldap-krb5 deleted file mode 100755 index 368db8e..0000000 --- a/bin/ldap-krb5 +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -# Keep renewing/recreating kerberos tickets for ldap/hostname - -if [ $(id -u) -ne 0 ]; then - echo "Error: You are not root" - exit 1 -fi - -. /etc/default/slapd -KSTART="k5start -b -f ${KRB5_KTNAME} -u ldap -i $(hostname --fqdn) -q -K 60" -case "${1}" in - start) - pgrep -U "${SLAPD_USER}" -G "${SLAPD_GROUP}" -fx "${KSTART}" >/dev/null \ - || sudo -u "${SLAPD_USER}" ${KSTART} \ - || exit 1 - ;; - stop) - pkill -U "${SLAPD_USER}" -G "${SLAPD_GROUP}" -fx "${KSTART}" >/dev/null \ - ;; - *) - echo "Usage: $0 {start|stop}" >&2 - exit 1 - ;; -esac @@ -12,14 +12,9 @@ default_realm = fripost.org # The LDAP suffix that will be appended to bind and search DN:s. ldap_suffix = ou=virtual,o=mailHosting,dc=fripost,dc=dev -# The authentication ID for SASL binds. This has to be a kerberos -# principal, and a ticket has to be cached for the user running the -# program. -krb5_principal = AdminWebPanel/fripost.org@FRIPOST.ORG - -# The hostname associated with the 'ldap/...' principal. (Probably the -# fqdn of the machine running slapd). -krb5_host = gnu.friprogramvarusyndikatet.se +# The kerberos service instance (probably the fqdn of the machine +# running slapd). +krb5_service_instance = gnu.friprogramvarusyndikatet.se # The minimum password length. password_min_length = 12 @@ -38,4 +38,4 @@ ldap_uri = ldap://127.0.0.1:389 # GnuPG home -gpghome = /etc/fripost-panel/gnupg/ +gpghome = /var/lib/fripost-panel/gnupg/ diff --git a/lib/Fripost/Panel/Interface.pm b/lib/Fripost/Panel/Interface.pm index db6752e..f150a39 100644 --- a/lib/Fripost/Panel/Interface.pm +++ b/lib/Fripost/Panel/Interface.pm @@ -12,10 +12,12 @@ Interface.pm - =cut use parent 'Fripost::Panel::Login'; + use Fripost::Schema; use Fripost::Password; use HTML::Entities; -use Net::IDN::Encode qw/email_to_unicode/; +use Net::IDN::Encode qw/email_to_unicode domain_to_ascii/; +use CGI::Util qw/escape unescape/; # This method is called right before the 'setup' method below. It @@ -117,7 +119,9 @@ sub ListLocals : Runmode { $template->param( listAliases => $#aliases >= 0 || $domain{permissions} =~ /[aop]/ ); $template->param( aliases => [ - map { { alias => encode_entities($_->{alias}) + map { my $a = escape(encode_entities($_->{alias})); # TODO + { aliasurl => escape($a) + , alias => $a , description => join ("\n", @{$_->{description}}) , isactive => $_->{isactive} , destinations => [ map { {destination => encode_entities($_)} } @@ -139,7 +143,7 @@ sub ListLocals : Runmode { , description => join ("\n", @{$_->{description}}) , isactive => $_->{isactive} , transport => $_->{transport} - , listurl => $CFG{'listurl_'.$_->{transport}}.$_->{list}.'@'.$d + , listurl => $CFG{'listurl_'.$_->{transport}}.$_->{list}.'@'.domain_to_ascii($d) }; } @lists @@ -189,7 +193,7 @@ sub EditDomain : Runmode { $template->param( isactive => $q->param('isactive') , description => $q->param('description') , catchalls => $q->param('catchalls') - , error => encode_entities ($error, "‘‘") ); + , error => encode_entities ($error) ); } else { $template->param( isactive => $domain{isactive} @@ -267,8 +271,7 @@ sub EditLocal : Runmode { $q->param('oldpw'), ldap_uri => $CFG{ldap_uri}, ldap_suffix => $CFG{ldap_suffix}, - -die => "Wrong password (for ‘" - .encode_entities($u)."‘)." ); + -die => "Wrong password (for ‘".$u."’)." ); }; $error = $@ || $fp->mailbox->passwd( $entry{user}, @@ -336,7 +339,7 @@ sub EditLocal : Runmode { my $news = (defined $q->param('submit') or (defined $q->param('a') and $q->param('a') eq 'delete')); $template->param( newChanges => $news ); - $template->param( error => encode_entities ($error, "‘‘") ) if $error; + $template->param( error => encode_entities ($error) ) if $error; $template->param( canDelete => 1 ) if $t eq 'alias'; # TODO $template->param( listurl => $CFG{'listurl_'.$local{transport}}.$l.'@'.$d ) if $t eq 'list'; @@ -445,7 +448,7 @@ sub AddLocal : Runmode { } $template->param( isactive => $q->param('isactive') , description => $q->param('description') - , error => encode_entities ($error, "‘‘") ); + , error => encode_entities ($error) ); } else { $template->param( isactive => 1 ); diff --git a/lib/Fripost/Panel/Login.pm b/lib/Fripost/Panel/Login.pm index 8132310..86b3e66 100644 --- a/lib/Fripost/Panel/Login.pm +++ b/lib/Fripost/Panel/Login.pm @@ -208,7 +208,7 @@ sub error_rm : ErrorRunmode { $mesg = 'Not Found' } $template->param( code => $error ); - $template->param( message => encode_entities ($mesg, "‘‘") ); + $template->param( message => encode_entities ($mesg) ); return $template->output; } diff --git a/lib/Fripost/Schema.pm b/lib/Fripost/Schema.pm index a0730f9..bb1f3f5 100644 --- a/lib/Fripost/Schema.pm +++ b/lib/Fripost/Schema.pm @@ -19,7 +19,7 @@ use warnings; use utf8; use Net::LDAP; -use Authen::SASL; +use Authen::SASL 'Cyrus'; use Fripost::Schema::Domain; use Fripost::Schema::Mailbox; use Fripost::Schema::Alias; @@ -53,10 +53,9 @@ sub SASLauth { my $sasl = Authen::SASL::->new( mechanism => 'GSSAPI', - callback => { user => 'dn:'.$self->whoami - , authname => $cfg{krb5_principal} } + callback => { user => 'dn:'.$self->whoami } ); - my $conn = $sasl->client_new('ldap', $cfg{krb5_host} ); + my $conn = $sasl->client_new('ldap', $cfg{krb5_service_instance} ); die $conn->error if $conn->code; my $mesg = $self->ldap->bind( '', sasl => $conn ); diff --git a/lib/Fripost/Schema/Alias.pm b/lib/Fripost/Schema/Alias.pm index f111d7f..07ae84f 100644 --- a/lib/Fripost/Schema/Alias.pm +++ b/lib/Fripost/Schema/Alias.pm @@ -114,7 +114,7 @@ sub add { my ($l,$d) = split /\@/, email_to_ascii($a->{alias}), 2; die "Missing alias name\n" if $l eq ''; &_is_valid($a); - die "‘".$a->{alias}."‘ alread exists\n" + die "‘".$a->{alias}."’ already exists\n" if $self->local->exists($a->{alias},%options); my %attrs = ( objectClass => 'FripostVirtualAlias' diff --git a/lib/Fripost/Schema/Domain.pm b/lib/Fripost/Schema/Domain.pm index 8017e00..64a8932 100644 --- a/lib/Fripost/Schema/Domain.pm +++ b/lib/Fripost/Schema/Domain.pm @@ -94,7 +94,7 @@ sub get { my $domain = $domains->pop_entry; unless (defined $domain) { die $options{'-die'}."\n" if defined $options{'-die'}; - die "No such such domain ‘$d‘.\n"; + die "No such such domain: ‘$d’\n"; } return ( domain => domain_to_unicode($domain->get_value('fvd')) diff --git a/lib/Fripost/Schema/List.pm b/lib/Fripost/Schema/List.pm index edf9d24..87876f6 100644 --- a/lib/Fripost/Schema/List.pm +++ b/lib/Fripost/Schema/List.pm @@ -117,7 +117,7 @@ sub add { die "Missing list name\n" if $l eq ''; must_attrs( $l, 'transport' ); &_is_valid($l); - die "‘".$l->{list}."‘ already exists\n" + die "‘".$l->{list}."’ already exists\n" if $self->local->exists($l->{list},%options); my %attrs = ( objectClass => 'FripostVirtualList' @@ -177,7 +177,7 @@ sub is_pending { scope => 'base', deref => 'never', filter => 'objectClass=FripostVirtualList', - attrs => [ 'fvl', 'fripostIsStatusPending' ] + attrs => [ 'fripostIsStatusPending' ] ); die "Error: ".$l.'@'.$d.": No such object in the LDAP directory\n" if $mesg->code == 32; # No such object; a common error here. @@ -265,7 +265,7 @@ sub _is_valid { must_attrs( $l, qw/list isactive/ ); $l->{list} = email_valid( $l->{list}, -exact => 1 ); - die "Invalid transport: ‘".$l->{transport}."‘\n" + die "Invalid transport: ‘".$l->{transport}."’\n" if defined $l->{transport} and $l->{transport} !~ /^(schleuder|mailman)$/; # TODO: check commands diff --git a/lib/Fripost/Schema/Local.pm b/lib/Fripost/Schema/Local.pm index bf92555..9efff91 100644 --- a/lib/Fripost/Schema/Local.pm +++ b/lib/Fripost/Schema/Local.pm @@ -68,7 +68,7 @@ sub get { unless (defined $local) { die $options{'-die'}."\n" if defined $options{'-die'}; - die "No such such entry ‘".$loc."‘.\n"; + die "No such such entry ‘".$loc."’.\n"; } my %ret; diff --git a/lib/Fripost/Schema/Mailbox.pm b/lib/Fripost/Schema/Mailbox.pm index 0f2ff53..95e2d10 100644 --- a/lib/Fripost/Schema/Mailbox.pm +++ b/lib/Fripost/Schema/Mailbox.pm @@ -137,7 +137,7 @@ sub add { my ($l,$d) = split /\@/, email_to_ascii($m->{user}), 2; die "Missing user name\n" if $l eq ''; &_is_valid($m); - die "‘".$m->{user}."‘ alread exists\n" + die "‘".$m->{user}."’ already exists\n" if $self->local->exists($m->{user},%options); my %attrs = ( objectClass => 'FripostVirtualMailbox' diff --git a/lib/Fripost/Schema/Misc.pm b/lib/Fripost/Schema/Misc.pm index 745a20b..114e01b 100644 --- a/lib/Fripost/Schema/Misc.pm +++ b/lib/Fripost/Schema/Misc.pm @@ -82,7 +82,7 @@ sub get_perms { sub must_attrs { my $h = shift; foreach (@_) { - die '‘'.$_."‘: Missing attribute.\n" + die 'Missing attribute: ‘'.$_."’\n" unless defined $h->{$_} and (ref $h->{$_} eq 'ARRAY' ? @{$h->{$_}} : $h->{$_} ne '') } @@ -102,14 +102,15 @@ sub email_valid { my $mesg = $options{'-error'} // "Invalid e-mail"; $in = $options{'-prefix'}.$i if defined $options{'-prefix'}; Encode::_utf8_on($in); + Encode::_utf8_on($i); $in = Net::IDN::Encode::email_to_ascii($in); my $addr = Email::Valid::->address( -address => $in, -tldcheck => 1, -fqdn => 1 ); my $match = defined $addr; - $match &&= $addr eq $in if $options{'-exact'}; - die $mesg." ‘".$i."‘\n" unless $match; + $match &&= $addr eq $in if $options{'-exact'}; + die $mesg." ‘".$i."’\n" unless $match; $addr =~ s/^$options{'-prefix'}// if defined $options{'-prefix'}; return $addr; } diff --git a/misc/mklist/mklist.pl b/misc/mklist/mklist.pl index ac5f526..3223c45 100755 --- a/misc/mklist/mklist.pl +++ b/misc/mklist/mklist.pl @@ -29,6 +29,8 @@ use Config::Auto; use lib 'lib'; use Mail::GnuPG; use MIME::Parser; +use MIME::QuotedPrint; +use Net::IDN::Encode qw/email_to_ascii/; use Fripost::Schema; my $transport = shift; @@ -92,9 +94,10 @@ my ($list, $owner, $password); # address. my @body = grep { !/^\s*$/ } (split /\s*\n\s*/, $msg->parts(0)->stringify_body); - $list = shift @body; - $owner = shift @body; - $password = shift @body; + $list = decode_qp(shift @body); + Encode::_utf8_on($list); $list = email_to_ascii($list); + $owner = decode_qp(shift @body); + $password = decode_qp(shift @body); # TODO: idealy the email would be encrypted (at least for schleuder), # since it contains a password. } diff --git a/template/list-locals.html b/template/list-locals.html index f9d8535..cb6f057 100644 --- a/template/list-locals.html +++ b/template/list-locals.html @@ -84,7 +84,7 @@ <tbody> <TMPL_LOOP NAME=aliases> <TMPL_IF NAME=__even__><tr class="odd"><TMPL_ELSE><tr></TMPL_IF> - <td><span class="alias"><a href="<TMPL_VAR NAME=url>/<TMPL_VAR NAME=domain>/<TMPL_VAR NAME=alias>/"><TMPL_VAR NAME=alias></a></span></td> + <td><span class="alias"><a href="<TMPL_VAR NAME=url>/<TMPL_VAR NAME=domain>/<TMPL_VAR NAME=aliasurl>/"><TMPL_VAR NAME=alias></a></span></td> <td><TMPL_IF NAME=description><TMPL_VAR NAME=description><TMPL_ELSE><span class="none">(none)</span></TMPL_IF></td> <td><TMPL_IF NAME=isactive><span class="active">✔</span><TMPL_ELSE><span class="inactive">✘</span></TMPL_IF></td> <td><TMPL_UNLESS NAME=destinations><span class="none">(none)</span></TMPL_UNLESS> |