mirror of
https://github.com/ovh/the-bastion.git
synced 2024-09-20 15:05:58 +08:00
feat: groupModify: add --idle-lock-timeout and --idle-kill-timeout for group-specific timeouts
This commit is contained in:
parent
6fb528ccf1
commit
46a01a546a
|
@ -41,7 +41,8 @@ if echo "$DISTRO_LIKE" | grep -q -w debian; then
|
|||
if [ "$(uname -m)" = armv7l ]; then
|
||||
wanted_list="$wanted_list wget"
|
||||
fi
|
||||
[ "$opt_dev" = 1 ] && wanted_list="$wanted_list libperl-critic-perl perltidy shellcheck openssl"
|
||||
[ "$opt_dev" = 1 ] && wanted_list="$wanted_list libperl-critic-perl libtest-deep-perl perltidy shellcheck openssl wget"
|
||||
|
||||
if { [ "$LINUX_DISTRO" = debian ] && [ "$DISTRO_VERSION_MAJOR" -lt 9 ]; } ||
|
||||
{ [ "$LINUX_DISTRO" = ubuntu ] && [ "$DISTRO_VERSION_MAJOR" -le 16 ]; }; then
|
||||
wanted_list="$wanted_list openssh-blacklist openssh-blacklist-extra"
|
||||
|
@ -70,7 +71,7 @@ elif echo "$DISTRO_LIKE" | grep -q -w rhel; then
|
|||
expect openssh-server netcat bash perl-CGI perl-Test-Simple passwd \
|
||||
cracklib-dicts perl-Time-Piece perl-Time-HiRes diffutils \
|
||||
perl-Sys-Syslog pamtester google-authenticator qrencode-libs \
|
||||
perl-LWP-Protocol-https findutils tar"
|
||||
perl-LWP-Protocol-https perl-Test-Deep findutils tar"
|
||||
if [ "$DISTRO_VERSION_MAJOR" = 7 ]; then
|
||||
wanted_list="$wanted_list fortune-mod coreutils util-linux"
|
||||
else
|
||||
|
@ -78,6 +79,7 @@ elif echo "$DISTRO_LIKE" | grep -q -w rhel; then
|
|||
fi
|
||||
[ "$opt_syslogng" = 1 ] && wanted_list="$wanted_list syslog-ng"
|
||||
|
||||
|
||||
if [ "$opt_install" = 1 ]; then
|
||||
if [ "$DISTRO_VERSION_MAJOR" = 8 ]; then
|
||||
# in December 2020, they added "-Linux" to their repo name, so trying both combinations
|
||||
|
@ -115,7 +117,7 @@ elif echo "$DISTRO_LIKE" | grep -q -w suse; then
|
|||
perl-Net-Server cryptsetup mosh expect openssh \
|
||||
coreutils netcat-openbsd bash perl-CGI iputils \
|
||||
perl-Time-HiRes perl-Unix-Syslog hostname perl-LWP-Protocol-https \
|
||||
google-authenticator-libpam tar"
|
||||
google-authenticator-libpam tar perl-Test-Deep"
|
||||
[ "$opt_syslogng" = 1 ] && wanted_list="$wanted_list syslog-ng"
|
||||
|
||||
if [ "$opt_install" = 1 ]; then
|
||||
|
@ -129,7 +131,8 @@ elif echo "$DISTRO_LIKE" | grep -q -w suse; then
|
|||
elif [ "$OS_FAMILY" = FreeBSD ]; then
|
||||
wanted_list="base64 coreutils rsync bash sudo pamtester p5-JSON p5-JSON-XS gnupg \
|
||||
p5-common-sense p5-DateTime p5-Net-IP p5-DBD-SQLite p5-Net-Netmask lsof \
|
||||
p5-Term-ReadKey expect fping p5-Net-Server p5-CGI p5-LWP-Protocol-https"
|
||||
p5-Term-ReadKey expect fping p5-Net-Server p5-CGI p5-LWP-Protocol-https \
|
||||
p5-Test-Deep"
|
||||
install_cmd="pkg add"
|
||||
installed=""
|
||||
for i in $wanted_list
|
||||
|
|
|
@ -18,13 +18,15 @@ use OVH::Result;
|
|||
# Fetch command options
|
||||
my $fnret;
|
||||
my ($result, @optwarns);
|
||||
my ($group, $mfaRequired, $ttl);
|
||||
my ($group, $mfaRequired, $ttl, $idleLockTimeout, $idleKillTimeout);
|
||||
eval {
|
||||
local $SIG{__WARN__} = sub { push @optwarns, shift };
|
||||
$result = GetOptions(
|
||||
"group=s" => sub { $group //= $_[1] },
|
||||
"mfa-required=s" => \$mfaRequired,
|
||||
"guest-ttl-limit=i" => \$ttl,
|
||||
"group=s" => sub { $group //= $_[1] },
|
||||
"mfa-required=s" => \$mfaRequired,
|
||||
"guest-ttl-limit=i" => \$ttl,
|
||||
"idle-lock-timeout=i" => \$idleLockTimeout,
|
||||
"idle-kill-timeout=i" => \$idleKillTimeout,
|
||||
);
|
||||
};
|
||||
if ($@) { die $@ }
|
||||
|
@ -40,8 +42,9 @@ if (!$group) {
|
|||
HEXIT('ERR_MISSING_PARAMETER', msg => "Missing argument 'group'");
|
||||
}
|
||||
|
||||
if (!$mfaRequired && !defined $ttl) {
|
||||
HEXIT('ERR_MISSING_PARAMETER', msg => "Missing argument 'mfa-required' or 'guest-ttl-limit'");
|
||||
if (!$mfaRequired && !defined $ttl && !defined $idleLockTimeout && !defined $idleKillTimeout) {
|
||||
HEXIT('ERR_MISSING_PARAMETER',
|
||||
msg => "Missing argument 'mfa-required', 'guest-ttl-limit', 'idle-lock-timeout' or 'idle-kill-timeout'");
|
||||
}
|
||||
|
||||
#<HEADER
|
||||
|
@ -88,6 +91,69 @@ if (defined $mfaRequired) {
|
|||
}
|
||||
}
|
||||
|
||||
my %idleTimeout = (
|
||||
lock => {
|
||||
name => "idle lock timeout",
|
||||
key => \%{OVH::Bastion::OPT_GROUP_IDLE_LOCK_TIMEOUT()},
|
||||
value => $idleLockTimeout,
|
||||
},
|
||||
kill => {
|
||||
name => "idle kill timeout",
|
||||
key => \%{OVH::Bastion::OPT_GROUP_IDLE_KILL_TIMEOUT()},
|
||||
value => $idleKillTimeout,
|
||||
},
|
||||
);
|
||||
|
||||
foreach my $item (keys %idleTimeout) {
|
||||
next if !defined $idleTimeout{$item}{'value'};
|
||||
|
||||
osh_info "Modifying " . $idleTimeout{$item}{'name'} . " policy of group...";
|
||||
if ($idleTimeout{$item}{'value'} >= 0) {
|
||||
$fnret = OVH::Bastion::group_config(
|
||||
group => $group,
|
||||
%{$idleTimeout{$item}{'key'}}, value => $idleTimeout{$item}{'value'}
|
||||
);
|
||||
if ($fnret) {
|
||||
if ($idleTimeout{$item}{'value'} == 0) {
|
||||
osh_info "... done, this group's " . $idleTimeout{$item}{'name'} . " policy is now set to: disabled";
|
||||
}
|
||||
else {
|
||||
osh_info "... done, this group is now configured to use a "
|
||||
. $idleTimeout{$item}{'name'}
|
||||
. " policy of "
|
||||
. OVH::Bastion::duration2human(seconds => $idleTimeout{$item}{'value'})->value->{'human'};
|
||||
}
|
||||
}
|
||||
else {
|
||||
osh_warn "... error while setting the group-specific "
|
||||
. $idleTimeout{$item}{'name'}
|
||||
. " policy ("
|
||||
. $fnret->msg . ")";
|
||||
warn_syslog "Error setting the group-specific "
|
||||
. $idleTimeout{$item}{'name'}
|
||||
. " policy of $group ("
|
||||
. $fnret->msg . ")";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$fnret = OVH::Bastion::group_config(group => $group, %{$idleTimeout{$item}{'key'}}, delete => 1);
|
||||
if ($fnret) {
|
||||
osh_info "... done, this group will now use the global " . $idleTimeout{$item}{'name'} . " policy";
|
||||
}
|
||||
else {
|
||||
osh_warn "... error while removing the group-specific "
|
||||
. $idleTimeout{$item}{'name'}
|
||||
. " policy ("
|
||||
. $fnret->msg . ")";
|
||||
warn_syslog "Error removing the group-specific "
|
||||
. $idleTimeout{$item}{'name'}
|
||||
. " policy of $group ("
|
||||
. $fnret->msg . ")";
|
||||
}
|
||||
}
|
||||
$result{$idleTimeout{$item}{'key'}} = $fnret;
|
||||
}
|
||||
|
||||
if (defined $ttl) {
|
||||
osh_info "Modifying guest TTL limit policy of group...";
|
||||
if ($ttl > 0) {
|
||||
|
|
|
@ -12,19 +12,33 @@ my $remainingOptions = OVH::Bastion::Plugin::begin(
|
|||
argv => \@ARGV,
|
||||
header => "modify the configuration of a group",
|
||||
options => {
|
||||
"group=s" => \my $group,
|
||||
"mfa-required=s" => \my $mfaRequired,
|
||||
"guest-ttl-limit=s" => \my $ttl,
|
||||
"group=s" => \my $group,
|
||||
"mfa-required=s" => \my $mfaRequired,
|
||||
"idle-lock-timeout=s" => \my $idleLockTimeout,
|
||||
"idle-kill-timeout=s" => \my $idleKillTimeout,
|
||||
"guest-ttl-limit=s" => \my $ttl,
|
||||
},
|
||||
helptext => <<'EOF',
|
||||
Modify the configuration of a group
|
||||
|
||||
Usage: --osh SCRIPT_NAME --group GROUP [--mfa-required password|totp|any|none] [--guest-ttl-limit DURATION]
|
||||
|
||||
--group GROUP Name of the group to modify
|
||||
--mfa-required password|totp|any|none Enforce UNIX password requirement, or TOTP requirement, or any MFA requirement, when connecting to a server of the group
|
||||
--guest-ttl-limit DURATION This group will enforce TTL setting, on guest access creation, to be set, and not to a higher value than DURATION,
|
||||
set to zero to allow guest accesses creation without any TTL set (default)
|
||||
--group GROUP Name of the group to modify
|
||||
--mfa-required password|totp|any|none Enforce UNIX password requirement, or TOTP requirement, or any MFA requirement, when connecting to a server of the group
|
||||
--idle-lock-timeout DURATION|0|-1 Overrides the global setting (`idleLockTimeout`), to the specified duration. If set to 0, disables `idleLockTimeout` for
|
||||
this group. If set to -1, remove this group override and use the global setting instead.
|
||||
--idle-kill-timeout DURATION|0|-1 Overrides the global setting (`idleKillTimeout`), to the specified duration. If set to 0, disables `idleKillTimeout` for
|
||||
this group. If set to -1, remove this group override and use the global setting instead.
|
||||
--guest-ttl-limit DURATION This group will enforce TTL setting, on guest access creation, to be set, and not to a higher value than DURATION,
|
||||
set to zero to allow guest accesses creation without any TTL set (default)
|
||||
|
||||
Note that `--idle-lock-timeout` and `--idle-kill-timeout` will NOT be applied for catch-all groups (having 0.0.0.0/0 in their server list).
|
||||
|
||||
If a server is in exactly one group an account is a member of, then its values of `--idle-lock-timeout` and `--idle-kill-timeout`, if set,
|
||||
will prevail over the global setting. The global setting can be seen with `--osh info`.
|
||||
|
||||
Otherwise, the most restrictive setting (i.e. the one with the lower strictly positive duration) between
|
||||
all the considered groups and the global setting, will be used.
|
||||
EOF
|
||||
);
|
||||
|
||||
|
@ -34,14 +48,22 @@ if (!$group) {
|
|||
help();
|
||||
osh_exit 'ERR_MISSING_PARAMETER', "Missing mandatory parameter 'group'";
|
||||
}
|
||||
if (!$mfaRequired && !defined $ttl) {
|
||||
if (!$mfaRequired && !defined $ttl && !defined $idleLockTimeout && !defined $idleKillTimeout) {
|
||||
help();
|
||||
osh_exit 'ERR_MISSING_PARAMETER', "Nothing to modify";
|
||||
}
|
||||
if (defined $ttl) {
|
||||
$fnret = OVH::Bastion::is_valid_ttl(ttl => $ttl);
|
||||
$fnret or osh_exit $fnret;
|
||||
$ttl = $fnret->value->{'seconds'};
|
||||
foreach my $item (\$ttl, \$idleLockTimeout, \$idleKillTimeout) {
|
||||
if (defined $$item && $$item != -1) {
|
||||
$fnret = OVH::Bastion::is_valid_ttl(ttl => $$item);
|
||||
$fnret or osh_exit $fnret;
|
||||
$$item = $fnret->value->{'seconds'};
|
||||
}
|
||||
}
|
||||
|
||||
# ttl doesn't allow -1 as a valid value, check that
|
||||
if ($ttl == -1) {
|
||||
osh_exit 'ERR_INVALID_PARAMETER',
|
||||
"Invalid TTL (-1), expected an amount of seconds, or a duration string such as '2d8h15m'";
|
||||
}
|
||||
|
||||
$fnret = OVH::Bastion::is_valid_group_and_existing(group => $group, groupType => 'key');
|
||||
|
@ -66,5 +88,7 @@ push @command, $OVH::Bastion::BASEPATH . '/bin/helper/osh-groupModify';
|
|||
push @command, '--group', $group;
|
||||
push @command, '--mfa-required', $mfaRequired if $mfaRequired;
|
||||
push @command, '--guest-ttl-limit', $ttl if defined $ttl;
|
||||
push @command, '--idle-lock-timeout', $idleLockTimeout if defined $idleLockTimeout;
|
||||
push @command, '--idle-kill-timeout', $idleKillTimeout if defined $idleKillTimeout;
|
||||
|
||||
osh_exit OVH::Bastion::helper(cmd => \@command);
|
||||
|
|
|
@ -176,11 +176,25 @@ if ( OVH::Bastion::is_group_owner(group => $shortGroup, account => $self, supe
|
|||
}
|
||||
|
||||
$fnret = OVH::Bastion::group_config(group => $group, key => 'guest_ttl_limit');
|
||||
if ($fnret) {
|
||||
if ($fnret && defined $fnret->value && $fnret->value =~ /^\d+$/) {
|
||||
osh_warn "Guest TTL enforced: guest accesses must have a TTL with a maximum duration of "
|
||||
. OVH::Bastion::duration2human(seconds => $fnret->value)->value->{'duration'};
|
||||
$result_hash->{'guest_ttl_limit'} = $fnret->value;
|
||||
}
|
||||
|
||||
$fnret = OVH::Bastion::group_config(group => $group, %{OVH::Bastion::OPT_GROUP_IDLE_KILL_TIMEOUT()});
|
||||
if ($fnret && defined $fnret->value && $fnret->value =~ /^-?\d+$/) {
|
||||
osh_warn "Specific idle kill timeout: idle sessions on servers of this group will be cut after "
|
||||
. OVH::Bastion::duration2human(seconds => $fnret->value)->value->{'duration'};
|
||||
$result_hash->{'idle_kill_timeout'} = $fnret->value;
|
||||
}
|
||||
|
||||
$fnret = OVH::Bastion::group_config(group => $group, => %{OVH::Bastion::OPT_GROUP_IDLE_LOCK_TIMEOUT()});
|
||||
if ($fnret && defined $fnret->value && $fnret->value =~ /^-?\d+$/) {
|
||||
osh_warn "Specific idle lock timeout: idle sessions on servers of this group will be locked after "
|
||||
. OVH::Bastion::duration2human(seconds => $fnret->value)->value->{'duration'};
|
||||
$result_hash->{'idle_lock_timeout'} = $fnret->value;
|
||||
}
|
||||
}
|
||||
else {
|
||||
osh_info "You should ask him/her/them if you think you need access for your work tasks.";
|
||||
|
|
|
@ -1172,7 +1172,7 @@ if ($osh_debug) {
|
|||
}
|
||||
|
||||
# build ttyrec command that'll prefix the real command
|
||||
my $ttyrec_fnret = OVH::Bastion::build_ttyrec_cmdline(
|
||||
my $ttyrec_fnret = OVH::Bastion::build_ttyrec_cmdline_part1of2(
|
||||
ip => $ip,
|
||||
port => $port,
|
||||
user => $user,
|
||||
|
@ -1310,6 +1310,60 @@ else {
|
|||
|
||||
push @command, '/usr/bin/ssh', $ip, '-l', $user, '-p', $port;
|
||||
|
||||
# before listing the accesses and the keys they use, first compute the correct
|
||||
# idle-kill-timeout and idle-lock-timeout value, as these can be overriden for group accesses,
|
||||
# see the help of groupModify command for details on the algorithm's logic, it is also commented below
|
||||
# First, we init the vars with the global setting.
|
||||
my %idleTimeout = (
|
||||
kill => OVH::Bastion::config("idleKillTimeout")->value,
|
||||
lock => OVH::Bastion::config("idleLockTimeout")->value,
|
||||
);
|
||||
|
||||
# Then, gather all the timeouts overrides that may be defined for the matching groups
|
||||
my %idleTimeoutsOverride = (kill => [], lock => []);
|
||||
foreach my $access (@accessList) {
|
||||
next if ($access->{'type'} !~ /^group/);
|
||||
push @{$idleTimeoutsOverride{'kill'}}, $access->{'idleKillTimeout'}
|
||||
if (defined $access->{'idleKillTimeout'} && $access->{'size'} != 2**32);
|
||||
push @{$idleTimeoutsOverride{'lock'}}, $access->{'idleLockTimeout'}
|
||||
if (defined $access->{'idleLockTimeout'} && $access->{'size'} != 2**32);
|
||||
}
|
||||
|
||||
# Now, decide what to apply for each timeout setting
|
||||
foreach my $timeout (qw{ kill lock }) {
|
||||
if (@{$idleTimeoutsOverride{$timeout}} == 0) {
|
||||
|
||||
# zero override, we'll use the global setting,
|
||||
# $idleTimeout{$timeout} is already inited to the global setting
|
||||
osh_debug("idle_timeout: no override for $timeout, using global setting");
|
||||
}
|
||||
elsif (@{$idleTimeoutsOverride{$timeout}} == 1) {
|
||||
|
||||
# exactly one match, use it
|
||||
$idleTimeout{$timeout} = $idleTimeoutsOverride{$timeout}[0];
|
||||
osh_debug("idle_timeout: exactly one override for $timeout, using it");
|
||||
}
|
||||
else {
|
||||
osh_debug("idle_timeout: more than one override for $timeout, using the most restrictive one");
|
||||
|
||||
# more than one match, so we add the global setting to the pile
|
||||
push @{$idleTimeoutsOverride{$timeout}}, $idleTimeout{$timeout};
|
||||
|
||||
# and choose the most restrictive one (lowest positive integer)
|
||||
$idleTimeout{$timeout} = (sort { $a <=> $b } grep { $_ > 0 } @{$idleTimeoutsOverride{$timeout}})[0];
|
||||
}
|
||||
osh_debug("idle_timeout: finally using " . $idleTimeout{$timeout} . " for $timeout");
|
||||
}
|
||||
|
||||
# adjust the ttyrec cmdline with these parameters
|
||||
$ttyrec_fnret = OVH::Bastion::build_ttyrec_cmdline_part2of2(
|
||||
input => $ttyrec_fnret->value,
|
||||
idleLockTimeout => $idleTimeout{'lock'},
|
||||
idleKillTimeout => $idleTimeout{'kill'}
|
||||
);
|
||||
main_exit(OVH::Bastion::EXIT_TTYREC_CMDLINE_FAILED, "ttyrec_failed", $ttyrec_fnret->msg) if !$ttyrec_fnret;
|
||||
@ttyrec = @{$ttyrec_fnret->value->{'cmd'}};
|
||||
|
||||
my @keysToTry;
|
||||
print " will try the following accesses you have: \n" unless $quiet;
|
||||
foreach my $access (@accessList) {
|
||||
|
|
|
@ -119,6 +119,9 @@ use constant {
|
|||
OPT_ACCOUNT_OSH_ONLY => 'osh_only',
|
||||
|
||||
OPT_ACCOUNT_MAX_INACTIVE_DAYS => {key => 'max_inactive_days', public => 1},
|
||||
|
||||
OPT_GROUP_IDLE_LOCK_TIMEOUT => {key => 'idle_lock_timeout'},
|
||||
OPT_GROUP_IDLE_KILL_TIMEOUT => {key => 'idle_kill_timeout'},
|
||||
};
|
||||
|
||||
###########
|
||||
|
@ -991,6 +994,19 @@ sub get_passfile {
|
|||
|
||||
sub build_ttyrec_cmdline {
|
||||
my %params = @_;
|
||||
my $fnret = build_ttyrec_cmdline_part1of2(%params);
|
||||
$fnret or return $fnret;
|
||||
|
||||
# for this simple version, use global timeout values
|
||||
return build_ttyrec_cmdline_part2of2(
|
||||
input => $fnret->value,
|
||||
idleLockTimeout => OVH::Bastion::config("idleLockTimeout")->value,
|
||||
idleKillTimeout => OVH::Bastion::config("idleKillTimeout")->value
|
||||
);
|
||||
}
|
||||
|
||||
sub build_ttyrec_cmdline_part1of2 {
|
||||
my %params = @_;
|
||||
|
||||
if (!$params{'home'}) {
|
||||
return R('ERR_MISSING_PARAMETER', msg => "Missing home parameter");
|
||||
|
@ -1041,11 +1057,6 @@ sub build_ttyrec_cmdline {
|
|||
}
|
||||
|
||||
# forge ttyrec command
|
||||
my $idleKillTimeout = OVH::Bastion::config('idleKillTimeout')->value;
|
||||
my $idleLockTimeout = OVH::Bastion::config('idleLockTimeout')->value;
|
||||
my $warnBeforeLockSeconds = OVH::Bastion::config('warnBeforeLockSeconds')->value;
|
||||
my $warnBeforeKillSeconds = OVH::Bastion::config('warnBeforeKillSeconds')->value;
|
||||
|
||||
my @ttyrec = ('ttyrec', '-f', $saveFile, '-F', $saveFileFormat);
|
||||
push @ttyrec, '-v' if $params{'debug'};
|
||||
push @ttyrec, '-T', 'always' if $params{'tty'};
|
||||
|
@ -1060,19 +1071,45 @@ sub build_ttyrec_cmdline {
|
|||
osh_debug("Account is immune to idle, not adding ttyrec commandline parameters");
|
||||
}
|
||||
else {
|
||||
push @ttyrec, '-k', $idleKillTimeout if $idleKillTimeout;
|
||||
push @ttyrec, '-t', $idleLockTimeout if $idleLockTimeout;
|
||||
push @ttyrec, '-s', "To unlock, use '--osh unlock' from another console" if $idleLockTimeout;
|
||||
my $warnBeforeLockSeconds = OVH::Bastion::config('warnBeforeLockSeconds')->value;
|
||||
my $warnBeforeKillSeconds = OVH::Bastion::config('warnBeforeKillSeconds')->value;
|
||||
push @ttyrec, '--warn-before-lock', $warnBeforeLockSeconds if $warnBeforeLockSeconds;
|
||||
push @ttyrec, '--warn-before-kill', $warnBeforeKillSeconds if $warnBeforeKillSeconds;
|
||||
}
|
||||
|
||||
my $ttyrecAdditionalParameters = OVH::Bastion::config('ttyrecAdditionalParameters')->value;
|
||||
push @ttyrec, @$ttyrecAdditionalParameters if @$ttyrecAdditionalParameters;
|
||||
|
||||
return R('OK', value => {saveFile => $saveFile, cmd => \@ttyrec});
|
||||
}
|
||||
|
||||
# call this after build_ttyrec_cmdline_part1of2, don't forget to
|
||||
# pass part1of2's value output to part2of2's 'input' parameter
|
||||
sub build_ttyrec_cmdline_part2of2 {
|
||||
my %params = @_;
|
||||
|
||||
my $input = $params{'input'};
|
||||
if (!$input) {
|
||||
return R('ERR_MISSING_PARAMETER', msg => "Missing 'input' parameter in build_ttyrec_cmdline_part2of2");
|
||||
}
|
||||
|
||||
if (!$input->{'cmd'}) {
|
||||
return R('ERR_MISSING_PARAMETER', msg => "Missing 'input->cmd' parameter in build_ttyrec_cmdline_part2of2");
|
||||
}
|
||||
|
||||
my @cmd = @{$input->{'cmd'}};
|
||||
|
||||
my $idleLockTimeout = $params{'idleLockTimeout'};
|
||||
my $idleKillTimeout = $params{'idleKillTimeout'};
|
||||
|
||||
push @cmd, '-k', $idleKillTimeout if $idleKillTimeout;
|
||||
push @cmd, '-t', $idleLockTimeout if $idleLockTimeout;
|
||||
push @cmd, '-s', "To unlock, use '--osh unlock' from another console" if $idleLockTimeout;
|
||||
|
||||
my $ttyrecAdditionalParameters = OVH::Bastion::config('ttyrecAdditionalParameters')->value;
|
||||
push @cmd, @$ttyrecAdditionalParameters if @$ttyrecAdditionalParameters;
|
||||
|
||||
$input->{'cmd'} = \@cmd;
|
||||
return R('OK', value => $input);
|
||||
}
|
||||
|
||||
sub do_pamtester {
|
||||
my %params = @_;
|
||||
my $sysself = $params{'sysself'};
|
||||
|
|
|
@ -842,36 +842,42 @@ sub is_access_granted {
|
|||
# 3/3 fill up keys and other metadata info (mfa, idle lock/kill timeout) if asked to
|
||||
if ($details) {
|
||||
foreach my $access (@grants) {
|
||||
undef $fnret;
|
||||
my $mfaFnret;
|
||||
my %data;
|
||||
if ($access->{'type'} =~ /^group/ and $access->{'group'}) {
|
||||
$fnret = OVH::Bastion::get_group_keys(
|
||||
$data{'keys'} = OVH::Bastion::get_group_keys(
|
||||
group => $access->{'group'},
|
||||
listOnly => $listOnly,
|
||||
noexec => $noexec,
|
||||
forceKey => $access->{'forceKey'}
|
||||
);
|
||||
$mfaFnret = OVH::Bastion::group_config(key => "mfa_required", group => $access->{'group'});
|
||||
$data{'mfa'} = OVH::Bastion::group_config(key => "mfa_required", group => $access->{'group'});
|
||||
$data{'idle_lock_timeout'} = OVH::Bastion::group_config(%{OVH::Bastion::OPT_GROUP_IDLE_LOCK_TIMEOUT()},
|
||||
group => $access->{'group'});
|
||||
$data{'idle_kill_timeout'} = OVH::Bastion::group_config(%{OVH::Bastion::OPT_GROUP_IDLE_KILL_TIMEOUT()},
|
||||
group => $access->{'group'});
|
||||
}
|
||||
elsif ($access->{'type'} =~ /^personal/) {
|
||||
$fnret = OVH::Bastion::get_personal_account_keys(
|
||||
$data{'keys'} = OVH::Bastion::get_personal_account_keys(
|
||||
account => $sysaccount,
|
||||
listOnly => $listOnly,
|
||||
noexec => $noexec,
|
||||
forceKey => $access->{'forceKey'}
|
||||
);
|
||||
$mfaFnret = OVH::Bastion::account_config(key => "personal_egress_mfa_required", account => $sysaccount);
|
||||
$data{'mfa'} =
|
||||
OVH::Bastion::account_config(key => "personal_egress_mfa_required", account => $sysaccount);
|
||||
}
|
||||
else {
|
||||
# unknown access type? no key!
|
||||
warn_syslog("Unknown access type '" . $access->{'type'} . "' found, ignoring");
|
||||
}
|
||||
if ($fnret) {
|
||||
if ($data{'keys'}) {
|
||||
|
||||
# TODO implement $access->{forceKey} check to include only the proper key
|
||||
$access->{'keys'} = $fnret->value->{'keys'};
|
||||
$access->{'sortedKeys'} = $fnret->value->{'sortedKeys'};
|
||||
$access->{'mfaRequired'} = $mfaFnret->value if $mfaFnret;
|
||||
$access->{'keys'} = $data{'keys'}->value->{'keys'};
|
||||
$access->{'sortedKeys'} = $data{'keys'}->value->{'sortedKeys'};
|
||||
$access->{'mfaRequired'} = $data{'mfa'}->value if $data{'mfa'};
|
||||
$access->{'idleLockTimeout'} = $data{'idle_lock_timeout'}->value if $data{'idle_lock_timeout'};
|
||||
$access->{'idleKillTimeout'} = $data{'idle_kill_timeout'}->value if $data{'idle_kill_timeout'};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# vim: set filetype=perl ts=4 sw=4 sts=4 et:
|
||||
use common::sense;
|
||||
use Test::More;
|
||||
use Test::Deep;
|
||||
|
||||
use File::Basename;
|
||||
use lib dirname(__FILE__) . '/../../lib/perl';
|
||||
|
@ -46,6 +47,9 @@ OVH::Bastion::load_configuration(
|
|||
],
|
||||
bastionName => "mock",
|
||||
|
||||
idleLockTimeout => 17,
|
||||
idleKillTimeout => 29,
|
||||
|
||||
# all options below are bool, we'll test for their normalization
|
||||
enableSyslog => 1,
|
||||
enableGlobalAccessLog => JSON::true,
|
||||
|
@ -60,6 +64,98 @@ OVH::Bastion::load_configuration(
|
|||
);
|
||||
|
||||
# TESTS
|
||||
my $fnret;
|
||||
|
||||
$fnret = OVH::Bastion::build_ttyrec_cmdline(
|
||||
ip => "127.0.0.1",
|
||||
port => 7979,
|
||||
user => "randomuser",
|
||||
account => "bastionuser",
|
||||
uniqid => 'cafed00dcafe',
|
||||
home => "/home/randomuser",
|
||||
);
|
||||
cmp_deeply(
|
||||
$fnret->value->{'saveFile'},
|
||||
re(
|
||||
qr{^\Q/home/randomuser/ttyrec/127.0.0.1/20\E\d\d-\d\d-\d\d.\d\d\-\d\d\-\d\d\.\d{6}\Q.cafed00dcafe.bastionuser.randomuser.127.0.0.1.7979.ttyrec\E$}
|
||||
),
|
||||
"build_ttyrec_cmdline saveFile"
|
||||
);
|
||||
cmp_deeply(
|
||||
$fnret->value->{'cmd'},
|
||||
[
|
||||
'ttyrec',
|
||||
'-f',
|
||||
$fnret->value->{'saveFile'},
|
||||
'-F',
|
||||
'/home/randomuser/ttyrec/127.0.0.1/%Y-%m-%d.%H-%M-%S.#usec#.cafed00dcafe.bastionuser.randomuser.127.0.0.1.7979.ttyrec',
|
||||
'-k',
|
||||
29,
|
||||
'-t',
|
||||
17,
|
||||
'-s',
|
||||
"To unlock, use '--osh unlock' from another console",
|
||||
'-k',
|
||||
29,
|
||||
],
|
||||
"build_ttyrec_cmdline cmd"
|
||||
);
|
||||
|
||||
$fnret = OVH::Bastion::build_ttyrec_cmdline_part1of2(
|
||||
ip => "127.0.0.1",
|
||||
port => 7979,
|
||||
user => "randomuser",
|
||||
account => "bastionuser",
|
||||
uniqid => 'cafed00dcafe',
|
||||
home => "/home/randomuser",
|
||||
);
|
||||
cmp_deeply(
|
||||
$fnret->value->{'saveFile'},
|
||||
re(
|
||||
qr{^\Q/home/randomuser/ttyrec/127.0.0.1/20\E\d\d-\d\d-\d\d.\d\d\-\d\d\-\d\d\.\d{6}\Q.cafed00dcafe.bastionuser.randomuser.127.0.0.1.7979.ttyrec\E$}
|
||||
),
|
||||
"build_ttyrec_cmdline_part1of2 saveFile"
|
||||
);
|
||||
cmp_deeply(
|
||||
$fnret->value->{'cmd'},
|
||||
[
|
||||
'ttyrec',
|
||||
'-f',
|
||||
$fnret->value->{'saveFile'},
|
||||
'-F',
|
||||
'/home/randomuser/ttyrec/127.0.0.1/%Y-%m-%d.%H-%M-%S.#usec#.cafed00dcafe.bastionuser.randomuser.127.0.0.1.7979.ttyrec'
|
||||
],
|
||||
"build_ttyrec_cmdline_part1of2 cmd"
|
||||
);
|
||||
$fnret = OVH::Bastion::build_ttyrec_cmdline_part2of2(
|
||||
input => $fnret->value,
|
||||
idleKillTimeout => 88,
|
||||
idleLockTimeout => 99,
|
||||
);
|
||||
cmp_deeply(
|
||||
$fnret->value->{'saveFile'},
|
||||
re(
|
||||
qr{^\Q/home/randomuser/ttyrec/127.0.0.1/20\E\d\d-\d\d-\d\d.\d\d\-\d\d\-\d\d\.\d{6}\Q.cafed00dcafe.bastionuser.randomuser.127.0.0.1.7979.ttyrec\E$}
|
||||
),
|
||||
"build_ttyrec_cmdline_part2of2 saveFile"
|
||||
);
|
||||
cmp_deeply(
|
||||
$fnret->value->{'cmd'},
|
||||
[
|
||||
'ttyrec',
|
||||
'-f',
|
||||
$fnret->value->{'saveFile'},
|
||||
'-F',
|
||||
'/home/randomuser/ttyrec/127.0.0.1/%Y-%m-%d.%H-%M-%S.#usec#.cafed00dcafe.bastionuser.randomuser.127.0.0.1.7979.ttyrec',
|
||||
'-k',
|
||||
88,
|
||||
'-t',
|
||||
99,
|
||||
'-s',
|
||||
"To unlock, use '--osh unlock' from another console"
|
||||
],
|
||||
"build_ttyrec_cmdline_part2of2 cmd"
|
||||
);
|
||||
|
||||
is(OVH::Bastion::config("bastionName")->value, "mock", "bastion name is mocked");
|
||||
|
||||
|
|
Loading…
Reference in a new issue