spf-dkim-dmarc-demo/console/web-api/lib/Email/SpoofingDemo/Web.pm

208 lines
5.8 KiB
Perl
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package Email::SpoofingDemo::Web;
use Dancer2;
use JSON;
use REST::Client;
our $VERSION = '0.1';
sub call_api {
my ($method, $target, $url, $body_parameters) = @_;
my $host = config->{'api'}{$target};
die "Invalid target: $target" unless defined $host;
my $client = REST::Client->new();
$client->setHost($host);
$client->setTimeout(5);
$client->addHeader('Accept' => 'application/json');
$client->addHeader('Content-Type' => 'application/json');
my $body_data;
$body_data = encode_json($body_parameters) if defined $body_parameters;
$client->request($method, $url, $body_data);
my $status = $client->responseCode();
if ($status =~ /^2\d\d$/) {
my $response;
if ($client->responseContent() ne '') {
$response = decode_json($client->responseContent());
}
return ($response, $status);
}
else {
warn "API request returned $status";
return ($client->responseContent(), $status);
}
}
get '/' => sub {
template 'index' => { 'title' => 'Accueil' };
};
get '/dns/zone-edit/:zone' => sub {
my $zone = route_parameters->get('zone');
if (defined $zone and not (grep { $_ eq $zone } @{config->{'editable_zones'}})) {
pass;
}
my $zone_contents;
if (defined $zone) {
my ($response, $status) = call_api(GET => 'dns', "/zone/${zone}/file");
$zone_contents = $response->{contents};
}
template 'dns/zone-edit' => {
'title' => 'Éditeur de zone DNS',
'zone_to_edit' => $zone // '',
'zone_contents' => $zone_contents // '',
};
};
post '/dns/zone-edit/:zone' => sub {
my $zone = route_parameters->{'zone'};
unless (grep { $_ eq $zone } @{config->{'editable_zones'}}) {
pass;
}
my $contents = body_parameters->{'zone-contents'};
my (undef, $status) = call_api(PUT => 'dns', "/zone/${zone}/file", { contents => $contents });
my $success = ($status eq '200') ? 'success' : 'failure';
redirect "/dns/zone-edit/$zone?success=$success", 303;
};
get '/sender/dkim-keys' => sub {
my ($installed_keys, $status) = call_api(GET => 'sender', '/installed-keys');
($status eq '200') or die "API returned $status";
template 'sender/dkim-keys' => {
active_role => 'sender',
title => 'Gestion des clefs DKIM',
installed_keys => $installed_keys,
};
};
get '/dkim-generator/sender' => sub {
template 'dkim-generator/sender' => {
title => 'Générateur de clefs DKIM'
};
};
post '/dkim-generator/sender' => sub {
my $api_params = {
domain => body_parameters->get('domain'),
selector => body_parameters->get('selector'),
key_size => body_parameters->get('key-size')
};
my ($response, $status) = call_api(POST => 'sender', '/generate-dkim-key', $api_params);
($status eq 200) or die "API returned $status";
template 'dkim-generator/sender' => {
title => 'Générateur de clefs DKIM',
txt_record => $response->{'txt_record'}
};
};
get '/attacker/spoof' => sub {
my ($config, $status) = call_api(GET => 'attacker', '/config');
($status eq 200) or die "Could not get attackers configuration";
template 'attacker/spoof' => {
title => 'Usurpateur didentité de courriel',
default_helo => $config->{default_helo},
my_mail_from => $config->{my_mail_from},
scenarios => $config->{templates}
};
};
post '/attacker/spoof' => sub {
my $scenario = body_parameters->get('scenario');
my $replace_mail_from = (body_parameters->get('rfc5321-mailfrom') eq 'replace');
my $helo = body_parameters->get('helo');
my %api_params = (
scenario => $scenario,
replace_mail_from => ($replace_mail_from ? JSON::true : JSON::false),
helo => $helo
);
my ($logs, $status) = call_api(POST => 'attacker', '/spoof', \%api_params);
deferred 'logs' => $logs;
deferred 'selected_scenario' => $scenario;
deferred 'replace_mail_from' => $replace_mail_from;
redirect '/attacker/spoof', 303;
};
get '/sender/send-email' => sub {
my %template_params = (
title => 'Envoi de messages légitimes',
email_data => [
{
what => 'Confirmation de commande',
from => 'support@expediteur.example',
url => 'confirmation_email'
},
{
what => 'Newsletter',
from => 'info@newsletter.expediteur.example',
url => 'newsletter'
}
]
);
my $success = query_parameters->get('success');
if (defined $success) {
$template_params{success} = ($success eq 'success') ? 'success' : 'failure';
}
template 'sender/send-email' => \%template_params;
};
get '/recipient/settings' => sub {
my ($system_status, $http_code) = call_api(GET => 'recipient', '/status');
die if $http_code ne '200';
template 'recipient/settings' => {
title => 'Paramètres du système destinataire',
system_status => $system_status
};
};
post '/recipient/settings' => sub {
my %api_params = map {
$_ => body_parameters->{"$_-status"} ? 'enabled' : 'disabled'
} qw(spf dkim dmarc);
my (undef, $status) = call_api(PUT => 'recipient', '/status', \%api_params);
my $success = ($status eq 200) ? 'success' : 'failure';
redirect "/recipient/settings?success=$success", 303;
};
get '/sender/send-email/:email' => sub {
my $email = route_parameters->get('email');
my (undef, $response) = call_api(POST => 'sender', "/send-email/${email}");
my $success = ($response =~ /^2\d\d$/) ? 'success' : 'failure';
redirect "/sender/send-email?success=$success", 303;
};
get '/recipient/webmail' => sub {
template 'recipient/webmail' => {
title => 'Courriels'
};
};
any qr{.*} => sub {
template '404';
};
dance;
true;