Skip to content

Instantly share code, notes, and snippets.

@kidoman
Created January 16, 2013 10:24
Show Gist options
  • Save kidoman/4546175 to your computer and use it in GitHub Desktop.
Save kidoman/4546175 to your computer and use it in GitHub Desktop.
htpasswd-ssha script fixed to work in Ubuntu 12.04 Must run before using this script: sudo apt-get install libdigest-sha-perl sudo apt-get install libterm-readkey-perl
#!/usr/bin/perl
#########################################################################
# htpasswd-ssha is a replacement of the well known apache htpasswd.
# All written in pure perl, it allows you to crypt SSHA passowrd for
# nginx per example.
#
# Copyright (C) 2011 Guillaume Seigneuret (Omega Cube)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
#########################################################################
use strict;
use Fcntl;
use Getopt::Std;
use Digest::SHA;
use MIME::Base64;
use Term::ReadKey;
$|=1;
my $VERSION="0.2";
{
my (%opts, $pass, $pass2);
getopts('cnmdsD', \%opts);
my $createfile = 0;
my $createfile = 1 if defined($opts{'c'});
my $deleteuser = 1 if defined($opts{'D'});
my $method = "sha1";
my $filename = $ARGV[0] if defined($ARGV[0]);
defined($ARGV[1])? my $username = $ARGV[1]:die HELP_MESSAGE();
unless($deleteuser){
$pass = promptpass("Enter password: ");
$pass2 = promptpass("Enter password again: ");
die ("\n ERROR: Password missmatch\n") if ($pass ne $pass2);
}
if(defined $opts{'n'}){
print "$username:".hashthis($method, $pass)."\n";
exit 0;
}
exit update_ht($filename, $username, hashthis($method, $pass), $createfile, $deleteuser);
}
sub update_ht {
my ($filename, $username, $hashedPass, $createfile, $deleteuser) = @_;
#print "$hashedPass\n";
my $match = 0;
if($createfile) {
die ("File already exists!\n") if (-e $filename);
sysopen (FILE, $filename, O_RDWR|O_EXCL|O_CREAT, 0640);
die ("The file already exists or I wasn't able to write files :(") if ($_ != 0);
print FILE "$username:$hashedPass\n";
}
else {
die "Unable to open $filename : $!\t\n"
if(!open(FILE, "$filename"));
my %auth;
while(<FILE>){
$auth{$1}=$2 if $_ =~ /^(.*):(.*)$/;
}
close(FILE);
die "Unable to open $filename : $!\t\n"
if(!open(FILE, ">$filename"));
$auth{$username} = $hashedPass;
delete $auth{$username} if($deleteuser);
foreach my $user (sort keys %auth){
print FILE $user.":".$auth{$user}."\n";
}
}
close(FILE);
return 0;
}
sub promptpass {
my ($message) = @_;
my $pass;
print $message;
ReadMode 2; #noecho;
chomp($pass = <STDIN>);
ReadMode 0; #restore;
print "\n";
return $pass;
}
sub hashthis {
my ($method, $pass) = @_;
my $hash = Digest::SHA->new;
my $salt = get_salt();
$hash->add($pass);
$hash->add($salt);
my $hashedPasswd = '{SSHA}' . encode_base64($hash->digest . $salt ,'');
return $hashedPasswd;
#eturn "{SSHA}".$hash->b64digest.$salt;
}
sub get_salt {
my $rands = substr(time(),-4);
my $salt = ('a'..'z')[int(($rands/100)%26)];
$salt .= ('a'..'z')[int(($rands%100)%26)];
return($salt);
}
sub HELP_MESSAGE {
print "Usage:\n
htpasswd [-cmdsD] passwordfile username
htpasswd -n[mds] username
htpasswd -nb[mds] username password\n
-c Create a new file.
-n Don't update file; display results on stdout.
-m Force MD5 encryption of the password (not yet implemented).
-d Force CRYPT encryption of the password (not yet implemented).
-s Force SSHA encryption of the password (default).
-D Delete the specified user\n";
exit 1;
}
sub VERSION_MESSAGE {
print "htpasswd v$VERSION\n\n";
}
sub STANDARD_HELP_VERSION {
print "";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment