summaryrefslogtreecommitdiffstats
path: root/scripts/Ssha2Passwd
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:49:46 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:49:46 +0000
commit50b37d4a27d3295a29afca2286f1a5a086142cec (patch)
tree9212f763934ee090ef72d823f559f52ce387f268 /scripts/Ssha2Passwd
parentInitial commit. (diff)
downloadfreeradius-50b37d4a27d3295a29afca2286f1a5a086142cec.tar.xz
freeradius-50b37d4a27d3295a29afca2286f1a5a086142cec.zip
Adding upstream version 3.2.1+dfsg.upstream/3.2.1+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'scripts/Ssha2Passwd')
-rwxr-xr-xscripts/Ssha2Passwd144
1 files changed, 144 insertions, 0 deletions
diff --git a/scripts/Ssha2Passwd b/scripts/Ssha2Passwd
new file mode 100755
index 0000000..65c23a4
--- /dev/null
+++ b/scripts/Ssha2Passwd
@@ -0,0 +1,144 @@
+#!/usr/bin/perl -w
+use strict;
+use Getopt::Long qw(:config no_ignore_case);
+use Pod::Usage;
+use Digest::SHA;
+use MIME::Base64;
+use Math::Random::Secure qw(irand);
+
+my %opts;
+GetOptions(\%opts,
+ qw[ help|?! man! f|format=s l|len=i s|salt=s S|Salt=s z|saltlen:i ]
+) or pod2usage(2);
+pod2usage(1) if $opts{help};
+pod2usage(-verbose => 2) if $opts{man};
+
+my $len = 256;
+if (exists $opts{l}) {
+ my @length = (224, 256, 384, 512);
+ if (grep {$_ eq $opts{l}} @length) {
+ $len = $opts{l};
+ } else {
+ print "Bad length\n";
+ exit(1);
+ }
+}
+
+sub fmt_base64 {
+ return encode_base64(shift, '')."\n";
+}
+
+sub fmt_hex {
+ return unpack('H*', shift)."\n";
+}
+
+sub fmt_bin {
+ return shift;
+}
+
+my $fmt = \&{'fmt_base64'};
+if (exists $opts{f}) {
+ my %format = ('m' => \&{'fmt_base64'}, 'base64' => \&{'fmt_base64'},
+ 'x' => \&{'fmt_hex'}, 'hex' => \&{'fmt_hex'},
+ 'b' => \&{'fmt_bin'}, 'bin' => \&{'fmt_bin'});
+ $fmt = $format{$opts{f}};
+ if (!defined $fmt) {
+ print "Bad format\n";
+ exit(1);
+ }
+}
+
+my $password = $ARGV[0];
+if (!defined $password) {
+ print "Missing password\n";
+ exit(1);
+}
+
+my $salt = $opts{s};
+if (exists $opts{S}) {
+ if (defined $salt) {
+ print "Redundant salt\n";
+ exit(1);
+ }
+ $salt = pack('H*', $opts{S});
+} elsif (!defined $salt and exists $opts{z}) {
+ my $ssiz = $opts{z};
+ if ($ssiz == 0) {
+ $ssiz = 8;
+ } elsif ($ssiz < 0) {
+ print "Bad salt length\n";
+ exit(1);
+ }
+ while ($ssiz >= 4) {
+ $salt .= pack('N', irand());
+ $ssiz -= 4;
+ }
+ $salt .= substr(pack('N', irand()), 1, $ssiz) if ($ssiz > 0);
+}
+
+my $ctx = Digest::SHA->new($len);
+$ctx->add($password);
+$ctx->add($salt) if (defined $salt);
+my $dig = $ctx->digest;
+$dig .= $salt if (defined $salt);
+
+print &$fmt($dig);
+
+__END__
+
+=head1 NAME
+
+ssha2passwd - Generate a SHA2 hashed password
+
+=head1 DESCRIPTION
+
+Hash the given password into a SHA2 digest with optional salt.
+
+=head1 SYNOPSIS
+
+ ssha2passwd [options] <password>
+
+=head1 OPTIONS
+
+=over
+
+=item B<-f> or B<-format> <format>
+
+Format options:
+
+=over
+
+=item B<m> or B<base64> : base64 encoded (default)
+
+=item B<x> or B<hex> : hexadecimal string
+
+=item B<b> or B<bin> : binary string
+
+=back
+
+=item B<-l> or B<-length> <length>
+
+Hash algorithm bit length (224, 256, 384, or 512 | default: 256).
+
+=item B<-s> or B<-salt> <string>
+
+=item B<-S> or B<-Salt> <hexadecimal string>
+
+Salt string appended to password and hashed. The resultant digest then
+has the salt string appended.
+
+=item B<-z> or B<-saltlen> [<length>]
+
+Byte length of random salt appended to password and hashed, if no salt
+string is explicitly given (0 is default, default: 8).
+
+=item B<-?> or B<-help>
+
+Print a brief help message.
+
+=item B<-man>
+
+Print the manual page.
+
+=back
+=cut