API REST pour le destinataire de mails
This commit is contained in:
parent
30cf2e5a9f
commit
cacba346f6
|
@ -51,6 +51,54 @@ RUN apk add \
|
||||||
s6-overlay \
|
s6-overlay \
|
||||||
vim
|
vim
|
||||||
|
|
||||||
|
# Dependencies for REST API
|
||||||
|
RUN apk add \
|
||||||
|
gcc \
|
||||||
|
libc-dev \
|
||||||
|
make \
|
||||||
|
perl-app-cpanminus \
|
||||||
|
perl-clone \
|
||||||
|
perl-config-any \
|
||||||
|
perl-data-optlist \
|
||||||
|
perl-dev \
|
||||||
|
perl-exporter-tiny \
|
||||||
|
perl-extutils-config \
|
||||||
|
perl-extutils-helpers \
|
||||||
|
perl-extutils-installpaths \
|
||||||
|
perl-file-sharedir \
|
||||||
|
perl-file-sharedir-install \
|
||||||
|
perl-file-slurp \
|
||||||
|
perl-file-which \
|
||||||
|
perl-hash-merge-simple \
|
||||||
|
perl-hash-multivalue \
|
||||||
|
perl-http-date \
|
||||||
|
perl-http-headers-fast \
|
||||||
|
perl-import-into \
|
||||||
|
perl-json-maybexs \
|
||||||
|
perl-module-build \
|
||||||
|
perl-module-build-tiny \
|
||||||
|
perl-module-implementation \
|
||||||
|
perl-module-runtime \
|
||||||
|
perl-moo \
|
||||||
|
perl-params-util \
|
||||||
|
perl-params-validate \
|
||||||
|
perl-path-tiny \
|
||||||
|
perl-plack \
|
||||||
|
perl-readonly \
|
||||||
|
perl-ref-util \
|
||||||
|
perl-role-tiny \
|
||||||
|
perl-safe-isa \
|
||||||
|
perl-sub-exporter \
|
||||||
|
perl-sub-install \
|
||||||
|
perl-sub-quote \
|
||||||
|
perl-template-toolkit \
|
||||||
|
perl-type-tiny \
|
||||||
|
perl-yaml
|
||||||
|
|
||||||
|
RUN cpanm -n -v \
|
||||||
|
Dancer2 \
|
||||||
|
Module::Pluggable::Object
|
||||||
|
|
||||||
COPY --from=roundcube-build --chown=root:www-data \
|
COPY --from=roundcube-build --chown=root:www-data \
|
||||||
/var/www/roundcubemail /var/www/roundcubemail
|
/var/www/roundcubemail /var/www/roundcubemail
|
||||||
RUN chown apache /var/www/roundcubemail/logs /var/www/roundcubemail/temp
|
RUN chown apache /var/www/roundcubemail/logs /var/www/roundcubemail/temp
|
||||||
|
@ -62,9 +110,6 @@ RUN newaliases
|
||||||
|
|
||||||
# TODO faire en sorte que Dovecot logue dans syslog
|
# TODO faire en sorte que Dovecot logue dans syslog
|
||||||
|
|
||||||
# TODO finir de configurer postfix pour qu’il fasse les contrôles
|
|
||||||
# SPF/DKIM/DMARC si on le lui demande
|
|
||||||
|
|
||||||
# TODO rendre le mot de passe de destinataire@destinataire.example
|
# TODO rendre le mot de passe de destinataire@destinataire.example
|
||||||
# configurable
|
# configurable
|
||||||
|
|
||||||
|
@ -90,4 +135,6 @@ COPY etc/opendmarc/opendmarc.conf /etc/opendmarc/opendmarc.conf
|
||||||
RUN doveadm pw -p "PasSecretDuTout" | \
|
RUN doveadm pw -p "PasSecretDuTout" | \
|
||||||
awk '{ print "destinataire:" $1 }' > /etc/dovecot/users
|
awk '{ print "destinataire:" $1 }' > /etc/dovecot/users
|
||||||
|
|
||||||
|
COPY web-api /src/api
|
||||||
|
|
||||||
ENTRYPOINT ["/init"]
|
ENTRYPOINT ["/init"]
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/execlineb -P
|
||||||
|
/usr/bin/env perl /src/api/bin/app.psgi
|
|
@ -0,0 +1 @@
|
||||||
|
longrun
|
|
@ -0,0 +1,24 @@
|
||||||
|
MANIFEST
|
||||||
|
MANIFEST.SKIP
|
||||||
|
.dancer
|
||||||
|
Makefile.PL
|
||||||
|
config.yml
|
||||||
|
cpanfile
|
||||||
|
views/index.tt
|
||||||
|
views/layouts/main.tt
|
||||||
|
lib/Email/SpoofingDemo/API/DNS.pm
|
||||||
|
t/002_index_route.t
|
||||||
|
t/001_base.t
|
||||||
|
environments/production.yml
|
||||||
|
environments/development.yml
|
||||||
|
bin/app.psgi
|
||||||
|
public/500.html
|
||||||
|
public/dispatch.cgi
|
||||||
|
public/dispatch.fcgi
|
||||||
|
public/favicon.ico
|
||||||
|
public/404.html
|
||||||
|
public/javascripts/jquery.js
|
||||||
|
public/css/error.css
|
||||||
|
public/css/style.css
|
||||||
|
public/images/perldancer-bg.jpg
|
||||||
|
public/images/perldancer.jpg
|
|
@ -0,0 +1,17 @@
|
||||||
|
^\.git\/
|
||||||
|
maint
|
||||||
|
^tags$
|
||||||
|
.last_cover_stats
|
||||||
|
Makefile$
|
||||||
|
^blib
|
||||||
|
^pm_to_blib
|
||||||
|
^.*.bak
|
||||||
|
^.*.old
|
||||||
|
^t.*sessions
|
||||||
|
^cover_db
|
||||||
|
^.*\.log
|
||||||
|
^.*\.swp$
|
||||||
|
MYMETA.*
|
||||||
|
^.gitignore
|
||||||
|
^.svn\/
|
||||||
|
^Email-SpoofingDemo-API-DNS-
|
|
@ -0,0 +1,26 @@
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use ExtUtils::MakeMaker;
|
||||||
|
|
||||||
|
# Normalize version strings like 6.30_02 to 6.3002,
|
||||||
|
# so that we can do numerical comparisons on it.
|
||||||
|
my $eumm_version = $ExtUtils::MakeMaker::VERSION;
|
||||||
|
$eumm_version =~ s/_//;
|
||||||
|
|
||||||
|
WriteMakefile(
|
||||||
|
NAME => 'Email::SpoofingDemo::API::DNS',
|
||||||
|
AUTHOR => q{Marc van der Wal <marc.vanderwal@afnic.fr>},
|
||||||
|
VERSION_FROM => 'lib/Email/SpoofingDemo/API/Recipient.pm',
|
||||||
|
ABSTRACT => 'Email spoofing demo: REST API for recipient',
|
||||||
|
($eumm_version >= 6.3001
|
||||||
|
? ('LICENSE'=> 'all-rights-reserved')
|
||||||
|
: ()),
|
||||||
|
PL_FILES => {},
|
||||||
|
PREREQ_PM => {
|
||||||
|
'Test::More' => 0,
|
||||||
|
'YAML' => 0,
|
||||||
|
'Dancer2' => 0.300000,
|
||||||
|
},
|
||||||
|
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
|
||||||
|
clean => { FILES => 'Email-SpoofingDemo-API-DNS-*' },
|
||||||
|
);
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use FindBin;
|
||||||
|
use lib "$FindBin::Bin/../lib";
|
||||||
|
|
||||||
|
use Email::SpoofingDemo::API::Recipient;
|
||||||
|
Email::SpoofingDemo::API::Recipient->to_app;
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
appname: "Email::SpoofingDemo::API::Recipient"
|
||||||
|
charset: "UTF-8"
|
||||||
|
serializer: JSON
|
|
@ -0,0 +1,11 @@
|
||||||
|
requires "Dancer2" => "0.300000";
|
||||||
|
|
||||||
|
recommends "YAML" => "0";
|
||||||
|
recommends "URL::Encode::XS" => "0";
|
||||||
|
recommends "CGI::Deurl::XS" => "0";
|
||||||
|
recommends "HTTP::Parser::XS" => "0";
|
||||||
|
|
||||||
|
on "test" => sub {
|
||||||
|
requires "Test::More" => "0";
|
||||||
|
requires "HTTP::Request::Common" => "0";
|
||||||
|
};
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
logger: "console"
|
||||||
|
log: "core"
|
||||||
|
|
||||||
|
# should Dancer2 consider warnings as critical errors?
|
||||||
|
warnings: 1
|
||||||
|
|
||||||
|
# should Dancer2 show a stacktrace when an 5xx error is caught?
|
||||||
|
# if set to yes, public/500.html will be ignored and either
|
||||||
|
# views/500.tt, 'error_template' template, or a default error template will be used.
|
||||||
|
show_errors: 1
|
||||||
|
|
||||||
|
# print the banner
|
||||||
|
startup_info: 1
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
# only log warning and error messsages
|
||||||
|
log: "warning"
|
||||||
|
|
||||||
|
# log message to a file in logs/
|
||||||
|
logger: "file"
|
||||||
|
|
||||||
|
# don't consider warnings critical
|
||||||
|
warnings: 0
|
||||||
|
|
||||||
|
# hide errors
|
||||||
|
show_errors: 0
|
||||||
|
|
||||||
|
# disable server tokens in production environments
|
||||||
|
no_server_tokens: 1
|
|
@ -0,0 +1,44 @@
|
||||||
|
package Email::SpoofingDemo::API::Recipient;
|
||||||
|
|
||||||
|
use Dancer2;
|
||||||
|
|
||||||
|
use Email::SpoofingDemo::PostfixConfig qw(spf_dkim_dmarc_status
|
||||||
|
set_spf_dkim_dmarc_status);
|
||||||
|
|
||||||
|
our $VERSION = '0.1';
|
||||||
|
|
||||||
|
get '/' => sub { return "Welcome"; };
|
||||||
|
|
||||||
|
get '/status' => sub {
|
||||||
|
my $status = spf_dkim_dmarc_status();
|
||||||
|
my %result = map {
|
||||||
|
$_ => ($status->{$_} ? 'enabled' : 'disabled')
|
||||||
|
} (keys %$status);
|
||||||
|
return \%result;
|
||||||
|
};
|
||||||
|
|
||||||
|
put '/status' => sub {
|
||||||
|
my $spf_enabled = body_parameters->get('spf');
|
||||||
|
my $dkim_enabled = body_parameters->get('dkim');
|
||||||
|
my $dmarc_enabled = body_parameters->get('dmarc');
|
||||||
|
|
||||||
|
unless (defined $spf_enabled
|
||||||
|
and defined $dkim_enabled
|
||||||
|
and defined $dmarc_enabled) {
|
||||||
|
status 400;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_spf_dkim_dmarc_status(
|
||||||
|
$spf_enabled eq 'enabled',
|
||||||
|
$dkim_enabled eq 'enabled',
|
||||||
|
$dmarc_enabled eq 'enabled'
|
||||||
|
);
|
||||||
|
return "OK";
|
||||||
|
};
|
||||||
|
|
||||||
|
any qr{.*} => sub { status 'not_found'; return "Invalid route" };
|
||||||
|
|
||||||
|
dance;
|
||||||
|
|
||||||
|
true;
|
|
@ -0,0 +1,110 @@
|
||||||
|
package Email::SpoofingDemo::PostfixConfig;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use v5.10;
|
||||||
|
use utf8;
|
||||||
|
|
||||||
|
use Exporter 'import';
|
||||||
|
|
||||||
|
our @EXPORT_OK = qw(spf_dkim_dmarc_status
|
||||||
|
set_spf_dkim_dmarc_status);
|
||||||
|
|
||||||
|
my $CHECK_SPF_POLICY = 'check_policy_service unix:private/policy';
|
||||||
|
my $DKIM_MILTER = 'inet:127.0.0.1:8891';
|
||||||
|
my $DMARC_MILTER = 'inet:127.0.0.1:8893';
|
||||||
|
|
||||||
|
my $POSTCONF = '/usr/sbin/postconf';
|
||||||
|
|
||||||
|
sub safe_system {
|
||||||
|
system @_;
|
||||||
|
my $exit_status = ($? >> 8);
|
||||||
|
die "$_[0] exited with status $exit_status" unless $exit_status == 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub reload_postfix {
|
||||||
|
safe_system(qw(postfix reload));
|
||||||
|
}
|
||||||
|
|
||||||
|
sub postconf_read {
|
||||||
|
my ($variable) = @_;
|
||||||
|
|
||||||
|
my $output = '';
|
||||||
|
|
||||||
|
open (my $fh, '-|', $POSTCONF, '-h', $variable) or die "postconf: $!";
|
||||||
|
while (<$fh>) {
|
||||||
|
chomp;
|
||||||
|
$output .= $_;
|
||||||
|
}
|
||||||
|
close($fh);
|
||||||
|
|
||||||
|
my $exit_status = ($? >> 8);
|
||||||
|
die "postconf failed" unless $exit_status == 0;
|
||||||
|
|
||||||
|
if (wantarray) {
|
||||||
|
return split(/,\s*/, $output);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub postconf_set {
|
||||||
|
die "Need an even number of parameters" if scalar(@_) % 2 != 0;
|
||||||
|
|
||||||
|
my @vars_to_set;
|
||||||
|
|
||||||
|
while (@_) {
|
||||||
|
my $parameter = shift;
|
||||||
|
my $value = shift;
|
||||||
|
push(@vars_to_set, "$parameter=$value");
|
||||||
|
}
|
||||||
|
|
||||||
|
my ($parameter, $value) = @_;
|
||||||
|
|
||||||
|
safe_system($POSTCONF, '-e', @vars_to_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub smtpd_recipient_restrictions {
|
||||||
|
my ($enabled) = @_;
|
||||||
|
|
||||||
|
return ($enabled) ? $CHECK_SPF_POLICY : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
sub spf_dkim_dmarc_status {
|
||||||
|
my @smtpd_recipient_restrictions = postconf_read('smtpd_recipient_restrictions');
|
||||||
|
my @smtpd_milters = postconf_read('smtpd_milters');
|
||||||
|
|
||||||
|
return {
|
||||||
|
spf => scalar(grep { $_ eq $CHECK_SPF_POLICY } @smtpd_recipient_restrictions),
|
||||||
|
dkim => scalar(grep { $_ eq $DKIM_MILTER } @smtpd_milters),
|
||||||
|
dmarc => scalar(grep { $_ eq $DMARC_MILTER } @smtpd_milters)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub smtpd_milters {
|
||||||
|
my ($dkim_enabled, $dmarc_enabled) = @_;
|
||||||
|
|
||||||
|
my @milters;
|
||||||
|
push @milters, $DKIM_MILTER if $dkim_enabled;
|
||||||
|
push @milters, $DMARC_MILTER if $dmarc_enabled;
|
||||||
|
|
||||||
|
return join(', ', @milters);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub set_spf_dkim_dmarc_status {
|
||||||
|
my ($spf_enabled, $dkim_enabled, $dmarc_enabled) = @_;
|
||||||
|
|
||||||
|
say STDERR "Setting configuration";
|
||||||
|
postconf_set(
|
||||||
|
smtpd_recipient_restrictions => smtpd_recipient_restrictions($spf_enabled),
|
||||||
|
smtpd_milters => smtpd_milters($dkim_enabled, $dmarc_enabled)
|
||||||
|
);
|
||||||
|
|
||||||
|
say STDERR "Reloading Postfix";
|
||||||
|
reload_postfix();
|
||||||
|
say STDERR "Done";
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/usr/bin/env perl
|
||||||
|
BEGIN { $ENV{DANCER_APPHANDLER} = 'PSGI';}
|
||||||
|
use Dancer2;
|
||||||
|
use FindBin '$RealBin';
|
||||||
|
use Plack::Runner;
|
||||||
|
|
||||||
|
# For some reason Apache SetEnv directives don't propagate
|
||||||
|
# correctly to the dispatchers, so forcing PSGI and env here
|
||||||
|
# is safer.
|
||||||
|
set apphandler => 'PSGI';
|
||||||
|
set environment => 'production';
|
||||||
|
|
||||||
|
my $psgi = path($RealBin, '..', 'bin', 'app.psgi');
|
||||||
|
die "Unable to read startup script: $psgi" unless -r $psgi;
|
||||||
|
|
||||||
|
Plack::Runner->run($psgi);
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env perl
|
||||||
|
BEGIN { $ENV{DANCER_APPHANDLER} = 'PSGI';}
|
||||||
|
use Dancer2;
|
||||||
|
use FindBin '$RealBin';
|
||||||
|
use Plack::Handler::FCGI;
|
||||||
|
|
||||||
|
# For some reason Apache SetEnv directives don't propagate
|
||||||
|
# correctly to the dispatchers, so forcing PSGI and env here
|
||||||
|
# is safer.
|
||||||
|
set apphandler => 'PSGI';
|
||||||
|
set environment => 'production';
|
||||||
|
|
||||||
|
my $psgi = path($RealBin, '..', 'bin', 'app.psgi');
|
||||||
|
my $app = do($psgi);
|
||||||
|
die "Unable to read startup script: $@" if $@;
|
||||||
|
my $server = Plack::Handler::FCGI->new(nproc => 5, detach => 1);
|
||||||
|
|
||||||
|
$server->run($app);
|
Loading…
Reference in New Issue