enh: batch: detect when asked to start a plugin requiring MFA

This commit is contained in:
Stéphane Lesimple 2021-04-09 14:14:58 +00:00 committed by Stéphane Lesimple
parent 000ed4e8af
commit f609565fe8
4 changed files with 59 additions and 4 deletions

View file

@ -57,7 +57,12 @@ while (my $line = <STDIN>) {
$line =~ s/ --json[a-z-]*//g;
my @cmd = ($ENV{'SHELL'}, '-c', "--osh $line --json");
osh_info "--- launching command: $line";
$fnret = OVH::Bastion::helper(cmd => \@cmd);
do {
# notify that we're under batch mode, hence if plugin requires MFA,
# we'll require --proactive-mfa, see comment in lib/perl/OVH/Bastion.pm
local $ENV{'OSH_BATCH'} = 1;
$fnret = OVH::Bastion::helper(cmd => \@cmd);
};
if (!$fnret) {
osh_warn "--- command failed!";
}

View file

@ -1006,6 +1006,14 @@ sub do_pamtester {
return R('ERR_MISSING_PARAMETER', msg => "Missing mandatory arguments 'sysself' or 'self'");
}
# if we're being called as part of the batch plugin, OSH_BATCH will be set and it means
# we can't grab the term, so pam can't set raw mode to avoid local echo, and it could end
# up having passwords typed by the user displayed on screen. In that case, refuse to do it,
# and return an error to our caller.
if ($ENV{'OSH_BATCH'}) {
return R('KO_MFA_TERM_NOT_RAW', msg => "MFA is required for this action, but we're running under batch mode, please use --proactive-mfa");
}
# use system() instead of OVH::Bastion::execute() because we need it to grab the term
my $pamtries = 3;
while (1) {
@ -1017,11 +1025,11 @@ sub do_pamtester {
$pamsysret = system('pamtester', 'sshd', $sysself, 'authenticate');
}
if ($pamsysret < 0) {
return R('KO_MFA_FAILED', msg => "MFA is required for this host, but this bastion is missing the `pamtester' tool, aborting");
return R('KO_MFA_FAILED', msg => "MFA is required for this action, but this bastion is missing the `pamtester' tool, aborting");
}
elsif ($pamsysret != 0) {
if (--$pamtries <= 0) {
return R('KO_MFA_FAILED', msg => "Sorry, but Multi-Factor Authentication failed, I can't connect you to this host");
return R('KO_MFA_FAILED', msg => "Sorry, but Multi-Factor Authentication failed, couldn't complete the requested action");
}
next;
}

View file

@ -79,7 +79,7 @@ testsuite_selfaccesses()
# batch plugin
script one "printf \"%b\\n\" \"info\\naccountInfo --account $account0\\nselfListEgressKeys\" | $a1 --osh batch"
script batch_one "printf \"%b\\n\" \"info\\naccountInfo --account $account0\\nselfListEgressKeys\" | $a1 --osh batch"
retvalshouldbe 0
json .command batch .error_code OK
json '.value[0].result.error_code' OK '.value[0].command' info '.value[0].result.value.account' "$account1"

View file

@ -66,6 +66,48 @@ testsuite_mfa()
json .command groupList .error_code OK_EMPTY
fi
# batch trying to start a plugin that requires mfa => should get an error
if [ "${capabilities[pamtester]}" = 1 ]; then
success batch_set_mfa $r0 "echo '{\\\"mfa_required\\\":\\\"any\\\"}' \> $opt_remote_etc_bastion/plugin.info.conf \; chmod o+r $opt_remote_etc_bastion/plugin.info.conf"
if [ "${capabilities[mfa]}" = 1 ] || [ "${capabilities[mfa-password]}" = 1 ]; then
script batch_try_mfa "echo 'set timeout 30; \
spawn $a4 --osh batch; \
expect \":\" { sleep 0.2; send \"$a4_password\\n\"; }; \
expect \"waiting for input\" { sleep 0.2; send \"info\\n\"; }; \
expect \"failed\" { sleep 0.2; send \"quit\\n\"; }; \
expect eof; \
lassign [wait] pid spawnid value value; \
exit \$value' | expect -f -"
retvalshouldbe 0
contain "launching command: info"
contain "entering MFA phase"
contain "please use --proactive-mfa"
nocontain "Your alias to connect"
json .command batch .error_code OK '.value[0].command' info '.value[0].result.error_code' KO_MFA_FAILED
else
script batch_try_mfa "echo 'set timeout 30; \
spawn $a4 --osh batch; \
expect \"waiting for input\" { sleep 0.2; send \"info\\n\"; }; \
expect \"failed\" { sleep 0.2; send \"quit\\n\"; }; \
expect eof; \
lassign [wait] pid spawnid value value; \
exit \$value' | expect -f -"
retvalshouldbe 0
contain "launching command: info"
contain "entering MFA phase"
contain "please use --proactive-mfa"
nocontain "Your alias to connect"
json .command batch .error_code OK '.value[0].command' info '.value[0].result.error_code' KO_MFA_FAILED
fi
success batch_unset_mfa $r0 "rm -f $opt_remote_etc_bastion/plugin.info.conf"
fi
# /batch
if [ "${capabilities[pamtester]}" = 1 ]; then
grant groupCreate