/ag-passwd
#!/usr/bin/perl
use AwesomeGrid::User;
use Crypt::PasswdMD5; # Linux, FreeBSD
use Digest::SHA1 qw/sha1_hex/; # OS X 10.4
use Crypt::Eksblowfish::Bcrypt; # OpenBSD
sub getsalt {
my $length = shift;
open RAND, "/dev/urandom"; # For production, this should be
# /dev/random
my $data;
read(RAND, $data, $length);
close RAND;
return $data;
}
sub unix_MD5 {
my $passwd = shift;
my $salt = unpack("h8",getsalt(8));
return unix_md5_crypt($passwd, $salt);
}
sub apache_MD5 {
my $passwd = shift;
my $salt = unpack("h8",getsalt(8));
return apache_md5_crypt($passwd, $salt);
}
sub OSX_SHA1 {
my $passwd = shift;
my $v = getsalt(4);
my $hash = sha1_hex("$v$passwd");
my $salt = unpack("H8",$v);
return uc("$salt$hash");
}
sub OpenBSD_Bcrypt {
my $passwd = shift;
my $salt = Crypt::Eksblowfish::Bcrypt::en_base64(getsalt(16));
my $p = Crypt::Eksblowfish::Bcrypt::bcrypt($passwd, '$2a$08$' . $salt);
return $p;
}
my $user;
if (exists $ENV{SUDO_USER}) {
$user = $ENV{SUDO_USER};
} else {
$user = shift;
if (!$user) {
if ($> == 0) {
print "When used by root, you must specify a username\n";
} else {
chomp(my $sudo = `which sudo`);
if ($sudo) {
print "Attempting to sudo myself...\n";
exec "$sudo $0";
} else {
print "You are not root and you don't have sudo installed. Sorry.\n";
}
}
exit 1;
}
}
if (!AwesomeGrid::User::exists($user)) {
print "User $user does not exist\n";
exit 1;
}
print "Changing password for $user\n";
my $aguser = AwesomeGrid::User->load($user) || exit 1;
# Restore sanity in case of emergency
END { system("stty echo") }
system("stty -echo");
print STDERR "New Password: ";
my $passwd1 = <STDIN>;
chomp $passwd1;
print STDERR "\n";
print STDERR "Repeat new password: ";
my $passwd2 = <STDIN>;
chomp $passwd2;
print STDERR "\n";
system("stty echo");
if ($passwd1 != $passwd1) {
print "Passwords don't match.\n";
exit 1;
}
$aguser->{'passwd-unix-md5'} = unix_MD5($passwd1);
$aguser->{'passwd-apache-md5'} = apache_MD5($passwd1);
$aguser->{'passwd-osx-sha1'} = OSX_SHA1($passwd1);
$aguser->{'passwd-bcrypt'} = OpenBSD_Bcrypt($passwd1);
$aguser->save();
print "Password updated.\n";