You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
the-bastion/bin/plugin/restricted/groupCreate

142 lines
4.1 KiB

#! /usr/bin/env perl
# vim: set filetype=perl ts=4 sw=4 sts=4 et:
use common::sense;
use Term::ReadKey;
use Term::ANSIColor;
use POSIX qw{ strftime };
use File::Basename;
use lib dirname(__FILE__) . '/../../../lib/perl';
use OVH::Result;
use OVH::Bastion;
use OVH::Bastion::Plugin qw( :DEFAULT );
my $remainingOptions = OVH::Bastion::Plugin::begin(
argv => \@ARGV,
header => "create a new group",
options => {
"group=s" => \my $group,
"owner=s" => \my $owner,
"algo=s" => \my $algo,
"size=i" => \my $size,
"encrypted" => \my $encrypted,
"no-key" => \my $no_key,
},
help => \&help,
);
sub help {
osh_info <<"EOF";
Create a group
Usage: --osh $scriptName --group GROUP --owner ACCOUNT <--algo ALGO --size SIZE [--encrypted]|--no-key>
--group Group name to create
--owner Preexisting bastion account to assign as owner (can be you)
--encrypted Add a passphrase to the key. Beware that you'll have to enter it for each use.
Do NOT add the passphrase after this option, you'll be prompted interactively for it.
--algo Specifies the algo of the key, either rsa, ecdsa or ed25519.
--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.
--no-key Don't generate an egress SSH key at all for this group
EOF
OVH::Bastion::print_accepted_key_algorithms(way => "egress", generate => 0);
return 0;
}
#
# code
#
my $fnret;
#
# params check
#
if (!$group || !$owner) {
help();
osh_exit 'ERR_MISSING_PARAMETER', "Group name or owner is missing";
}
# first, check that the name doesn't start with 'key' (see https://github.com/ovh/the-bastion/issues/178)
# as the is_valid_group() internally automatically guesses whether the input is from a user (in that case
# the $group is a bastion group name) or some other part of the code (in that case the $group might be
# the name of the OS group mapped to the bastion group name, hence starting with 'key')
if ($group =~ /^key/) {
osh_exit 'ERR_INVALID_PARAMETER', "The group name can't start with 'key' (reserved prefix)";
}
if ($algo && !$size && lc($algo) eq 'ed25519') {
$size = 256; # ed25519 size is always 256
}
if (!$no_key && (!$algo || !$size)) {
help();
osh_exit 'ERR_MISSING_PARAMETER', "Group algorithm or size is missing";
}
$fnret = OVH::Bastion::is_valid_group(group => $group, groupType => "key");
$fnret or osh_exit($fnret);
# get returned untainted value
$group = $fnret->value->{'group'};
my $shortGroup = $fnret->value->{'shortGroup'};
# check if algo is supported by system
if ($algo) {
$algo = lc($algo);
$fnret = OVH::Bastion::is_allowed_algo_and_size(algo => $algo, size => $size, way => 'egress');
$fnret or osh_exit $fnret;
}
#
# Now create it
#
my @command = qw{ sudo -n -u root -- /usr/bin/env perl -T };
push @command, $OVH::Bastion::BASEPATH . '/bin/helper/osh-groupCreate';
push @command, "--group", $group, "--owner", $owner;
push @command, "--algo", $algo if $algo;
push @command, "--size", $size if $size;
push @command, "--encrypted" if $encrypted;
push @command, "--no-key" if $no_key;
ReadMode('noecho');
$fnret = OVH::Bastion::helper(cmd => \@command, expects_stdin => 1);
ReadMode('restore');
$fnret or osh_exit $fnret;
my $result_hash = $fnret->value;
if ($no_key) {
osh_info 'Group creation complete!';
}
else {
osh_info 'Group creation complete! The public key of this group is:';
$fnret = OVH::Bastion::get_bastion_ips();
my $from;
if ($fnret) {
my @ips = @{$fnret->value};
$from = 'from="' . join(',', @ips) . '"';
}
$fnret = OVH::Bastion::get_group_keys(group => $group);
if ($fnret and $from) {
foreach my $keyfile (@{$fnret->value->{'sortedKeys'}}) {
my $key = $fnret->value->{'keys'}{$keyfile};
$key->{'prefix'} = $from;
OVH::Bastion::print_public_key(key => $key);
$result_hash->{'public_key'} = $key;
}
}
}
osh_ok $result_hash;