mirror of https://github.com/ovh/the-bastion
parent
fe58cf1d14
commit
e760cf6142
@ -0,0 +1,133 @@
|
||||
#! /usr/bin/perl -T
|
||||
# vim: set filetype=perl ts=4 sw=4 sts=4 et:
|
||||
# KEYSUDOERS # as an owner, we can delete an egress key of the group
|
||||
# KEYSUDOERS SUPEROWNERS, %%GROUP%-owner ALL=(keykeeper) NOPASSWD: /usr/bin/env perl -T %BASEPATH%/bin/helper/osh-groupDelEgressKey --group %GROUP% *
|
||||
# FILEMODE 0750
|
||||
# FILEOWN 0 keykeeper
|
||||
|
||||
#>HEADER
|
||||
use common::sense;
|
||||
use Getopt::Long;
|
||||
|
||||
use File::Basename;
|
||||
use lib dirname(__FILE__) . '/../../lib/perl';
|
||||
use OVH::Bastion;
|
||||
use OVH::Result;
|
||||
local $| = 1;
|
||||
|
||||
#
|
||||
# Globals
|
||||
#
|
||||
$ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/pkg/bin';
|
||||
my ($self) = $ENV{'SUDO_USER'} =~ m{^([a-zA-Z0-9._-]+)$};
|
||||
if (not defined $self) {
|
||||
if ($< == 0) {
|
||||
$self = 'root';
|
||||
}
|
||||
else {
|
||||
HEXIT('ERR_SUDO_NEEDED', msg => 'This command must be run under sudo');
|
||||
}
|
||||
}
|
||||
|
||||
# Fetch command options
|
||||
Getopt::Long::Configure("no_auto_abbrev");
|
||||
my $fnret;
|
||||
my ($result, @optwarns);
|
||||
my ($group, $id);
|
||||
eval {
|
||||
local $SIG{__WARN__} = sub { push @optwarns, shift };
|
||||
$result = GetOptions(
|
||||
"group=s" => sub { $group //= $_[1] }, # ignore subsequent --group on cmdline (anti-sudoers-override)
|
||||
"id=s" => sub { $id //= $_[1] },
|
||||
);
|
||||
};
|
||||
if ($@) { die $@ }
|
||||
|
||||
if (!$result) {
|
||||
local $" = ", ";
|
||||
HEXIT('ERR_BAD_OPTIONS', msg => "Error parsing options: @optwarns");
|
||||
}
|
||||
|
||||
if (!$group || !$id) {
|
||||
HEXIT('ERR_MISSING_PARAMETER', msg => "Missing argument 'group' or 'id'");
|
||||
}
|
||||
|
||||
#<HEADER
|
||||
|
||||
#>PARAMS:GROUP
|
||||
$fnret = OVH::Bastion::is_valid_group_and_existing(group => $group, groupType => "key");
|
||||
$fnret or HEXIT($fnret);
|
||||
|
||||
# get returned untainted value
|
||||
$group = $fnret->value->{'group'};
|
||||
my $shortGroup = $fnret->value->{'shortGroup'};
|
||||
|
||||
#<PARAMS:GROUP
|
||||
|
||||
#>RIGHTSCHECK
|
||||
if ($self eq 'root') {
|
||||
osh_debug "Real root, skipping checks of permissions";
|
||||
}
|
||||
$fnret = OVH::Bastion::is_group_owner(account => $self, group => $shortGroup, superowner => 1, sudo => 1);
|
||||
if (!$fnret) {
|
||||
HEXIT('ERR_SECURITY_VIOLATION', msg => "You're not allowed to run this, dear $self");
|
||||
}
|
||||
|
||||
#<RIGHTSCHECK
|
||||
|
||||
#>CODE
|
||||
$fnret = OVH::Bastion::get_group_keys(group => $group);
|
||||
$fnret or HEXIT($fnret);
|
||||
|
||||
my @matchingKeys = grep { $fnret->value->{'keys'}{$_}{'id'} eq $id } @{$fnret->value->{'sortedKeys'} || []};
|
||||
|
||||
if (!@matchingKeys) {
|
||||
HEXIT('ERR_INVALID_PARAMETER', msg => "Couldn't find any key with the ID you specified ($id) in group $shortGroup");
|
||||
}
|
||||
|
||||
my $keyToDelete = $matchingKeys[0];
|
||||
my $key = $fnret->value->{'keys'}{$keyToDelete};
|
||||
|
||||
osh_info("We're about to delete the following key:\n");
|
||||
OVH::Bastion::print_public_key(key => $key);
|
||||
|
||||
# get the path to the privkey
|
||||
my $fileToDelete = $fnret->value->{'keys'}{$keyToDelete}{'fullpath'};
|
||||
if (!-f $fileToDelete) {
|
||||
warn_syslog("The file '$fileToDelete' doesn't exist while trying to delete this egress key from group $shortGroup");
|
||||
HEXIT('ERR_INVALID_PARAMETER', msg => "Couldn't find the key file");
|
||||
}
|
||||
|
||||
my @errors;
|
||||
foreach my $file ($fileToDelete, "$fileToDelete.pub") {
|
||||
push @errors, "Couldn't delete '$file' in groupDelEgressKey by $self ($!)" if !unlink($file);
|
||||
}
|
||||
|
||||
if (@errors) {
|
||||
warn_syslog($_) for @errors;
|
||||
if (@errors == 2) {
|
||||
HEXIT('ERR_INTERNAL', msg => "Couldn't delete the requested key, more information available in the system log");
|
||||
}
|
||||
HEXIT('ERR_INTERNAL', msg => "Couldn't delete one of the files constituting the key, more information available in the system log");
|
||||
}
|
||||
|
||||
OVH::Bastion::syslogFormatted(
|
||||
severity => 'info',
|
||||
type => 'group',
|
||||
fields => [
|
||||
[action => 'delete_egress_key'],
|
||||
[group => $shortGroup],
|
||||
[self => $self],
|
||||
[key_id => $key->{'id'}],
|
||||
[key_algo => $key->{'typecode'}],
|
||||
[key_algo_family => $key->{'family'}],
|
||||
[key_size => $key->{'size'}],
|
||||
[key_fingerprint => $key->{'fingerprint'}],
|
||||
[key_comment => $key->{'comment'}],
|
||||
[key_mtime => $key->{'mtime'}],
|
||||
[key_path => $key->{'fullpath'}],
|
||||
[key_base64 => $key->{'base64'}],
|
||||
]
|
||||
);
|
||||
|
||||
HEXIT('OK', value => $key, msg => "Key $id has successfully been deleted from the $shortGroup group");
|
||||
@ -0,0 +1,138 @@
|
||||
#! /usr/bin/perl -T
|
||||
# vim: set filetype=perl ts=4 sw=4 sts=4 et:
|
||||
# KEYSUDOERS # as an owner, we can generate an egress key for the group
|
||||
# KEYSUDOERS SUPEROWNERS, %%GROUP%-owner ALL=(root) NOPASSWD: /usr/bin/env perl -T %BASEPATH%/bin/helper/osh-groupGenerateEgressKey --group %GROUP% *
|
||||
# FILEMODE 0755
|
||||
# FILEOWN 0 0
|
||||
|
||||
#>HEADER
|
||||
use common::sense;
|
||||
use Getopt::Long;
|
||||
|
||||
use File::Basename;
|
||||
use lib dirname(__FILE__) . '/../../lib/perl';
|
||||
use OVH::Result;
|
||||
use OVH::Bastion;
|
||||
use OVH::Bastion::Plugin::generateEgressKey;
|
||||
local $| = 1;
|
||||
|
||||
#
|
||||
# Globals
|
||||
#
|
||||
$ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/pkg/bin';
|
||||
my ($self) = $ENV{'SUDO_USER'} =~ m{^([a-zA-Z0-9._-]+)$};
|
||||
if (not defined $self) {
|
||||
if ($< == 0) {
|
||||
$self = 'root';
|
||||
}
|
||||
else {
|
||||
HEXIT('ERR_SUDO_NEEDED', msg => 'This command must be run under sudo');
|
||||
}
|
||||
}
|
||||
|
||||
# Fetch command options
|
||||
my ($result, @optwarns);
|
||||
my ($group, $algo, $size, $encrypted);
|
||||
eval {
|
||||
local $SIG{__WARN__} = sub { push @optwarns, shift };
|
||||
$result = GetOptions(
|
||||
"group=s" => sub { $group //= $_[1] }, # ignore subsequent --group on cmdline (anti-sudoers-override)
|
||||
"algo=s" => sub { $algo //= $_[1] },
|
||||
"size=i" => sub { $size //= $_[1] },
|
||||
"encrypted" => sub { $encrypted //= $_[1] },
|
||||
);
|
||||
};
|
||||
if ($@) { die $@ }
|
||||
|
||||
if (!$result) {
|
||||
local $" = ", ";
|
||||
HEXIT('ERR_BAD_OPTIONS', msg => "Error parsing options: @optwarns");
|
||||
}
|
||||
|
||||
if (!$size || !$algo || !$group) {
|
||||
HEXIT('ERR_MISSING_PARAMETER', msg => "Missing argument 'size', 'algo' or 'group'");
|
||||
}
|
||||
|
||||
#<HEADER
|
||||
|
||||
my $fnret;
|
||||
|
||||
$fnret = OVH::Bastion::is_valid_group_and_existing(group => $group, groupType => "key");
|
||||
$fnret or HEXIT($fnret);
|
||||
|
||||
$fnret = OVH::Bastion::Plugin::generateEgressKey::preconditions(
|
||||
context => 'group',
|
||||
self => $self,
|
||||
group => $group,
|
||||
algo => $algo,
|
||||
size => $size,
|
||||
sudo => 1,
|
||||
);
|
||||
$fnret or HEXIT($fnret);
|
||||
|
||||
# get returned untainted values
|
||||
my ($shortGroup, $keyhome);
|
||||
($group, $algo, $size, $shortGroup, $keyhome) = @{$fnret->value}{qw{ group algo size shortGroup keyhome}};
|
||||
|
||||
my $passphrase = '';
|
||||
if ($encrypted) {
|
||||
|
||||
# read the passphrase from stdin
|
||||
$passphrase = <STDIN>;
|
||||
|
||||
# we need to untaint it, as it's going to be passed as an arg to the array version of system(),
|
||||
# it can contain anything, really, there is no shell escape possible (see generate_ssh_key in ssh.inc)
|
||||
($passphrase) = $passphrase =~ /^(.+)$/;
|
||||
}
|
||||
|
||||
my $keykeeper_uid = (getpwnam('keykeeper'))[2];
|
||||
my $group_gid = (getgrnam($group))[2];
|
||||
|
||||
if (!$keykeeper_uid || !$group_gid) {
|
||||
warn_syslog("Couldn't get the uid of keykeeper ($keykeeper_uid) or gid of $group ($group_gid) while $self is attempting to generate a new key with algo $algo and size $size");
|
||||
HEXIT('ERR_INTERNAL', msg => "Couldn't fetch the required account or group IDs");
|
||||
}
|
||||
|
||||
osh_info "Generating a new key pair, this might take a while...";
|
||||
$fnret = OVH::Bastion::generate_ssh_key(
|
||||
folder => $keyhome,
|
||||
prefix => $shortGroup,
|
||||
algo => $algo,
|
||||
size => $size,
|
||||
passphrase => $passphrase,
|
||||
uid => $keykeeper_uid,
|
||||
gid => $group_gid,
|
||||
group_readable => 1,
|
||||
);
|
||||
$fnret or HEXIT($fnret);
|
||||
|
||||
my $filepath = $fnret->value->{'file'};
|
||||
my $mtime = (stat($filepath))[9];
|
||||
|
||||
osh_info "The new key pair has been generated:\n";
|
||||
$fnret = OVH::Bastion::get_ssh_pub_key_info(file => $filepath . ".pub", way => "egress");
|
||||
$fnret or HEXIT($fnret);
|
||||
|
||||
my $key = $fnret->value;
|
||||
|
||||
OVH::Bastion::syslogFormatted(
|
||||
severity => 'info',
|
||||
type => 'group',
|
||||
fields => [
|
||||
[action => 'generate_egress_key'],
|
||||
[group => $shortGroup],
|
||||
[self => $self],
|
||||
[key_id => $key->{'id'}],
|
||||
[key_algo => $key->{'typecode'}],
|
||||
[key_algo_family => $key->{'family'}],
|
||||
[key_size => $key->{'size'}],
|
||||
[key_fingerprint => $key->{'fingerprint'}],
|
||||
[key_comment => $key->{'comment'}],
|
||||
[key_mtime => $mtime],
|
||||
[key_path => $filepath],
|
||||
[key_base64 => $key->{'base64'}],
|
||||
[key_encrypted => $encrypted ? "yes" : "no"],
|
||||
]
|
||||
);
|
||||
|
||||
HEXIT('OK', value => $key);
|
||||
@ -0,0 +1,61 @@
|
||||
#! /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 => "Remove a bastion group egress key",
|
||||
options => {
|
||||
"group=s" => \my $group,
|
||||
"id=s" => \my $id,
|
||||
},
|
||||
helptext => <<"EOF",
|
||||
Remove a bastion group egress key
|
||||
|
||||
Usage: --osh SCRIPT_NAME <--group GROUP> <--id ID>
|
||||
|
||||
--group GROUP Name of the group to delete the egress key from
|
||||
--id ID Specify the key ID to delete, you can get it with groupInfo
|
||||
EOF
|
||||
);
|
||||
|
||||
#
|
||||
# code
|
||||
#
|
||||
my $fnret;
|
||||
|
||||
if (!$id || !$group) {
|
||||
help();
|
||||
osh_exit 'ERR_MISSING_PARAMETER', "Missing the --group or --id parameter";
|
||||
}
|
||||
|
||||
$fnret = OVH::Bastion::is_valid_group_and_existing(group => $group, groupType => "key");
|
||||
$fnret or osh_exit($fnret);
|
||||
|
||||
# get returned untainted value
|
||||
$group = $fnret->value->{'group'};
|
||||
my $shortGroup = $fnret->value->{'shortGroup'};
|
||||
|
||||
if (!OVH::Bastion::is_group_owner(account => $self, group => $shortGroup, superowner => 1)) {
|
||||
osh_exit 'ERR_NOT_GROUP_OWNER', "You must be an owner to delete an egress group key";
|
||||
}
|
||||
|
||||
$fnret = OVH::Bastion::get_group_keys(group => $group);
|
||||
|
||||
my @matchingKeys = grep { $fnret->value->{'keys'}{$_}{'id'} eq $id } @{$fnret->value->{'sortedKeys'} || []};
|
||||
|
||||
if (!@matchingKeys) {
|
||||
osh_exit 'ERR_INVALID_PARAMETER', "Couldn't find any key with the ID you specified ($id) in group $shortGroup";
|
||||
}
|
||||
|
||||
my @command = qw{ sudo -n -u keykeeper -- /usr/bin/env perl -T };
|
||||
push @command, $OVH::Bastion::BASEPATH . '/bin/helper/osh-groupDelEgressKey';
|
||||
push @command, "--group", $group, "--id", $id;
|
||||
|
||||
osh_exit(OVH::Bastion::helper(cmd => \@command));
|
||||
@ -0,0 +1,10 @@
|
||||
{
|
||||
"interactive": [
|
||||
"groupDelEgressKey" , {"ac" : ["--group"]},
|
||||
"groupDelEgressKey --group" , {"ac" : ["<GROUP>"]},
|
||||
"groupDelEgressKey --group \\S+" , {"ac" : ["--id"]},
|
||||
"groupDelEgressKey --group \\S+ --id" , {"pr" : ["<KEYID>"]},
|
||||
"groupDelEgressKey --group \\S+ --id \\d+", {"pr" : ["<enter>"]}
|
||||
],
|
||||
"master_only": true
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
#! /usr/bin/env perl
|
||||
# vim: set filetype=perl ts=4 sw=4 sts=4 et:
|
||||
use common::sense;
|
||||
use Term::ReadKey;
|
||||
|
||||
use File::Basename;
|
||||
use lib dirname(__FILE__) . '/../../../lib/perl';
|
||||
use OVH::Result;
|
||||
use OVH::Bastion;
|
||||
use OVH::Bastion::Plugin qw( :DEFAULT );
|
||||
use OVH::Bastion::Plugin::generateEgressKey;
|
||||
|
||||
my $remainingOptions = OVH::Bastion::Plugin::begin(
|
||||
argv => \@ARGV,
|
||||
header => "generating a new key pair for a group",
|
||||
options => {
|
||||
"group=s" => \my $group,
|
||||
"algo=s" => \my $algo,
|
||||
"size=i" => \my $size,
|
||||
"encrypted" => \my $encrypted,
|
||||
},
|
||||
help => \&OVH::Bastion::Plugin::generateEgressKey::help,
|
||||
);
|
||||
|
||||
#
|
||||
# code
|
||||
#
|
||||
my $fnret;
|
||||
|
||||
$fnret = OVH::Bastion::Plugin::generateEgressKey::preconditions(
|
||||
context => 'group',
|
||||
self => $self,
|
||||
group => $group,
|
||||
algo => $algo,
|
||||
size => $size
|
||||
);
|
||||
if ($fnret->err eq 'ERR_MISSING_PARAMETER') {
|
||||
OVH::Bastion::Plugin::generateEgressKey::help();
|
||||
osh_exit(R('ERR_MISSING_PARAMETER', msg => "Missing the 'algo', 'size' or 'group' parameter'"));
|
||||
}
|
||||
$fnret or osh_exit $fnret;
|
||||
|
||||
my ($shortGroup, $keyhome);
|
||||
($group, $algo, $size, $shortGroup, $keyhome) = @{$fnret->value}{qw{ group algo size shortGroup keyhome }};
|
||||
|
||||
my $passphrase = ''; # empty by default
|
||||
if ($encrypted) {
|
||||
$fnret = OVH::Bastion::Plugin::generateEgressKey::ask_passphrase();
|
||||
$fnret or osh_exit $fnret;
|
||||
$passphrase = $fnret->value;
|
||||
}
|
||||
|
||||
my @command = qw{ sudo -n -u root -- /usr/bin/env perl -T };
|
||||
push @command, $OVH::Bastion::BASEPATH . '/bin/helper/osh-groupGenerateEgressKey';
|
||||
push @command, '--group', $group;
|
||||
push @command, '--algo', $algo;
|
||||
push @command, '--size', $size;
|
||||
push @command, '--encrypted' if $encrypted;
|
||||
|
||||
$fnret = OVH::Bastion::helper(cmd => \@command, stdin_str => $passphrase);
|
||||
$fnret or osh_exit $fnret;
|
||||
|
||||
my $key = $fnret->value;
|
||||
|
||||
$fnret = OVH::Bastion::get_bastion_ips();
|
||||
$fnret or osh_exit $fnret;
|
||||
|
||||
$key->{'prefix'} = 'from="' . join(',', @{$fnret->value}) . '"';
|
||||
|
||||
OVH::Bastion::print_public_key(key => $key);
|
||||
|
||||
osh_ok($key);
|
||||
@ -0,0 +1,14 @@
|
||||
{
|
||||
"interactive": [
|
||||
"groupGenerateEgressKey" , {"ac" : ["--group"]},
|
||||
"groupGenerateEgressKey --group" , {"ac" : ["<GROUP>"]},
|
||||
"groupGenerateEgressKey --group \\S+" , {"ac" : ["--algo"]},
|
||||
"groupGenerateEgressKey --group \\S+ --algo" , {"ac" : ["rsa", "ecdsa", "ed25519"]},
|
||||
"groupGenerateEgressKey --group \\S+ --algo \\S+" , {"ac" : ["--size"]},
|
||||
"groupGenerateEgressKey --group \\S+ --algo \\S+ --size" , {"pr" : ["<SIZE>"]},
|
||||
"groupGenerateEgressKey --group \\S+ --algo \\S+ --size \\d+" , {"ac" : ["<enter>", "--encrypted"]},
|
||||
"groupGenerateEgressKey --group \\S+ --algo \\S+ --size \\d+ --encrypted", {"pr" : ["<enter>"]}
|
||||
],
|
||||
"master_only": true,
|
||||
"terminal_mode" : "raw"
|
||||
}
|
||||
@ -0,0 +1,122 @@
|
||||
package OVH::Bastion::Plugin::generateEgressKey;
|
||||
|
||||
# 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 };
|
||||
|
||||
sub help {
|
||||
require Term::ANSIColor;
|
||||
my $fnret = OVH::Bastion::get_supported_ssh_algorithms_list(way => 'egress');
|
||||
my @algoList = @{$fnret->value};
|
||||
my $algos = Term::ANSIColor::colored(uc join(' ', @algoList), 'green');
|
||||
my $helpAlgoSize = '--algo rsa --size 4096';
|
||||
if (grep { $_ eq 'ecdsa' } @algoList) {
|
||||
$helpAlgoSize = '--algo ecdsa --size 521';
|
||||
}
|
||||
if (grep { $_ eq 'ed25519' } @algoList) {
|
||||
$helpAlgoSize = '--algo ed25519';
|
||||
}
|
||||
osh_info <<"EOF";
|
||||
Create a new public + private key pair. The private key will stay on this bastion.
|
||||
|
||||
Usage: --osh $scriptName $helpAlgoSize [--encrypted]
|
||||
|
||||
--algo ALGO Specifies the algo of the key, either rsa, ecdsa or ed25519.
|
||||
|
||||
--size SIZE Specifies the size of the key to be generated.
|
||||
For RSA, choose between 2048 and 8192 (4096 is good).
|
||||
For ECDSA, choose either 256, 384 or 521.
|
||||
For ED25519, size is always 256.
|
||||
|
||||
--encrypted if specified, a passphrase will be prompted for the new key
|
||||
|
||||
With the policy and SSH version on this bastion,
|
||||
the following algorithms are supported: $algos
|
||||
|
||||
algo size strength speed compatibility
|
||||
------- ---- ---------- -------- -----------------------
|
||||
RSA 4096 good slow works everywhere
|
||||
ECDSA 521 strong fast debian7+ (OpenSSH 5.7+)
|
||||
ED25519 256 verystrong veryfast debian8+ (OpenSSH 6.5+)
|
||||
EOF
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub ask_passphrase {
|
||||
require Term::ReadKey;
|
||||
print "Please enter a passphrase for the private key that'll stay on the bastion (not echoed): ";
|
||||
Term::ReadKey::ReadMode('noecho');
|
||||
chomp(my $pass1 = <STDIN>);
|
||||
if (length($pass1) < 5) {
|
||||
|
||||
# ssh-keygen will refuse
|
||||
print "\n";
|
||||
return R('ERR_PASSPHRASE_TOO_SHORT', msg => "Passphrase needs to be at least 5 chars");
|
||||
}
|
||||
print "\nPlease enter it again: ";
|
||||
chomp(my $pass2 = <STDIN>);
|
||||
print "\n";
|
||||
Term::ReadKey::ReadMode('restore');
|
||||
if ($pass1 ne $pass2) {
|
||||
return R('ERR_PASSPHRASE_MISMATCH', msg => "Passphrases don't match, please try again");
|
||||
}
|
||||
return R('OK', value => $pass1);
|
||||
}
|
||||
|
||||
sub preconditions {
|
||||
my %params = @_;
|
||||
my $fnret;
|
||||
|
||||
my ($self, $group, $algo, $size, $account, $sudo, $context) = @params{qw{ self group algo size account sudo context}};
|
||||
|
||||
if (!$algo || !$context) {
|
||||
return R('ERR_MISSING_PARAMETER', msg => "Missing argument algo[$algo] or context[$context]");
|
||||
}
|
||||
|
||||
if (!grep { $context eq $_ } qw{ group account }) {
|
||||
return R('ERR_INVALID_PARAMETER', msg => "Type should be group or account");
|
||||
}
|
||||
|
||||
# check whether algo is supported by system
|
||||
$fnret = OVH::Bastion::is_allowed_algo_and_size(algo => $algo, size => $size, way => 'egress');
|
||||
$fnret or return $fnret;
|
||||
($algo, $size) = @{$fnret->value}{qw{ algo size }}; # untaint
|
||||
|
||||
# check preconditions if we're generating a key for a group
|
||||
if ($context eq 'group') {
|
||||
if (!$group || !$self) {
|
||||
return R('ERR_MISSING_PARAMETER', msg => "Missing 'group' or 'self' parameter");
|
||||
}
|
||||
$fnret = OVH::Bastion::is_valid_group_and_existing(group => $group, groupType => 'key');
|
||||
$fnret or return $fnret;
|
||||
my $keyhome = $fnret->value->{'keyhome'};
|
||||
my $shortGroup = $fnret->value->{'shortGroup'};
|
||||
$group = $fnret->value->{'group'};
|
||||
|
||||
$fnret = OVH::Bastion::is_group_owner(group => $shortGroup, account => $self, superowner => 1, sudo => $sudo);
|
||||
if (!$fnret) {
|
||||
return R('ERR_NOT_GROUP_OWNER', msg => "Sorry, you're not an owner of group $shortGroup, which is needed to manage its egress keys ($fnret)");
|
||||
}
|
||||
|
||||
return R('OK', value => {group => $group, shortGroup => $shortGroup, keyhome => $keyhome, algo => $algo, size => $size, context => $context});
|
||||
}
|
||||
elsif ($context eq 'account') {
|
||||
if (!$account) {
|
||||
return R('ERR_MISSING_PARAMETER', msg => "Missing 'group' parameter");
|
||||
}
|
||||
$fnret = OVH::Bastion::is_bastion_account_valid_and_existing(account => $account);
|
||||
$fnret or return $fnret;
|
||||
|
||||
return R('OK', value => {algo => $algo, size => $size, context => $context});
|
||||
}
|
||||
else {
|
||||
return R('ERR_INTERNAL');
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
Loading…
Reference in new issue