From a204313af909dd42faa312ff1c5c92a7e46685df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lesimple?= Date: Thu, 17 Dec 2020 15:43:02 +0000 Subject: [PATCH] feat: accountModify: add --osh-only (closes #97) --- bin/helper/osh-accountCreate | 2 +- bin/helper/osh-accountModify | 13 ++++++++++--- bin/plugin/restricted/accountCreate | 2 +- bin/plugin/restricted/accountModify | 4 +++- bin/shell/osh.pl | 2 +- .../plugins/restricted/accountCreate.rst | 2 +- .../plugins/restricted/accountModify.rst | 4 ++++ lib/perl/OVH/Bastion.pm | 1 + tests/functional/tests.d/340-selfaccesses.sh | 19 +++++++++++++++++++ 9 files changed, 41 insertions(+), 8 deletions(-) diff --git a/bin/helper/osh-accountCreate b/bin/helper/osh-accountCreate index 1c64028..c1583d9 100755 --- a/bin/helper/osh-accountCreate +++ b/bin/helper/osh-accountCreate @@ -363,7 +363,7 @@ else { # push this flag to prevent ssh/telnet usage if ($oshOnly) { - $fnret = OVH::Bastion::account_config(account => $account, key => "osh_only", value => "yes"); + $fnret = OVH::Bastion::account_config(account => $account, key => OVH::Bastion::OPT_ACCOUNT_OSH_ONLY, value => "yes"); $fnret or HEXIT($fnret); } diff --git a/bin/helper/osh-accountModify b/bin/helper/osh-accountModify index eb71ed8..8775e22 100755 --- a/bin/helper/osh-accountModify +++ b/bin/helper/osh-accountModify @@ -178,8 +178,12 @@ sub _toggle_yes_no { my $keyname = $params{'keyname'}; my $keyfile = $params{'keyfile'}; my $value = $params{'value'}; + my $public = $params{'public'}; - $fnret = OVH::Bastion::account_config(account => $account, public => 1, key => $keyfile); + # by default, if public is not specified, it's 1 + $public = 1 if !exists $params{'public'}; + + $fnret = OVH::Bastion::account_config(account => $account, public => $public, key => $keyfile); if ($value eq 'yes') { osh_info "Setting this account as $keyname..."; if ($fnret) { @@ -187,7 +191,7 @@ sub _toggle_yes_no { return R('OK_NO_CHANGE'); } - $fnret = OVH::Bastion::account_config(account => $account, public => 1, key => $keyfile, value => 'yes'); + $fnret = OVH::Bastion::account_config(account => $account, public => $public, key => $keyfile, value => 'yes'); if (!$fnret) { osh_warn "... error while setting the option"; return R('ERR_OPTION_CHANGE_FAILED'); @@ -203,7 +207,7 @@ sub _toggle_yes_no { return R('OK_NO_CHANGE'); } - $fnret = OVH::Bastion::account_config(account => $account, public => 1, key => $keyfile, delete => 1); + $fnret = OVH::Bastion::account_config(account => $account, public => $public, key => $keyfile, delete => 1); if (!$fnret) { osh_warn "... error while removing the option"; return R('ERR_OPTION_CHANGE_FAILED'); @@ -230,6 +234,9 @@ foreach my $tuple (@modify) { elsif ($key eq 'idle-ignore') { $result{$jsonkey} = _toggle_yes_no(value => $value, keyfile => OVH::Bastion::OPT_ACCOUNT_IDLE_IGNORE, keyname => 'idle-ignore'); } + elsif ($key eq 'osh-only') { + $result{$jsonkey} = _toggle_yes_no(value => $value, public => 0, keyfile => OVH::Bastion::OPT_ACCOUNT_OSH_ONLY, keyname => 'osh-only'); + } elsif ($key eq 'pam-auth-bypass') { $fnret = OVH::Bastion::is_user_in_group(user => $account, group => OVH::Bastion::PAM_AUTH_BYPASS_GROUP); if ($value eq 'yes') { diff --git a/bin/plugin/restricted/accountCreate b/bin/plugin/restricted/accountCreate index 262600a..4e6d7e3 100755 --- a/bin/plugin/restricted/accountCreate +++ b/bin/plugin/restricted/accountCreate @@ -34,7 +34,7 @@ Usage: --osh SCRIPT_NAME --account ACCOUNT [OPTIONS] --uid-auto Auto-select an UID from the allowed range (the upper available one will be used) --always-active This account's activation won't be challenged on connection, even if the bastion is globally configured to check for account activation - --osh-only This account will only be able to use OSH commands, and not connecting to machines (ssh or telnet) + --osh-only This account will only be able to use ``--osh`` commands, and can't connect anywhere through the bastion --immutable-key Deny any subsequent modification of the account key (selfAddKey and selfDelKey are denied) --comment '"STRING"' An optional comment when creating the account. Quote it twice as shown if you're under a shell. --public-key '"KEY"' Account public SSH key to deposit on the bastion, if not present, diff --git a/bin/plugin/restricted/accountModify b/bin/plugin/restricted/accountModify index db6a1db..df68ff7 100755 --- a/bin/plugin/restricted/accountModify +++ b/bin/plugin/restricted/accountModify @@ -21,6 +21,7 @@ my $remainingOptions = OVH::Bastion::Plugin::begin( "egress-strict-host-key-checking=s" => \$modify{'egress-strict-host-key-checking'}, "personal-egress-mfa-required=s" => \$modify{'personal-egress-mfa-required'}, "idle-ignore=s" => \$modify{'idle-ignore'}, + "osh-only=s" => \$modify{'osh-only'}, }, helptext => <<'EOF', Modify an account configuration @@ -43,6 +44,7 @@ Usage: --osh SCRIPT_NAME --account ACCOUNT [--option value [--option value [...] using the personal keys of the account, POLICY can be 'password', 'totp', 'any' or 'none' --always-active yes|no Set or unset the account as always active (i.e. disable the check of the 'active' status on this account) --idle-ignore yes|no If enabled, this account is immune to the idleLockTimeout and idleKillTimeout bastion-wide policy + --osh-only yes|no If enabled, this account can only use ``--osh`` commands, and can't connect anywhere through the bastion EOF ); @@ -69,7 +71,7 @@ foreach my $key (qw{ mfa-password-required mfa-totp-required }) { osh_exit 'ERR_INVALID_PARAMETER', "Expected '--$key yes' or '--$key no' or '--$key bypass' instead of '--$key $modify{$key}'"; } } -foreach my $key (qw{ always-active pam-auth-bypass idle-ignore }) { +foreach my $key (qw{ always-active pam-auth-bypass idle-ignore osh-only }) { next unless $modify{$key}; if (not grep { $modify{$key} eq $_ } qw{ yes no }) { help(); diff --git a/bin/shell/osh.pl b/bin/shell/osh.pl index 582b54a..7a409c4 100755 --- a/bin/shell/osh.pl +++ b/bin/shell/osh.pl @@ -970,7 +970,7 @@ if (!$quiet) { } # before doing stuff, check if we have the right to connect somewhere (some users are locked only to osh commands) -$fnret = OVH::Bastion::account_config(account => $self, key => "osh_only"); +$fnret = OVH::Bastion::account_config(account => $self, key => OVH::Bastion::OPT_ACCOUNT_OSH_ONLY); if ($fnret and $fnret->value() =~ /yes/) { $fnret = R('KO_ACCESS_DENIED', msg => "You don't have the right to connect anywhere"); } diff --git a/doc/sphinx/plugins/restricted/accountCreate.rst b/doc/sphinx/plugins/restricted/accountCreate.rst index 3bf2e51..ec6b209 100644 --- a/doc/sphinx/plugins/restricted/accountCreate.rst +++ b/doc/sphinx/plugins/restricted/accountCreate.rst @@ -33,7 +33,7 @@ Create a new bastion account configured to check for account activation .. option:: --osh-only - This account will only be able to use OSH commands, and not connecting to machines (ssh or telnet) + This account will only be able to use ``--osh`` commands, and can't connect anywhere through the bastion .. option:: --immutable-key diff --git a/doc/sphinx/plugins/restricted/accountModify.rst b/doc/sphinx/plugins/restricted/accountModify.rst index c15d8f8..87fbf1f 100644 --- a/doc/sphinx/plugins/restricted/accountModify.rst +++ b/doc/sphinx/plugins/restricted/accountModify.rst @@ -54,5 +54,9 @@ Modify an account configuration If enabled, this account is immune to the idleLockTimeout and idleKillTimeout bastion-wide policy +.. option:: --osh-only yes|no + + If enabled, this account can only use ``--osh`` commands, and can't connect anywhere through the bastion + diff --git a/lib/perl/OVH/Bastion.pm b/lib/perl/OVH/Bastion.pm index e6433cc..dc7fd8f 100644 --- a/lib/perl/OVH/Bastion.pm +++ b/lib/perl/OVH/Bastion.pm @@ -114,6 +114,7 @@ use constant { OPT_ACCOUNT_INGRESS_PIV_GRACE => 'ingress_piv_grace', OPT_ACCOUNT_ALWAYS_ACTIVE => 'always_active', OPT_ACCOUNT_IDLE_IGNORE => 'idle_ignore', + OPT_ACCOUNT_OSH_ONLY => 'osh_only', }; ########### diff --git a/tests/functional/tests.d/340-selfaccesses.sh b/tests/functional/tests.d/340-selfaccesses.sh index 766a62b..b555dd3 100644 --- a/tests/functional/tests.d/340-selfaccesses.sh +++ b/tests/functional/tests.d/340-selfaccesses.sh @@ -40,6 +40,25 @@ testsuite_selfaccesses() success realm modify_account1 $a0 --osh accountModify --pam-auth-bypass yes --account $account1 json .error_code OK .command accountModify + # test osh-only + success accountModify enable_osh_only $a0 --osh accountModify --osh-only yes --account $account1 + json .error_code OK .command accountModify + + # account1 can not connect to anything + run accountModify no_ssh_after_osh_only $a1 anybody@127.0.0.1 + retvalshouldbe 107 + json .error_code KO_ACCESS_DENIED .error_message "You don't have the right to connect anywhere" + + success accountModify disable_osh_only $a0 --osh accountModify --osh-only no --account $account1 + json .error_code OK .command accountModify + + # account1 can connect now (or could if they were granted) + run accountModify can_ssh_after_osh_only_disable $a1 anybody@127.0.0.1 + retvalshouldbe 107 + json .error_code KO_ACCESS_DENIED + contain "Access denied" + nocontain "anywhere" + revoke accountModify success selfListEgressKeys beforeadd $a1 -osh selfListEgressKeys