Commit aa91de47 authored by sikeda's avatar sikeda
Browse files

[change] Authentication key used by mail commands are no longer reusable. It...

[change] Authentication key used by mail commands are no longer reusable.  It will be randomly generated.
Note that the keys generated by earlier releases are no longer available.


git-svn-id: https://subversion.renater.fr/sympa/branches/sympa-6.2-branch@12743 05aa8bb8-cd2b-0410-b1d7-8918dfa770ce
parent 9c3d8444
......@@ -5736,30 +5736,28 @@ sub do_subscribe {
$param->{'may_subscribe'} = 1;
 
if ($sub_is =~ /owner/) {
my $spool_req = Sympa::Spool::Auth->new;
my $request = Sympa::Request->new(
context => $list,
action => 'add',
custom_attribute => $in{custom_attribute},
email => $param->{'user'}{'email'},
gecos => $param->{'user'}{'gecos'},
sender => $param->{'user'}{'email'},
);
my $keyauth = $spool_req->store($request);
$list->send_notify_to_owner(
'subrequest',
{ 'who' => $param->{'user'}{'email'},
'keyauth' => Sympa::compute_auth(
context => $list,
email => $param->{'user'}{'email'},
action => 'add'
),
'replyto' => Conf::get_robot_conf($robot, 'sympa'),
'keyauth' => $keyauth,
'replyto' => Sympa::get_address($list, 'sympa'),
'custom_attribute' => $in{custom_attribute},
'gecos' => $param->{'user'}{'gecos'},
'ip' => $ip
}
);
 
my $spool_req = Sympa::Spool::Auth->new;
my $request = Sympa::Request->new_from_tuples(
context => $list,
email => $param->{'user'}{'email'},
custom_attribute => $in{custom_attribute},
action => 'add'
);
$spool_req->store($request);
Sympa::Report::notice_report_web('sent_to_owner', {},
$param->{'action'});
wwslog('info', 'Subscribe sent to owners');
......@@ -6329,25 +6327,22 @@ sub unsubscribe {
$report{'details_error'} = {};
return %report;
} elsif ($sig_is =~ /owner/) {
my $spool_req = Sympa::Spool::Auth->new;
my $request = Sympa::Request->new(
context => $list,
action => 'del',
email => $param->{'user'}{'email'},
sender => $param->{'user'}{'email'},
);
my $keyauth = $spool_req->store($request);
$list->send_notify_to_owner(
'sigrequest',
{ 'who' => $param->{'user'}{'email'},
'keyauth' => Sympa::compute_auth(
context => $list,
email => $param->{'user'}{'email'},
action => 'del'
),
'keyauth' => $keyauth,
}
);
 
my $spool_req = Sympa::Spool::Auth->new;
my $request = Sympa::Request->new_from_tuples(
context => $list,
email => $param->{'user'}{'email'},
action => 'del'
);
$spool_req->store($request);
wwslog('info', 'Signoff sent to owner');
$report{'success'} = 1;
$report{'details'} = 'sent_to_owner';
......@@ -7955,7 +7950,7 @@ sub do_add_fromsub {
 
my $spool_req = Sympa::Spool::Auth->new(
context => $list,
authkey => $id,
keyauth => $id,
action => 'add'
);
my ($request, $handle);
......@@ -8222,7 +8217,7 @@ sub do_del_fromsig {
 
my $spool_req = Sympa::Spool::Auth->new(
context => $list,
authkey => $id,
keyauth => $id,
action => 'del'
);
my ($request, $handle);
......
......@@ -75,6 +75,7 @@ nobase_modules_DATA = \
Sympa/Report.pm \
Sympa/Request.pm \
Sympa/Request/Handler/add.pm \
Sympa/Request/Handler/auth.pm \
Sympa/Request/Handler/confirm.pm \
Sympa/Request/Handler/del.pm \
Sympa/Request/Handler/distribute.pm \
......@@ -116,6 +117,7 @@ nobase_modules_DATA = \
Sympa/Spindle/DoForward.pm \
Sympa/Spindle/DoMessage.pm \
Sympa/Spindle/ProcessArchive.pm \
Sympa/Spindle/ProcessAuth.pm \
Sympa/Spindle/ProcessAutomatic.pm \
Sympa/Spindle/ProcessBounce.pm \
Sympa/Spindle/ProcessDigest.pm \
......
......@@ -45,7 +45,6 @@ use strict;
use warnings;
#use Cwd qw();
use DateTime;
use Digest::MD5;
use English qw(-no_match_vars);
use Scalar::Util qw();
use URI;
......@@ -71,6 +70,7 @@ my $log = Sympa::Log->instance;
=item compute_auth ( context =E<gt> $that, email =E<gt> $email,
action =E<gt> $cmd )
DEPRECATED.
Genererate a MD5 checksum using private cookie and parameters.
Parameters:
......@@ -100,52 +100,15 @@ Authenticaton key.
=cut
# Old name: List::compute_auth().
sub compute_auth {
$log->syslog('debug3', '(%s, %s, %s)', @_);
my %options = @_;
my $that = $options{context};
my $email = $options{email};
my $cmd = $options{action};
# Compat. <= 6.2.12.
$cmd = 'remind' if $cmd eq 'global_remind';
my ($list, $robot);
if (ref $that eq 'Sympa::List') {
$list = $that;
} elsif ($that and $that ne '*') {
$robot = $that;
} else {
$robot = '*';
}
$email = '' unless defined $email;
$email =~ tr/A-Z/a-z/;
$cmd =~ tr/A-Z/a-z/;
my ($cookie, $key, $listname);
if ($list) {
$listname = $list->{'name'};
$cookie = $list->{'admin'}{'cookie'}
|| Conf::get_robot_conf($robot, 'cookie');
} else {
$listname = '';
$cookie = Conf::get_robot_conf($robot, 'cookie');
}
$key = substr(
Digest::MD5::md5_hex(join('/', $cookie, $listname, $email, $cmd)),
-8);
return $key;
}
#DEPRECATED. Reusable auth key is no longer used.
#sub compute_auth;
=over
=item request_auth ( context =E<gt> $that, sender =E<gt> $sender,
action =E<gt> $cmd, [ email =E<gt> $email ], [ other options... ] )
DEPRECATED.
Sends an authentication request for a requested
command.
......@@ -185,126 +148,8 @@ C<1> or C<undef>.
=cut
# Old name: List::request_auth().
sub request_auth {
$log->syslog('debug2', '(%s, %s, %s, %s)', @_);
my %options = @_;
# Suppress warnings on uninitialized value.
foreach my $i (qw(sender email gecos)) {
$options{$i} = '' unless defined $options{$i};
}
my $that = $options{context} || '*';
my $sender = $options{sender};
my $cmd = $options{action};
my $email = $options{email};
my $gecos = $options{gecos};
my $quiet = $options{quiet};
$cmd = "quiet $cmd" if $quiet;
my ($list, $robot);
if (ref $that eq 'Sympa::List') {
$list = $that;
$robot = $that->{'domain'};
} elsif ($that and $that ne '*') {
$robot = $that;
} else {
$robot = '*';
}
my $keyauth;
my $data = {'to' => $sender};
if ($list) {
my $listname = $list->{'name'};
$data->{'list_context'} = 1;
if ($cmd =~ /signoff$/) {
$email ||= $sender;
$keyauth = Sympa::compute_auth(
context => $list,
email => $email,
action => 'signoff'
);
$data->{'command'} = "auth $keyauth $cmd $listname $email";
$data->{'type'} = 'signoff';
} elsif ($cmd =~ /subscribe$/) {
$keyauth = Sympa::compute_auth(
context => $list,
email => $sender,
action => 'subscribe'
);
$data->{'command'} = "auth $keyauth $cmd $listname $gecos";
$data->{'type'} = 'subscribe';
} elsif ($cmd =~ /add$/) {
$keyauth = Sympa::compute_auth(
context => $list,
email => $email,
action => 'add'
);
$data->{'command'} = "auth $keyauth $cmd $listname $email $gecos";
$data->{'type'} = 'add';
} elsif ($cmd =~ /del$/) {
my $keyauth = Sympa::compute_auth(
context => $list,
email => $email,
action => 'del'
);
$data->{'command'} = "auth $keyauth $cmd $listname $email";
$data->{'type'} = 'del';
} elsif ($cmd eq 'remind') {
my $keyauth =
Sympa::compute_auth(context => $list, action => 'remind');
$data->{'command'} = "auth $keyauth $cmd $listname";
$data->{'type'} = 'remind';
} elsif ($cmd eq 'invite') {
my $keyauth = Sympa::compute_auth(
context => $list,
email => $email,
action => 'invite'
);
$data->{'command'} = "auth $keyauth $cmd $listname $email";
$data->{'type'} = 'invite';
} elsif ($cmd eq 'review') {
my $keyauth =
Sympa::compute_auth(context => $list, action => 'review');
$data->{'command'} = "auth $keyauth $cmd $listname";
$data->{'type'} = 'review';
}
$data->{'auto_submitted'} = 'auto-replied';
unless (Sympa::send_file($list, 'request_auth', $sender, $data)) {
$log->syslog('notice',
'Unable to send template "request_auth" to %s', $sender);
return undef;
}
} else {
if ($cmd eq 'global_remind') {
my $keyauth = Sympa::compute_auth(
context => '*',
action => 'global_remind'
);
$data->{'command'} = "auth $keyauth remind *";
$data->{'type'} = 'remind';
}
$data->{'auto_submitted'} = 'auto-replied';
unless (Sympa::send_file($robot, 'request_auth', $sender, $data)) {
$log->syslog('notice',
'Unable to send template "request_auth" to %s', $sender);
return undef;
}
}
return 1;
}
# DEPRECATED. Reusable auth keys are no longer used.
#sub request_auth;
=head3 Finding config files and templates
......
......@@ -41,6 +41,12 @@ our %comms = (
scenario => 'add',
action_regexp => qr'reject|request_auth|do_it'i,
},
auth => {
cmd_regexp => qr'auth'i,
arg_regexp => qr'(\w+)\s+(.+)',
arg_keys => [qw(keyauth cmd)],
cmd_format => 'AUTH %s %s',
},
confirm => {
cmd_regexp => qr'con|confirm'i,
arg_regexp => qr'(\w+)\s*\z',
......
......@@ -76,15 +76,15 @@ workflow of Sympa. For more details see documentation on each class.
=head2 Command processing
<< sympa_msg.pl >>
<<sympa_msg.pl>>
*2
: +-> (reject)
(message) => [ProcessMessage] /
\ /---> [ToAuth] => (authkey)
+-> [AuthorizeRequest]
\---> [ToAuthOwner] => Auth
\
\ /---> [ToAuth] => Auth
*3 (AUTH) +-> [AuthorizeRequest]
: / \---> [ToAuthOwner] => Auth
Auth => [ProcessAuth] ------+ \
+-> [DispatchRequest]
:
*3
......
# -*- indent-tabs-mode: nil; -*-
# vim:ft=perl:et:sw=4
# $Id$
# Sympa - SYsteme de Multi-Postage Automatique
#
# Copyright (c) 1997, 1998, 1999 Institut Pasteur & Christophe Wolfhugel
# Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
# 2006, 2007, 2008, 2009, 2010, 2011 Comite Reseau des Universites
# Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016 GIP RENATER
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
package Sympa::Request::Handler::auth;
use strict;
use warnings;
use Time::HiRes qw();
use Sympa;
use Sympa::Log;
use Sympa::Spindle::ProcessAuth;
use base qw(Sympa::Spindle);
my $log = Sympa::Log->instance;
sub _twist {
my $self = shift;
my $request = shift;
my $key = $request->{keyauth};
my $sender = $request->{sender};
my $req = $request->{request}; # Request to be authorized.
my $spindle = Sympa::Spindle::ProcessAuth->new(
context => $req->{context},
action => $req->{action},
keyauth => $key,
confirmed_by => $sender,
scenario_context => $self->{scenario_context},
);
unless ($spindle and $spindle->spin) {
$log->syslog('info', 'AUTH %s from %s refused, auth failed',
$key, $sender);
$self->add_stash($request, 'user', 'wrong_email_confirm',
{key => $key, command => $req->{action}});
return undef;
} else {
foreach my $item (@{$spindle->{stash} || []}) {
$self->add_stash(@$item);
}
if ($spindle->{finish} and $spindle->{finish} eq 'success') {
return 1;
} else {
return undef;
}
}
}
1;
__END__
......@@ -79,12 +79,6 @@ sub _twist {
}
# Is the guest user allowed to subscribe in this list?
my %context;
$context{'user'}{'email'} = $email;
$context{'user'}{'gecos'} = $comment;
$context{'requested_by'} = $sender;
# Emulating subscription privilege of target user.
my $result =
Sympa::Scenario::request_action($list, 'subscribe', 'md5',
......@@ -120,14 +114,29 @@ sub _twist {
{'email' => $email, template => $result->{'tt2'}});
return undef;
} else {
my $keyauth = Sympa::compute_auth(
my $spool_req = Sympa::Spool::Auth->new;
my $req_subscribe = Sympa::Request->new(
context => $list,
action => 'subscribe',
email => $email,
action => 'subscribe'
sender => $sender,
);
$context{'subject'} = sprintf 'auth %s sub %s %s', $keyauth,
$list->{'name'}, $comment;
unless (Sympa::send_file($list, 'invite', $email, \%context)) {
my $keyauth = $spool_req->store($req_subscribe);
unless (
Sympa::send_file(
$list, 'invite', $email,
{ user => {email => $email, gecos => $comment},
requested_by => $sender,
keyauth => $keyauth,
# Compat. <= 6.2.14.
subject => sprintf(
'auth %s sub %s %s',
$keyauth, $list->{'name'}, $comment
)
}
)
) {
$log->syslog('notice', 'Unable to send template "invite" to %s',
$email);
my $error = sprintf 'Unable to send template "invite" to %s',
......
......@@ -145,8 +145,31 @@ sub _load {
}
# Parses the command and returns Sympa::Request instance.
# Old name: Sympa::Commands::parse().
sub _parse {
my $robot = shift;
my $line = shift;
my $message = shift;
my $request = __parse($robot, $line, $message);
if ($request->{action} eq 'auth' and not $request->{error}) {
my $req = __parse($robot, $request->{cmd}, $message);
if ($req->{action} eq 'auth') {
$request->{error} = 'syntax_errors';
} elsif ($req->{action} eq 'unknown' or $req->{error}) {
$req->{cmd_line} = $request->{cmd_line};
$request = $req;
} else {
$request->{request} = $req;
}
}
return $request;
}
# Old name: Sympa::Commands::parse().
sub __parse {
$log->syslog('debug2', '(%s, %s, %s, %s)', @_);
my $robot = shift;
my $line = shift;
......@@ -154,8 +177,6 @@ sub _parse {
$log->syslog('notice', "Parsing: %s", $line);
# Authentication key if 'auth' is present in the command line.
my $auth = $1 if $line =~ s/\A\s*auth\s+(\S+)\s+(.+)\z/$2/i;
# Boolean says if quiet is in the cmd line.
my $quiet = 1 if $line =~ s/\Aquiet\s+(.+)\z/$1/i;
......@@ -199,9 +220,8 @@ sub _parse {
$context = $robot || '*';
}
} else {
return Sympa::Request->new_from_tuples(
return Sympa::Request->new(
action => $action,
auth => $auth,
cmd_line => $line,
context => $robot,
error => 'syntax_errors',
......@@ -212,10 +232,9 @@ sub _parse {
);
}
my $request = Sympa::Request->new_from_tuples(
my $request = Sympa::Request->new(
%args,
action => $action,
auth => $auth,
cmd_line => $line,
context => $context,
quiet => $quiet,
......@@ -235,7 +254,7 @@ sub _parse {
}
# Unknown command.
return Sympa::Request->new_from_tuples(
return Sympa::Request->new(
action => 'unknown',
cmd_line => $line,
context => $robot,
......
......@@ -1476,39 +1476,58 @@ sub subscribe {
->faultdetail($reason_string);
}
if ($action =~ /owner/i) {
my $spool_req = Sympa::Spool::Auth->new;
my $request = Sympa::Request->new(
context => $list,
email => $sender,
gecos => $gecos,
action => 'add'
);
my $keyauth = $spool_req->store($request);
$list->send_notify_to_owner(
'subrequest',
{ 'who' => $sender,
'keyauth' => Sympa::compute_auth(
context => $list,
email => $sender,
action => 'add'
),
'keyauth' => $keyauth,
'replyto' => Conf::get_robot_conf($robot, 'sympa'),
'gecos' => $gecos
}
);
my $spool_req = Sympa::Spool::Auth->new;
my $request = Sympa::Request->new_from_tuples(
context => $list,
email => $sender,
gecos => $gecos,
action => 'add'
);
$spool_req->store($request);
$log->syslog('info', '%s from %s forwarded to the owners of the list',
$listname, $sender);
return SOAP::Data->name('result')->type('boolean')->value(1);
}
if ($action =~ /request_auth/i) {
Sympa::request_auth(
my $request = Sympa::Request->new(
context => $list,
sender => $sender,
action => 'subscribe',
gecos => $gecos
);
my $spool_req = Sympa::Spool::Auth->new;
my $keyauth;
unless ($keyauth = $spool_req->store($request)) {
#XXX FIXME: Check if failed!
}
# Send notice to the user.
my $cmd_line = $request->{cmd_line};
unless (
Sympa::send_file(
$list,
'request_auth',
$sender,
{ command => sprintf('AUTH %s %s', $keyauth, $cmd_line),
type => $request->{action},
to => $sender,
auto_submitted => 'auto-replied',
}
)
) {
#XXX FIXME: Check if failed!
}
$log->syslog('info', '%s from %s, auth requested', $listname,