chore/fix: move HEXIT() to helper module, use HEXIT only in helpers

This commit is contained in:
Stéphane Lesimple 2021-12-09 12:55:48 +00:00 committed by Stéphane Lesimple
parent 850152a88c
commit cb28b44382
4 changed files with 47 additions and 41 deletions

View file

@ -57,7 +57,7 @@ use OVH::Result;
use parent qw( Exporter );
our @EXPORT = ## no critic (AutomaticExportation)
qw( osh_header osh_footer osh_exit osh_debug osh_info osh_warn osh_crit osh_ok HEXIT warn_syslog );
qw( osh_header osh_footer osh_exit osh_debug osh_info osh_warn osh_crit osh_ok warn_syslog );
our $AUTOLOAD;
@ -465,30 +465,6 @@ sub osh_ok { ## no critic (ArgUnpacking)
exit OVH::Bastion::EXIT_OK;
}
# HEXIT aka "helper exit", used by helper scripts found in helpers/
# Can be used in several ways:
# With an R object: HEXIT(R('OK', value => {}, msg => "okey"))
# Or with 1 value, that will be taken as the R->err: HEXIT('OK')
# Or with 2 values, that will be taken as err, msg: HEXIT('ERR_UNKNOWN', 'Unexpected error')
# With more values, they'll be used as constructor for an R object
sub HEXIT { ## no critic (ArgUnpacking)
my $R;
if (@_ == 1) {
$R = ref $_[0] eq 'OVH::Result' ? $_[0] : R($_[0]);
}
elsif (@_ == 2) {
my $err = shift || 'OK';
my $msg = shift;
$R = R($err, msg => $msg);
}
else {
$R = R(@_);
}
OVH::Bastion::json_output($R, force_default => 1);
exit 0;
}
sub osh_debug {
my $text = shift;
if (($ENV{'PLUGIN_DEBUG'} or $ENV{'OSH_DEBUG'}) and not $ENV{'PLUGIN_QUIET'}) {

View file

@ -11,17 +11,47 @@ use OVH::Result;
# We handle our importer's '$self' var, this is by design.
use Exporter 'import';
our $self; ## no critic (ProhibitPackageVars)
our @EXPORT = qw( $self ); ## no critic (ProhibitAutomaticExportation)
our @EXPORT = qw( $self HEXIT ); ## no critic (ProhibitAutomaticExportation)
# HEXIT aka "helper exit", used by helper scripts found in helpers/
# Can be used in several ways:
# With an R object: HEXIT(R('OK', value => {}, msg => "okey"))
# Or with 1 value, that will be taken as the R->err: HEXIT('OK')
# Or with 2 values, that will be taken as err, msg: HEXIT('ERR_UNKNOWN', 'Unexpected error')
# With more values, they'll be used as constructor for an R object
sub HEXIT { ## no critic (ArgUnpacking)
my $R;
if (@_ == 1) {
$R = ref $_[0] eq 'OVH::Result' ? $_[0] : R($_[0]);
}
elsif (@_ == 2) {
my $err = shift || 'OK';
my $msg = shift;
$R = R($err, msg => $msg);
}
else {
$R = R(@_);
}
OVH::Bastion::json_output($R, force_default => 1);
exit 0;
}
#
# This code has to be ran for all helpers before they attempt to do anything useful,
# and as we're only use'd by helpers, we include it here directly on top-level.
#
$| = 1;
#
# This code has to be ran for all helpers so we include it here directly
#
# Don't let helpers be interrupted too easily
$SIG{'HUP'} = 'IGNORE'; # continue even when attached terminal is closed (we're called with setsid on supported systems anyway)
$SIG{'PIPE'} = 'IGNORE'; # continue even if osh_info gets a SIGPIPE because there's no longer a terminal
# Ensure the PATH is not tainted, and has sane values
$ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/pkg/bin';
# Build $self from SUDO_USER, as helpers are always run under sudo
($self) = $ENV{'SUDO_USER'} =~ m{^([a-zA-Z0-9._-]+)$};
if (not defined $self) {
if ($< == 0) {

View file

@ -59,11 +59,11 @@ sub preconditions {
if ($context eq 'account' && $self ne $account) {
$fnret = OVH::Bastion::is_user_in_group(user => $self, group => "osh-accountGeneratePassword");
$fnret or HEXIT('ERR_SECURITY_VIOLATION', msg => "You're not allowed to run this, dear $self");
$fnret or return R('ERR_SECURITY_VIOLATION', msg => "You're not allowed to run this, dear $self");
}
elsif ($context eq 'group') {
$fnret = OVH::Bastion::is_group_owner(account => $self, group => $shortGroup, superowner => 1, sudo => $sudo);
$fnret or HEXIT('ERR_NOT_ALLOWED', msg => "You're not a group owner of $shortGroup, dear $self");
$fnret or return R('ERR_NOT_ALLOWED', msg => "You're not a group owner of $shortGroup, dear $self");
}
# return untainted values
@ -105,7 +105,7 @@ sub act {
# get the corresponding hashes
$fnret = OVH::Bastion::get_hashes_from_password(password => $pass);
$fnret or HEXIT($fnret);
$fnret or return $fnret;
# verify that the hashes match this regex (some constructors need it)
my $check_re = qr'^\$\d\$[a-zA-Z0-9]+\$[a-zA-Z0-9.\/]+$';
@ -124,7 +124,7 @@ sub act {
# push password in a file
if (!-d $passhome) {
if (!mkdir $passhome) {
HEXIT('ERR_INTERNAL', msg => "Couldn't create passwords directory in group home '$passhome' ($!)");
return R('ERR_INTERNAL', msg => "Couldn't create passwords directory in group home '$passhome' ($!)");
}
if ($context eq 'account') {
if (my (undef, undef, $uid, $gid) = getpwnam($account)) {
@ -133,7 +133,7 @@ sub act {
}
}
if (!-d $passhome) {
HEXIT('ERR_INTERNAL', msg => "Couldn't create passwords directory in group home");
return R('ERR_INTERNAL', msg => "Couldn't create passwords directory in group home");
}
chmod 0750, $passhome;
if (-e $base) {
@ -146,19 +146,19 @@ sub act {
if (-e "$base.$n") {
osh_debug "renaming $base.$n to $base.$next";
if (!rename "$base.$n", "$base.$next") {
HEXIT('ERR_INTERNAL', msg => "Couldn't rename '$base.$n' to '$base.$next' ($!)");
return R('ERR_INTERNAL', msg => "Couldn't rename '$base.$n' to '$base.$next' ($!)");
}
if (-e "$base.$n.metadata" && !rename "$base.$n.metadata", "$base.$next.metadata") {
HEXIT('ERR_INTERNAL', msg => "Couldn't rename '$base.$n.metadata' to '$base.$next.metadata' ($!)");
return R('ERR_INTERNAL', msg => "Couldn't rename '$base.$n.metadata' to '$base.$next.metadata' ($!)");
}
}
}
osh_debug "renaming $base to $base.1";
if (!rename "$base", "$base.1") {
HEXIT('ERR_INTERNAL', msg => "Couldn't rename '$base' to '$base.1' ($!)");
return R('ERR_INTERNAL', msg => "Couldn't rename '$base' to '$base.1' ($!)");
}
if (-e "$base.metadata" && !rename "$base.metadata", "$base.1.metadata") {
HEXIT('ERR_INTERNAL', msg => "Couldn't rename '$base.metadata' to '$base.1.metadata' ($!)");
return R('ERR_INTERNAL', msg => "Couldn't rename '$base.metadata' to '$base.1.metadata' ($!)");
}
}
if (open(my $fdout, '>', $base)) {
@ -172,7 +172,7 @@ sub act {
chmod 0440, $base;
}
else {
HEXIT('ERR_INTERNAL', msg => "Couldn't create password file in $base ($!)");
return R('ERR_INTERNAL', msg => "Couldn't create password file in $base ($!)");
}
if (open(my $fdout, '>', "$base.metadata")) {

View file

@ -537,7 +537,7 @@ sub generate_ssh_key {
my $sshKeyName = $folder . '/id_' . $algo . $size . '_' . $prefix . '.' . time();
if (-e $sshKeyName) {
HEXIT('ERR_KEY_ALREADY_EXISTS', msg => "Can't forge key, generated name already exists");
return R('ERR_KEY_ALREADY_EXISTS', msg => "Can't forge key, generated name already exists");
}
my $bastionName = OVH::Bastion::config('bastionName');