2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2025-06-12 17:30:19 +00:00

Load the cryptmethod in the passwd table to generate the password

sha256 and sha512 crypt methods are supported from glibc 2.7 version.
This patch enable the crypt feature on linux system and encrypt the
password with sha256 by default.

implement: #1890
This commit is contained in:
chenglch
2016-11-18 13:20:39 +08:00
parent a9f0237ca8
commit 69fff6a31e
6 changed files with 109 additions and 72 deletions

View File

@ -56,7 +56,7 @@ passwd Attributes:
\ **cryptmethod**\
Indicates the method that was used to encrypt the password attribute. On AIX systems, if a value is provided for this attribute it indicates that the password attribute is encrypted. If the cryptmethod value is not set it indicates the password is a simple string value. On Linux systems, the cryptmethod is not supported however the code attempts to auto-discover MD5 encrypted passwords.
Indicates the method that was used to encrypt the password attribute. On AIX systems, if a value is provided for this attribute it indicates that the password attribute is encrypted. If the cryptmethod value is not set it indicates the password is a simple string value. On Linux systems, the cryptmethod can be set to md5, sha256 or sha512. If not set, sha256 will be used as default.

View File

@ -824,7 +824,7 @@ passed as argument rather than by table value',
key => 'The type of component this user/pw is for. Valid values: blade (management module), ipmi (BMC), system (nodes), omapi (DHCP), hmc, ivm, cec, frame, switch.',
username => 'The default userid for this type of component',
password => 'The default password for this type of component',
cryptmethod => 'Indicates the method that was used to encrypt the password attribute. On AIX systems, if a value is provided for this attribute it indicates that the password attribute is encrypted. If the cryptmethod value is not set it indicates the password is a simple string value. On Linux systems, the cryptmethod is not supported however the code attempts to auto-discover MD5 encrypted passwords.',
cryptmethod => 'Indicates the method that was used to encrypt the password attribute. On AIX systems, if a value is provided for this attribute it indicates that the password attribute is encrypted. If the cryptmethod value is not set it indicates the password is a simple string value. On Linux systems, the cryptmethod can be set to md5, sha256 or sha512. If not set, sha256 will be used as default.',
authdomain => 'The domain in which this entry has meaning, e.g. specifying different domain administrators per active directory domain',
comments => 'Any user-written notes.',
disable => "Set to 'yes' or '1' to comment out this row.",

View File

@ -1,9 +1,14 @@
package xCAT::PasswordUtils;
use xCAT::Table;
use xCAT::MsgUtils;
use xCAT::Utils;
my $ipmiuser = "USERID"; # default username to apply if nothing specified
my $ipmipass = "PASSW0RD"; # default password to apply if nothing specified
my $bladeuser = "USERID"; # default username to apply if nothing specified
my $bladepass = "PASSW0RD"; # default password to apply if nothing specified
my %CRYPT_METHOD = ('md5' => '$1$', 'sha256' => '$5$', 'sha512' => '$6$');
# Picks the IPMI authentication to use with or deploy to a BMC
# mandatory arguments:
@ -112,3 +117,48 @@ sub getIPMIAuth {
return \%authmap;
}
# Encrypt system password based on the values in passwd table
# The values for system root user will be used if query key-pair is not defined
sub crypt_system_password {
# Just leave these arguments here for the compability reasons in Template.pm
# which get these values by parsing the template files.
my ($table, $kp, $fields) = @_;
if (!defined($table)) {
$table = 'passwd';
}
if (!defined($kp)) {
$kp->{'key'} = 'system';
$kp->{username} = 'root';
$fields->[0] = 'password';
$fields->[1] = 'cryptmethod';
}
my $tabh = xCAT::Table->new($table);
unless ($tabh) {
return undef;
}
$data = $tabh->getAttribs($kp, @{$fields});
if (!defined($data)) {
xCAT::MsgUtils->message("S",
"ERROR: Unable to get data from database table $table, key=$key");
return undef;
}
$tabh->close();
$password = $data->{'password'};
if (!defined($password)) {
xCAT::MsgUtils->message("S",
"ERROR: Unable to get password from database table $table, key=$key");
return undef;
}
$cryptmethod = $data->{'cryptmethod'};
if (!$cryptmethod) {
# Use sha256 crypt method by default
$result = crypt($password, $CRYPT_METHOD{'sha256'} . xCAT::Utils::genpassword(8));
} elsif( defined($CRYPT_METHOD{$cryptmethod})) {
$result = crypt($password,
$CRYPT_METHOD{$cryptmethod} . xCAT::Utils::genpassword(8));
} else {
xCAT::MsgUtils->message("S", "Unsupported crypt method $cryptmethod");
return undef;
}
return $result;
}

View File

