Added a genpass flag to generate a password and install it in the guest
* We could use the same functions to set a password via a --password flag * It would nice to move more functionality to subroutines * The current generatePassword subroutine, only generates alphanum passwords and hashes
This commit is contained in:
@@ -104,8 +104,10 @@ xen-create-image - Easily create new Xen instances with networking and OpenSSH.
|
||||
fs, size, swap and noswap are ignored when using this
|
||||
option.
|
||||
|
||||
--genpass Generate a random root password
|
||||
|
||||
--passwd Ask for a root password during setup.
|
||||
NOTE: This is done interactively.
|
||||
NOTE: This is done interactively and overrides --genpass
|
||||
|
||||
--role=role Run the specified role script(s) post-install.
|
||||
Role scripts are discussed later in this manpage.
|
||||
@@ -732,6 +734,7 @@ use Digest::MD5 qw/ md5_hex /;
|
||||
use Env;
|
||||
use File::Path qw/ mkpath /;
|
||||
use File::Temp qw/ tempdir /;
|
||||
use File::Copy qw/ cp /;
|
||||
use Getopt::Long;
|
||||
use Pod::Usage;
|
||||
|
||||
@@ -784,6 +787,11 @@ my $RELEASE = '4.2beta1';
|
||||
my $IP_ADDRESSES = '';
|
||||
|
||||
|
||||
#
|
||||
# Variable for generated password
|
||||
#
|
||||
my $PASSWORD = '';
|
||||
|
||||
#
|
||||
# Setup default options.
|
||||
#
|
||||
@@ -1018,7 +1026,7 @@ runXenConfigCreation();
|
||||
#
|
||||
# Setup the password if the user wanted that.
|
||||
#
|
||||
setupRootPassword() if ( $CONFIG{ 'passwd' } );
|
||||
setupRootPassword() if ( $CONFIG{ 'passwd' } or $CONFIG{ 'genpass' } );
|
||||
|
||||
|
||||
#
|
||||
@@ -1342,6 +1350,13 @@ sub setupDefaultOptions
|
||||
$CONFIG{ 'install-method' } = 'debootstrap';
|
||||
$CONFIG{ 'debootstrap-cmd' } = '';
|
||||
|
||||
#
|
||||
# Default values for passwords
|
||||
#
|
||||
$CONFIG{ 'genpass' } = 1;
|
||||
$CONFIG{ 'genpass_len' } = 8;
|
||||
$CONFIG{ 'password' } = '';
|
||||
|
||||
#
|
||||
# The program to run to create a filesystem.
|
||||
#
|
||||
@@ -1551,6 +1566,9 @@ sub parseCommandLineArguments
|
||||
"hooks=i", \$CONFIG{ 'hooks' },
|
||||
"pygrub", \$CONFIG{ 'pygrub' },
|
||||
"passwd", \$CONFIG{ 'passwd' },
|
||||
"genpass=i", \$CONFIG{ 'genpass' },
|
||||
"genpass-len=i", \$CONFIG{ 'genpass_len' },
|
||||
"password=s", \$CONFIG{ 'password' },
|
||||
"partitions=s", \$CONFIG{ 'partitions' },
|
||||
"role=s", \$CONFIG{ 'role' },
|
||||
"role-args=s", \$CONFIG{ 'role-args' },
|
||||
@@ -3729,16 +3747,81 @@ sub setupRootPassword
|
||||
{
|
||||
logprint("Setting up root password\n");
|
||||
|
||||
if ( -x $MOUNT_POINT . "/usr/bin/passwd" )
|
||||
if ( $CONFIG{ 'passwd' } )
|
||||
{
|
||||
system("chroot $MOUNT_POINT /usr/bin/passwd");
|
||||
if ( -x $MOUNT_POINT . "/usr/bin/passwd" )
|
||||
{
|
||||
system("chroot $MOUNT_POINT /usr/bin/passwd");
|
||||
}
|
||||
else
|
||||
{
|
||||
logprint("'passwd' command not found in the new install.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logprint("'passwd' command not found in the new install.\n");
|
||||
logprint("Generating a password for the new guest.\n");
|
||||
#
|
||||
# Replace the password in the /etc/shadow file
|
||||
#
|
||||
my $shadow_path = $MOUNT_POINT . '/etc/shadow';
|
||||
if ( -e $shadow_path )
|
||||
{
|
||||
#
|
||||
# Generate a password, salt and use that to generating a hash
|
||||
#
|
||||
my $salt = generatePassword(8);
|
||||
$PASSWORD = generatePassword( $CONFIG{ 'genpass_len' } );
|
||||
my $hash = `echo -n $PASSWORD | openssl passwd -stdin -1 -salt $salt`;
|
||||
$hash =~ s/\s+$//;
|
||||
|
||||
#
|
||||
# Copy the file to ensure the original retains the correct
|
||||
# permissions set by the System
|
||||
#
|
||||
my $tmp_shadow_path = "$shadow_path.tmp";
|
||||
cp("$shadow_path","$tmp_shadow_path");
|
||||
open(TMP, "<", $tmp_shadow_path) or die $!;
|
||||
open(SHADOW, ">", $shadow_path) or die $!;
|
||||
my $line;
|
||||
while(defined($line = <TMP>))
|
||||
{
|
||||
chomp $line;
|
||||
$line =~ s#^root:[^:]*:#root:$hash:#;
|
||||
print SHADOW "$line\n";
|
||||
}
|
||||
|
||||
#
|
||||
# Close the files and delete the temporary file
|
||||
#
|
||||
close(SHADOW);
|
||||
close(TMP);
|
||||
unlink($tmp_shadow_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
logprint("Failed to find /etc/passwd in the install.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
=begin doc
|
||||
|
||||
create a random "string"
|
||||
|
||||
=end doc
|
||||
|
||||
=cut
|
||||
|
||||
sub generatePassword {
|
||||
my $length = $_[0];
|
||||
my $possible = 'abcdefghijkmnpqrstuvwxyz23456789ABCDEFGHJKLMNPQRSTUVWXYZ';
|
||||
my $password = '';
|
||||
while (length($password) < $length) {
|
||||
$password .= substr($possible, (int(rand(length($possible)))), 1);
|
||||
}
|
||||
return $password
|
||||
}
|
||||
|
||||
|
||||
=begin doc
|
||||
@@ -4010,7 +4093,8 @@ sub END
|
||||
logprint( $IP_ADDRESSES );
|
||||
}
|
||||
logprint("\n");
|
||||
logprint("RSA Fingerprint : $host_rsa_key");
|
||||
logprint("\n\n");
|
||||
logprint("RSA Fingerprint : $host_rsa_key\n");
|
||||
logprint("Root Password : $PASSWORD\n");
|
||||
logprint("\n");
|
||||
}
|
||||
}
|
||||
|
||||
186
roles/passwd
186
roles/passwd
@@ -1,186 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
=head1 NAME
|
||||
|
||||
passwd - xen-tools role-script to setup root password for new guests.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Steve
|
||||
--
|
||||
http://www.steve.org.uk/
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Digest::MD5;
|
||||
use Expect;
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Get the arguments our role script was passed.
|
||||
#
|
||||
my( $prefix, $passwd ) = ( @ARGV );
|
||||
|
||||
#
|
||||
# Make sure they are valid.
|
||||
#
|
||||
if ( ! -d $prefix )
|
||||
{
|
||||
print "Prefix not found: $prefix\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( ! length( $passwd ) )
|
||||
{
|
||||
print "Password missing.\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Now make sure we have the module we require.
|
||||
#
|
||||
eval "use Expect;";
|
||||
if ( $@ )
|
||||
{
|
||||
print "Expect.pm not found. Aborting.\n";
|
||||
print "(For Debian systems run:\n\tapt-get install libexpect-perl\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# OK now we're good to go: Continue until it succeeds.
|
||||
#
|
||||
my $count = 0;
|
||||
while( $count < 10 )
|
||||
{
|
||||
changePassword( $prefix, $passwd );
|
||||
$count += 1;
|
||||
}
|
||||
|
||||
print "Failed to setup root password\n";
|
||||
print "-----------------------------\n";
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Don't look at this code.
|
||||
#
|
||||
# OK. Expect sometimes fails. It sucks.
|
||||
#
|
||||
# So how do we know if a password change operation fails? We take
|
||||
# an MD5(/etc/passwd + /etc/shadow) and if they don't change we've
|
||||
# failed.
|
||||
#
|
||||
# Upon success we will simply exit();
|
||||
#
|
||||
#
|
||||
sub changePassword
|
||||
{
|
||||
my ( $prefix, $passwd ) = ( @_ );
|
||||
|
||||
#
|
||||
# Find current checksum.
|
||||
#
|
||||
my $orig = checksum( $prefix );
|
||||
|
||||
#
|
||||
# Create the expect object.
|
||||
#
|
||||
my $exp = Expect->spawn( "/usr/sbin/chroot",
|
||||
$prefix,
|
||||
"/usr/bin/passwd",
|
||||
"root" )
|
||||
or die "Cannot spawn the password under chroot: $!\n";
|
||||
|
||||
# prompt
|
||||
unless ($exp->expect(5,"Enter new"))
|
||||
{
|
||||
print "Failed 1st prompt\n";
|
||||
$exp->hard_close();
|
||||
return;
|
||||
}
|
||||
|
||||
# send + wait.
|
||||
$exp->send( $passwd . "\n" );
|
||||
sleep( 1 );
|
||||
|
||||
# confirm
|
||||
unless ($exp->expect(5,"Retype new"))
|
||||
{
|
||||
print "Failed 2nd prompt\n";
|
||||
$exp->hard_close();
|
||||
return;
|
||||
}
|
||||
|
||||
# send.
|
||||
$exp->send( $passwd . "\n" );
|
||||
|
||||
|
||||
# Closeup.
|
||||
$exp->soft_close();
|
||||
|
||||
#
|
||||
# Did it work?
|
||||
#
|
||||
my $updated = checksum( $prefix );
|
||||
|
||||
if ( $updated ne $orig )
|
||||
{
|
||||
print "Password setup correctly.\n";
|
||||
exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
print "Setting password failed.\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Checksum /etc/passwd + /etc/shadow if they exist in the
|
||||
# given chroot()
|
||||
#
|
||||
sub checksum
|
||||
{
|
||||
my( $prefix ) = ( @_ );
|
||||
|
||||
my $sum = '';
|
||||
|
||||
foreach my $file ( qw! /etc/passwd /etc/shadow ! )
|
||||
{
|
||||
if ( -e $prefix . "/" . $file )
|
||||
{
|
||||
#
|
||||
# Open the file.
|
||||
#
|
||||
open(FILE, $prefix . "/" . $file)
|
||||
or die "Can¡Çt open ¡Ç$prefix/$file¡Ç: $!";
|
||||
binmode(FILE);
|
||||
|
||||
#
|
||||
# Add the data
|
||||
#
|
||||
my $md5 = Digest::MD5->new;
|
||||
while (<FILE>)
|
||||
{
|
||||
$md5->add($_);
|
||||
}
|
||||
close(FILE);
|
||||
|
||||
#
|
||||
# Update the sum
|
||||
#
|
||||
$sum .= $md5->b64digest;
|
||||
}
|
||||
}
|
||||
|
||||
return $sum;
|
||||
}
|
||||
Reference in New Issue
Block a user