mirror of
https://github.com/ovh/the-bastion.git
synced 2025-01-04 06:27:11 +08:00
114 lines
3.5 KiB
Perl
Executable file
114 lines
3.5 KiB
Perl
Executable file
#! /usr/bin/env perl
|
|
# vim: set filetype=perl ts=4 sw=4 sts=4 et:
|
|
use common::sense;
|
|
|
|
use File::Basename;
|
|
use lib dirname(__FILE__) . '/../../../lib/perl';
|
|
use OVH::Result;
|
|
use OVH::Bastion;
|
|
use OVH::Bastion::Plugin qw( :DEFAULT help );
|
|
|
|
my $remainingOptions = OVH::Bastion::Plugin::begin(
|
|
argv => \@ARGV,
|
|
header => "setup TOTP for your account",
|
|
options => {
|
|
'no-confirm' => \my $noConfirm,
|
|
},
|
|
helptext => <<'EOF'
|
|
Setup an additional credential (TOTP) to access your account
|
|
|
|
Usage: --osh SCRIPT_NAME [--no-confirm]
|
|
|
|
--no-confirm Bypass the confirmation step for TOTP enrollment phase
|
|
EOF
|
|
);
|
|
|
|
my $fnret;
|
|
my @command;
|
|
|
|
if (OVH::Bastion::config('accountMFAPolicy')->value eq 'disabled') {
|
|
osh_exit('ERR_DISABLED_BY_POLICY',
|
|
"Sorry, Multi-Factor Authentication has been disabled by policy on this bastion");
|
|
}
|
|
|
|
if ($ENV{'OSH_IN_INTERACTIVE_SESSION'}) {
|
|
osh_exit('ERR_PRECONDITIONS_FAILED',
|
|
"For security reasons, this plugin can't be used in interactive mode.\nTo ensure you're the owner of the account, please call it the regular way (i.e. --osh $scriptName)"
|
|
);
|
|
}
|
|
|
|
# do the TOTP enrollment
|
|
|
|
my $TOTPProvider = OVH::Bastion::config("TOTPProvider")->value;
|
|
|
|
if ($TOTPProvider eq 'none') {
|
|
|
|
# unconfigured: as we don't know which provider we have, just error out
|
|
osh_exit(
|
|
R(
|
|
'ERR_CONFIGURATION_ERROR',
|
|
msg => "No TOTP provider has been enabled, please check with your sysadmin if this is unexpected"
|
|
)
|
|
);
|
|
}
|
|
elsif ($TOTPProvider eq 'google-authenticator') {
|
|
|
|
# first, check if the google-authenticator we have supports --issuer, if not, just omit it, it's not a deal-breaker
|
|
$fnret = OVH::Bastion::execute(cmd => ['google-authenticator', '-h'], must_succeed => 1);
|
|
$fnret or osh_exit($fnret);
|
|
my @additional_params;
|
|
if (grep { /--issuer/ } @{$fnret->value->{'stdout'}}) {
|
|
push @additional_params, "--issuer=" . OVH::Bastion::config('bastionName')->value;
|
|
}
|
|
if ($noConfirm && grep { /--no-confirm/ } @{$fnret->value->{'stdout'}}) {
|
|
push @additional_params, "--no-confirm";
|
|
}
|
|
|
|
@command = (
|
|
'script',
|
|
'-q',
|
|
'-c',
|
|
"google-authenticator -f -t -Q UTF8 -r 3 -R 15 -w 2 -D "
|
|
. join(" ", @additional_params)
|
|
. " -l $self -s $HOME/"
|
|
. OVH::Bastion::TOTP_GAUTH_FILENAME,
|
|
'/dev/null'
|
|
);
|
|
{
|
|
local $ENV{'SHELL'} = '/bin/sh';
|
|
$fnret = OVH::Bastion::execute(
|
|
cmd => \@command,
|
|
noisy_stderr => 1,
|
|
noisy_stdout => 1,
|
|
expects_stdin => 1,
|
|
is_binary => 1,
|
|
must_succeed => 1
|
|
);
|
|
}
|
|
|
|
if (!$fnret) {
|
|
osh_exit('ERR_TOTP_SETUP_FAILED', msg => "Couldn't setup TOTP for your account, try again!");
|
|
}
|
|
|
|
chmod 0400, $HOME . '/' . OVH::Bastion::TOTP_GAUTH_FILENAME;
|
|
}
|
|
elsif ($TOTPProvider eq 'duo') {
|
|
|
|
# nothing to do locally, appart from marking the user as TOTP-active, which is done after this block.
|
|
}
|
|
else {
|
|
# unknown provider, this shouldn't happen
|
|
osh_exit(
|
|
R(
|
|
'ERR_CONFIGURATION_ERROR',
|
|
msg => "An unknown TOTP provider has been provided, please check with your sysadmin."
|
|
)
|
|
);
|
|
}
|
|
|
|
# it worked, add the account to the proper system group
|
|
@command = qw{ sudo -n -u root -- /usr/bin/env perl -T };
|
|
push @command, $OVH::Bastion::BASEPATH . '/bin/helper/osh-selfMFASetupTOTP';
|
|
push @command, '--account', $self;
|
|
|
|
osh_exit(OVH::Bastion::helper(cmd => \@command));
|