@ -15,6 +15,7 @@ use xCAT::ADUtils; #to allow setting of one-time machine passwords
use xCAT::Utils;
use xCAT::TableUtils;
use xCAT::NetworkUtils;
use xCAT::PasswordUtils;
use XML::Simple;
BEGIN
@ -1573,28 +1574,27 @@ sub envvar
return ($ENV{$envvar});
}
sub genpassword {
#Generate a pseudo-random password of specified length
my $length = shift;
my $password = '';
my $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890';
srand; #have to reseed, rand is not rand otherwise
while (length($password) < $length) {
$password .= substr($characters, int(rand 63), 1);
}
return $password;
}
sub crydb
{
my $result = tabdb(@_);
my ($table, $key, $field) = @_;
my @fields = [$field, 'cryptmethod'];
my $kp;
# 1 - MD5, 5 - SHA256, 6 - SHA512
unless (($result =~ /^\$1\$/) || ($result =~ /^\$5\$/) || ($result =~ /^\$6\$/)) {
$result = crypt($result, '$1$' . genpassword(8));
}
return $result;
my $get_query_map = sub {
my $key = shift;
my %kp;
foreach (split /,/, $key) {
my ($k, $v);
($k, $v) = split /=/, $_;
$kp{$k} = $v if defined($k);
}
return \%kp if %kp;
sendmsg([ 1, "Unable to parse password parameters $key" ]);
return undef;
};
$kp = $get_query_map->($key);
return undef if (!defined($kp));
return xCAT::PasswordUtils::crypt_system_password($table, $kp, \@fields);
}
sub tabdb

View File

@ -37,6 +37,7 @@ use File::Path;
use xCAT::Utils;
use xCAT::TableUtils;
use xCAT::SvrUtils;
use xCAT::PasswordUtils;
use Digest::MD5 qw(md5_hex);
Getopt::Long::Configure("bundling");
@ -390,34 +391,27 @@ sub process_request {
# before packaging the image
system("umount $rootimg_dir/proc");
copybootscript($installroot, $rootimg_dir, $osver, $arch, $profile, $callback);
my $passtab = xCAT::Table->new('passwd');
if ($passtab) {
my $pass = 'cluster';
(my $pent) = $passtab->getAttribs({ key => 'system', username => 'root' }, 'password');
if ($pent and defined($pent->{password})) {
$pass = $pent->{password};
}
my $oldmask = umask(0077);
my $shadow;
open($shadow, "<", "$rootimg_dir/etc/shadow");
my @shadents = <$shadow>;
close($shadow);
open($shadow, ">", "$rootimg_dir/etc/shadow");
# 1 - MD5, 5 - SHA256, 6 - SHA512
unless (($pass =~ /^\$1\$/) || ($pass =~ /^\$5\$/) || ($pass =~ /^\$6\$/)) {
$pass = crypt($pass, '$1$' . xCAT::Utils::genpassword(8));
}
print $shadow "root:$pass:13880:0:99999:7:::\n";
foreach (@shadents) {
unless (/^root:/) {
print $shadow "$_";
}
}
close($shadow);
umask($oldmask);
my $pass = xCAT::PasswordUtils::crypt_system_password();
if (!defined($pass)) {
$pass = 'cluster';
}
my $oldmask = umask(0077);
my $shadow;
open($shadow, "<", "$rootimg_dir/etc/shadow");
my @shadents = <$shadow>;
close($shadow);
open($shadow, ">", "$rootimg_dir/etc/shadow");
print $shadow "root:$pass:13880:0:99999:7:::\n";
foreach (@shadents) {
unless (/^root:/) {
print $shadow "$_";
}
}
close($shadow);
umask($oldmask);
# sync fils configured in the synclist to the rootimage
$syncfile = xCAT::SvrUtils->getsynclistfile(undef, $osver, $arch, $profile, "netboot", $imagename);
if (defined($syncfile) && -f $syncfile

View File

@ -16,6 +16,7 @@ use File::Temp;
use xCAT::Utils qw(genpassword);
use xCAT::TableUtils qw(get_site_attribute);
use xCAT::SvrUtils;
use xCAT::PasswordUtils;
use Data::Dumper;
Getopt::Long::Configure("bundling");
Getopt::Long::Configure("pass_through");
@ -182,34 +183,26 @@ sub process_request {
#get the root password for the node
my $passtab = xCAT::Table->new('passwd');
if ($passtab) {
my $pass = 'cluster';
(my $pent) = $passtab->getAttribs({ key => 'system', username => 'root' }, 'password');
if ($pent and defined($pent->{password})) {
$pass = $pent->{password};
}
my $oldmask = umask(0077);
my $shadow;
open($shadow, "<", "$rootimg_dir/etc/shadow");
my @shadents = <$shadow>;
close($shadow);
open($shadow, ">", "$rootimg_dir/etc/shadow");
# 1 - MD5, 5 - SHA256, 6 - SHA512
unless (($pass =~ /^\$1\$/) || ($pass =~ /^\$5\$/) || ($pass =~ /^\$6\$/)) {
$pass = crypt($pass, '$1$' . genpassword(8));
}
print $shadow "root:$pass:13880:0:99999:7:::\n";
foreach (@shadents) {
unless (/^root:/) {
print $shadow "$_";
}
}
close($shadow);
umask($oldmask);
my $pass = xCAT::PasswordUtils::crypt_system_password();
if (!defined($pass)) {
$pass = 'cluster';
}
my $oldmask = umask(0077);
my $shadow;
open($shadow, "<", "$rootimg_dir/etc/shadow");
my @shadents = <$shadow>;
close($shadow);
open($shadow, ">", "$rootimg_dir/etc/shadow");
print $shadow "root:$pass:13880:0:99999:7:::\n";
foreach (@shadents) {
unless (/^root:/) {
print $shadow "$_";
}
}
close($shadow);
umask($oldmask);
my $distname = $osver;
unless (-r "$::XCATROOT/share/xcat/netboot/$distname/" or not $distname) {
chop($distname);