1# 2# Samba LM/NT Hash Generating Library. 3# Slightly modified to fit in with Webmin 4# 5# Copyright(C) 2001 Benjamin Kuit <bj@it.uts.edu.au> 6# 7 8# Works out if local system has the module Digest::MD4, and uses it 9# if it does, otherwise uses ported version of the md4 algorithm 10# Performance is a lot better with Digest::MD4, so its recommended to 11# get Digest::MD4 installed if you intend to generate a lot of hashes 12# in a small amount of time. 13my $HaveDigestMD4; 14 15BEGIN { 16 $HaveDigestMD4 = 0; 17 if ( eval "require 'Digest/MD4.pm';" ) { 18 $HaveDigestMD4 = 1; 19 } 20} 21 22# lmhash PASSWORD 23# Generates lanman password hash for a given password, returns the hash 24# 25# Extracted and ported from SAMBA/source/libsmb/smbencrypt.c:nt_lm_owf_gen 26sub lmhash($) { 27 my ( $pass ) = @_; 28 my ( @p16 ); 29 30 $pass = substr($pass||"",0,129); 31 $pass =~ tr/a-z/A-Z/; 32 $pass = substr($pass,0,14); 33 @p16 = E_P16($pass); 34 return join("", map {sprintf("%02X",$_);} @p16); 35} 36 37# nthash PASSWORD 38# Generates nt md4 password hash for a given password, returns the hash 39# 40# Extracted and ported from SAMBA/source/libsmb/smbencrypt.c:nt_lm_owf_gen 41sub nthash($) { 42 my ( $pass ) = @_; 43 my ( $hex ); 44 my ( $digest ); 45 $pass = substr($pass||"",0,128); 46 $pass =~ s/(.)/$1\000/sg; 47 $hex = ""; 48 if ( $HaveDigestMD4 ) { 49 eval { 50 $digest = new Digest::MD4; 51 $digest->reset(); 52 $digest->add($pass); 53 $hex = $digest->hexdigest(); 54 $hex =~ tr/a-z/A-Z/; 55 }; 56 $HaveDigestMD4 = 0 unless ( $hex ); 57 } 58 $hex = sprintf("%02X"x16,mdfour($pass)) unless ( $hex ); 59 return $hex; 60} 61 62# ntlmgen PASSWORD, LMHASH, NTHASH 63# Generate lanman and nt md4 password hash for given password, and assigns 64# values to arguments. Combined function of lmhash and nthash 65sub ntlmgen { 66 my ( $nthash, $lmhash ); 67 $nthash = nthash($_[0]); 68 $lmhash = lmhash($_[0]); 69 if ( $#_ == 2 ) { 70 $_[1] = $lmhash; 71 $_[2] = $nthash; 72 } 73 return ( $lmhash, $nthash ); 74} 75 76# Support functions 77# Ported from SAMBA/source/lib/md4.c:F,G and H respectfully 78sub F { my ( $X, $Y, $Z ) = @_; return ($X&$Y) | ((~$X)&$Z); } 79sub G { my ( $X, $Y, $Z) = @_; return ($X&$Y) | ($X&$Z) | ($Y&$Z); } 80sub H { my ($X, $Y, $Z) = @_; return $X^$Y^$Z; } 81 82# Needed? because perl seems to choke on overflowing when doing bitwise 83# operations on numbers larger than 32 bits. Well, it did on my machine =) 84sub add32 { 85 my ( @v ) = @_; 86 my ( $ret, @sum ); 87 foreach ( @v ) { 88 $_ = [ ($_&0xffff0000)>>16, ($_&0xffff) ]; 89 } 90 @sum = (); 91 foreach ( @v ) { 92 $sum[0] += $_->[0]; 93 $sum[1] += $_->[1]; 94 } 95 $sum[0] += ($sum[1]&0xffff0000)>>16; 96 $sum[1] &= 0xffff; 97 $sum[0] &= 0xffff; 98 $ret = ($sum[0]<<16) | $sum[1]; 99 return $ret; 100} 101# Ported from SAMBA/source/lib/md4.c:lshift 102# Renamed to prevent clash with SAMBA/source/libsmb/smbdes.c:lshift 103sub md4lshift { 104 my ($x, $s) = @_; 105 $x &= 0xFFFFFFFF; 106 return (($x<<$s)&0xFFFFFFFF) | ($x>>(32-$s)); 107} 108# Ported from SAMBA/source/lib/md4.c:ROUND1 109sub ROUND1 { 110 my($a,$b,$c,$d,$k,$s,@X) = @_; 111 $_[0] = md4lshift(add32($a,F($b,$c,$d),$X[$k]), $s); 112 return $_[0]; 113} 114# Ported from SAMBA/source/lib/md4.c:ROUND2 115sub ROUND2 { 116 my ($a,$b,$c,$d,$k,$s,@X) = @_; 117 $_[0] = md4lshift(add32($a,G($b,$c,$d),$X[$k],0x5A827999), $s); 118 return $_[0]; 119} 120# Ported from SAMBA/source/lib/md4.c:ROUND3 121sub ROUND3 { 122 my ($a,$b,$c,$d,$k,$s,@X) = @_; 123 $_[0] = md4lshift(add32($a,H($b,$c,$d),$X[$k],0x6ED9EBA1), $s); 124 return $_[0]; 125} 126# Ported from SAMBA/source/lib/md4.c:mdfour64 127sub mdfour64 { 128 my ( $A, $B, $C, $D, @M ) = @_; 129 my ( $AA, $BB, $CC, $DD ); 130 my ( @X ); 131 @X = (map { $_?$_:0 } @M)[0..15]; 132 $AA=$A; $BB=$B; $CC=$C; $DD=$D; 133 ROUND1($A,$B,$C,$D, 0, 3, @X); ROUND1($D,$A,$B,$C, 1, 7, @X); 134 ROUND1($C,$D,$A,$B, 2, 11, @X); ROUND1($B,$C,$D,$A, 3, 19, @X); 135 ROUND1($A,$B,$C,$D, 4, 3, @X); ROUND1($D,$A,$B,$C, 5, 7, @X); 136 ROUND1($C,$D,$A,$B, 6, 11, @X); ROUND1($B,$C,$D,$A, 7, 19, @X); 137 ROUND1($A,$B,$C,$D, 8, 3, @X); ROUND1($D,$A,$B,$C, 9, 7, @X); 138 ROUND1($C,$D,$A,$B, 10, 11, @X); ROUND1($B,$C,$D,$A, 11, 19, @X); 139 ROUND1($A,$B,$C,$D, 12, 3, @X); ROUND1($D,$A,$B,$C, 13, 7, @X); 140 ROUND1($C,$D,$A,$B, 14, 11, @X); ROUND1($B,$C,$D,$A, 15, 19, @X); 141 ROUND2($A,$B,$C,$D, 0, 3, @X); ROUND2($D,$A,$B,$C, 4, 5, @X); 142 ROUND2($C,$D,$A,$B, 8, 9, @X); ROUND2($B,$C,$D,$A, 12, 13, @X); 143 ROUND2($A,$B,$C,$D, 1, 3, @X); ROUND2($D,$A,$B,$C, 5, 5, @X); 144 ROUND2($C,$D,$A,$B, 9, 9, @X); ROUND2($B,$C,$D,$A, 13, 13, @X); 145 ROUND2($A,$B,$C,$D, 2, 3, @X); ROUND2($D,$A,$B,$C, 6, 5, @X); 146 ROUND2($C,$D,$A,$B, 10, 9, @X); ROUND2($B,$C,$D,$A, 14, 13, @X); 147 ROUND2($A,$B,$C,$D, 3, 3, @X); ROUND2($D,$A,$B,$C, 7, 5, @X); 148 ROUND2($C,$D,$A,$B, 11, 9, @X); ROUND2($B,$C,$D,$A, 15, 13, @X); 149 ROUND3($A,$B,$C,$D, 0, 3, @X); ROUND3($D,$A,$B,$C, 8, 9, @X); 150 ROUND3($C,$D,$A,$B, 4, 11, @X); ROUND3($B,$C,$D,$A, 12, 15, @X); 151 ROUND3($A,$B,$C,$D, 2, 3, @X); ROUND3($D,$A,$B,$C, 10, 9, @X); 152 ROUND3($C,$D,$A,$B, 6, 11, @X); ROUND3($B,$C,$D,$A, 14, 15, @X); 153 ROUND3($A,$B,$C,$D, 1, 3, @X); ROUND3($D,$A,$B,$C, 9, 9, @X); 154 ROUND3($C,$D,$A,$B, 5, 11, @X); ROUND3($B,$C,$D,$A, 13, 15, @X); 155 ROUND3($A,$B,$C,$D, 3, 3, @X); ROUND3($D,$A,$B,$C, 11, 9, @X); 156 ROUND3($C,$D,$A,$B, 7, 11, @X); ROUND3($B,$C,$D,$A, 15, 15, @X); 157 # We want to change the arguments, so assign them to $_[0] markers 158 # rather than to $A..$D 159 $_[0] = add32($A,$AA); $_[1] = add32($B,$BB); 160 $_[2] = add32($C,$CC); $_[3] = add32($D,$DD); 161 @X = map { 0 } (1..16); 162} 163 164# Ported from SAMBA/source/lib/md4.c:copy64 165sub copy64 { 166 my ( @in ) = @_; 167 my ( $i, @M ); 168 for $i ( 0..15 ) { 169 $M[$i] = ($in[$i*4+3]<<24) | ($in[$i*4+2]<<16) | 170 ($in[$i*4+1]<<8) | ($in[$i*4+0]<<0); 171 } 172 return @M; 173} 174# Ported from SAMBA/source/lib/md4.c:copy4 175sub copy4 { 176 my ( $x ) = @_; 177 my ( @out ); 178 $out[0] = $x&0xFF; 179 $out[1] = ($x>>8)&0xFF; 180 $out[2] = ($x>>16)&0xFF; 181 $out[3] = ($x>>24)&0xFF; 182 @out = map { $_?$_:0 } @out; 183 return @out; 184} 185# Ported from SAMBA/source/lib/md4.c:mdfour 186sub mdfour { 187 my ( @in ) = unpack("C*",$_[0]); 188 my ( $b, @A, @M, @buf, @out ); 189 $b = scalar @in * 8; 190 @A = ( 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 ); 191 while (scalar @in > 64 ) { 192 @M = copy64( @in ); 193 mdfour64( @A, @M ); 194 @in = @in[64..$#in]; 195 } 196 @buf = ( @in, 0x80, map {0} (1..128) )[0..127]; 197 if ( scalar @in <= 55 ) { 198 @buf[56..59] = copy4( $b ); 199 @M = copy64( @buf ); 200 mdfour64( @A, @M ); 201 } 202 else { 203 @buf[120..123] = copy4( $b ); 204 @M = copy64( @buf ); 205 mdfour64( @A, @M ); 206 @M = copy64( @buf[64..$#buf] ); 207 mdfour64( @A, @M ); 208 } 209 @out[0..3] = copy4($A[0]); 210 @out[4..7] = copy4($A[1]); 211 @out[8..11] = copy4($A[2]); 212 @out[12..15] = copy4($A[3]); 213 return @out; 214} 215# Contants used in lanlam hash calculations 216# Ported from SAMBA/source/libsmb/smbdes.c:perm1[56] 217my @perm1 = (57, 49, 41, 33, 25, 17, 9, 218 1, 58, 50, 42, 34, 26, 18, 219 10, 2, 59, 51, 43, 35, 27, 220 19, 11, 3, 60, 52, 44, 36, 221 63, 55, 47, 39, 31, 23, 15, 222 7, 62, 54, 46, 38, 30, 22, 223 14, 6, 61, 53, 45, 37, 29, 224 21, 13, 5, 28, 20, 12, 4); 225# Ported from SAMBA/source/libsmb/smbdes.c:perm2[48] 226my @perm2 = (14, 17, 11, 24, 1, 5, 227 3, 28, 15, 6, 21, 10, 228 23, 19, 12, 4, 26, 8, 229 16, 7, 27, 20, 13, 2, 230 41, 52, 31, 37, 47, 55, 231 30, 40, 51, 45, 33, 48, 232 44, 49, 39, 56, 34, 53, 233 46, 42, 50, 36, 29, 32); 234# Ported from SAMBA/source/libsmb/smbdes.c:perm3[64] 235my @perm3 = (58, 50, 42, 34, 26, 18, 10, 2, 236 60, 52, 44, 36, 28, 20, 12, 4, 237 62, 54, 46, 38, 30, 22, 14, 6, 238 64, 56, 48, 40, 32, 24, 16, 8, 239 57, 49, 41, 33, 25, 17, 9, 1, 240 59, 51, 43, 35, 27, 19, 11, 3, 241 61, 53, 45, 37, 29, 21, 13, 5, 242 63, 55, 47, 39, 31, 23, 15, 7); 243# Ported from SAMBA/source/libsmb/smbdes.c:perm4[48] 244my @perm4 = ( 32, 1, 2, 3, 4, 5, 245 4, 5, 6, 7, 8, 9, 246 8, 9, 10, 11, 12, 13, 247 12, 13, 14, 15, 16, 17, 248 16, 17, 18, 19, 20, 21, 249 20, 21, 22, 23, 24, 25, 250 24, 25, 26, 27, 28, 29, 251 28, 29, 30, 31, 32, 1); 252# Ported from SAMBA/source/libsmb/smbdes.c:perm5[32] 253my @perm5 = ( 16, 7, 20, 21, 254 29, 12, 28, 17, 255 1, 15, 23, 26, 256 5, 18, 31, 10, 257 2, 8, 24, 14, 258 32, 27, 3, 9, 259 19, 13, 30, 6, 260 22, 11, 4, 25); 261# Ported from SAMBA/source/libsmb/smbdes.c:perm6[64] 262my @perm6 =( 40, 8, 48, 16, 56, 24, 64, 32, 263 39, 7, 47, 15, 55, 23, 63, 31, 264 38, 6, 46, 14, 54, 22, 62, 30, 265 37, 5, 45, 13, 53, 21, 61, 29, 266 36, 4, 44, 12, 52, 20, 60, 28, 267 35, 3, 43, 11, 51, 19, 59, 27, 268 34, 2, 42, 10, 50, 18, 58, 26, 269 33, 1, 41, 9, 49, 17, 57, 25); 270# Ported from SAMBA/source/libsmb/smbdes.c:sc[16] 271my @sc = (1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1); 272# Ported from SAMBA/source/libsmb/smbdes.c:sbox[8][4][16] 273# Side note, I used cut and paste for all these numbers, I did NOT 274# type them all in =) 275my @sbox = ([[14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7], 276 [ 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8], 277 [ 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0], 278 [15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]], 279 [[15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10], 280 [ 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5], 281 [ 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15], 282 [13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]], 283 [[10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8], 284 [13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1], 285 [13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7], 286 [ 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12]], 287 [[ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15], 288 [13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9], 289 [10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4], 290 [ 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]], 291 [[ 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9], 292 [14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6], 293 [ 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14], 294 [11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3]], 295 [[12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11], 296 [10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8], 297 [ 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6], 298 [ 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]], 299 [[ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1], 300 [13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6], 301 [ 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2], 302 [ 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]], 303 [[13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7], 304 [ 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2], 305 [ 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8], 306 [ 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]]); 307 308# Ported from SAMBA/source/libsmb/smbdes.c:xor 309# Hack: Split arguments in half and then xor's first half of arguments to 310# second half of arguments. Probably proper way of doing this would 311# be to used referenced variables 312sub mxor { 313 my ( @in ) = @_; 314 my ( $i, $off, @ret ); 315 $off = int($#in/2); 316 for $i ( 0..$off ) { 317 $ret[$i] = $in[$i] ^ $in[$i+$off+1]; 318 } 319 return @ret; 320} 321 322# Ported from SAMBA/source/libsmb/smbdes.c:str_to_key 323sub str_to_key { 324 my ( @str ) = @_; 325 my ( $i, @key ); 326 @str = map { $_?$_:0 } @str; 327 $key[0] = $str[0]>>1; 328 $key[1] = (($str[0]&0x01)<<6) | ($str[1]>>2); 329 $key[2] = (($str[1]&0x03)<<5) | ($str[2]>>3); 330 $key[3] = (($str[2]&0x07)<<4) | ($str[3]>>4); 331 $key[4] = (($str[3]&0x0F)<<3) | ($str[4]>>5); 332 $key[5] = (($str[4]&0x1F)<<2) | ($str[5]>>6); 333 $key[6] = (($str[5]&0x3F)<<1) | ($str[6]>>7); 334 $key[7] = $str[6]&0x7F; 335 for $i (0..7) { 336 $key[$i] = ($key[$i]<<1); 337 } 338 return @key; 339} 340# Ported from SAMBA/source/libsmb/smbdes.c:permute 341# Would probably be better to pass in by reference 342sub permute { 343 my ( @a ) = @_; 344 my ( $i, $n, @in, @p, @out ); 345 346 # Last argument is the count of the perm values 347 $n = $a[$#a]; 348 @in = @a[0..($#a-$n-1)]; 349 @p = @_[($#a-$n)..($#a-1)]; 350 351 for $i ( 0..($n-1) ) { 352 $out[$i] = $in[$p[$i]-1]?1:0; 353 } 354 return @out; 355} 356 357# Ported from SAMBA/source/libsmb/smbdes.c:lshift 358# Lazy shifting =) 359sub lshift { 360 my ( $count, @d ) = @_; 361 $count %= ($#d+1); 362 @d = (@d,@d)[$count..($#d+$count)]; 363 return @d; 364} 365 366# Ported from SAMBA/source/libsmb/smbdes.c:dohash 367sub dohash { 368 my ( @a ) = @_; 369 my ( @in, @key, $forw, @pk1, @c, @d, @ki, @cd, $i, @pd1, @l, @r, @rl, @out ); 370 371 @in = @a[0..63]; 372 @key = @a[64..($#_-1)]; 373 $forw = $a[$#a]; 374 375 @pk1 = permute( @key, @perm1, 56 ); 376 377 @c = @pk1[0..27]; 378 @d = @pk1[28..55]; 379 380 for $i ( 0..15 ) { 381 @c = lshift( $sc[$i], @c ); 382 @d = lshift( $sc[$i], @d ); 383 384 @cd = map { $_?1:0 } ( @c, @d ); 385 $ki[$i] = [ permute( @cd, @perm2, 48 ) ]; 386 } 387 388 @pd1 = permute( @in, @perm3, 64 ); 389 390 @l = @pd1[0..31]; 391 @r = @pd1[32..63]; 392 393 for $i ( 0..15 ) { 394 my ( $j, $k, @b, @er, @erk, @cb, @pcb, @r2 ); 395 @er = permute( @r, @perm4, 48 ); 396 @erk = mxor(@er, @{ @ki[$forw?$i:(15-$i)] }); 397 398 for $j ( 0..7 ) { 399 for $k ( 0..5 ) { 400 $b[$j][$k] = $erk[$j*6 + $k]; 401 } 402 } 403 for $j ( 0..7 ) { 404 my ( $m, $n ); 405 $m = ($b[$j][0]<<1) | $b[$j][5]; 406 $n = ($b[$j][1]<<3) | ($b[$j][2]<<2) | ($b[$j][3]<<1) | $b[$j][4]; 407 408 for $k ( 0..3 ) { 409 $b[$j][$k]=($sbox[$j][$m][$n] & (1<<(3-$k)))?1:0; 410 } 411 } 412 for $j ( 0..7 ) { 413 for $k ( 0..3 ) { 414 $cb[$j*4+$k]=$b[$j][$k]; 415 } 416 } 417 @pcb = permute( @cb, @perm5, 32); 418 @r2 = mxor(@l,@pcb); 419 @l = @r[0..31]; 420 @r = @r2[0..31]; 421 } 422 @rl = ( @r, @l ); 423 @out = permute( @rl, @perm6, 64 ); 424 return @out; 425} 426 427# Ported from SAMBA/source/libsmb/smbdes.c:smbhash 428sub smbhash{ 429 my ( @in, @key, $forw, @outb, @out, @inb, @keyb, @key2, $i ); 430 @in = @_[0..7]; 431 @key = @_[8..14]; 432 $forw = $_[$#_]; 433 434 @key2 = str_to_key(@key); 435 436 for $i ( 0..63 ) { 437 $inb[$i] = ( $in[$i/8] & (1<<(7-($i%8)))) ? 1:0; 438 $keyb[$i] = ( $key2[$i/8] & (1<<(7-($i%8)))) ? 1:0; 439 $outb[$i] = 0; 440 } 441 @outb = dohash(@inb,@keyb,$forw); 442 for $i ( 0..7 ) { 443 $out[$i] = 0; 444 } 445 for $i ( 0..64 ) { 446 if ( $outb[$i] ) { 447 $out[$i/8] |= (1<<(7-($i%8))); 448 } 449 } 450 return @out; 451} 452 453# Ported from SAMBA/source/libsmb/smbdes.c:E_P16 454sub E_P16 { 455 my ( @p16, @p14, @sp8 ); 456 @p16 = map { 0 } (1..16); 457 @p14 = unpack("C*",$_[0]); 458 @sp8 = ( 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 ); 459 @p16 = (smbhash(@sp8,@p14[0..6],1),smbhash(@sp8,@p14[7..13],1)); 460 return @p16; 461} 462 4631; 464 465__END__ 466 467=head1 NAME 468 469Crypt::SmbHash - Perl-only implementation of lanman and nt md4 hash functions, for use in Samba style smbpasswd entries 470 471=head1 SYNOPSIS 472 473 use Crypt::SmbHash; 474 475 ntlmgen SCALAR, LMSCALAR, NTSCALAR; 476 477=head1 DESCRIPTION 478 479This module generates Lanman and NT MD4 style password hashes, using 480perl-only code for portability. The module aids in the administration 481of Samba style systems. 482 483In the Samba distribution, authentication is referred to a private 484smbpasswd file. Entries have similar forms to the following: 485 486username:unixuid:LM:NT 487 488Where LM and NT are one-way password hashes of the same password. 489 490ntlmgen generates the hashes given in the first argument, and places 491the result in the second and third arguments. 492 493Example: 494To generate a smbpasswd entry: 495 496 #!/usr/local/bin/perl 497 use Crypt::SmbHash; 498 $username = $ARGV[0]; 499 $password = $ARGV[1]; 500 if ( !$password ) { 501 print "Not enough arguments\n"; 502 print "Usage: $0 username password\n"; 503 exit 1; 504 } 505 $uid = (getpwnam($username))[2]; 506 my ($login,undef,$uid) = getpwnam($ARGV[0]); 507 ntlmgen $password, $lm, $nt; 508 printf "%s:%d:%s:%s:[%-11s]:LCT-%08X\n", $login, $uid, $lm, $nt, "U", time; 509 510 511ntlmgen returns returns the hash values in a list context, so the alternative 512method of using it is: 513 514 ( $lm, $nt ) = ntlmgen $password; 515 516The functions lmhash and nthash are used by ntlmgen to generate the 517hashes, and are available when requested: 518 519 use Crypt::SmbHash qw(lmhash nthash) 520 $lm = lmhash($pass); 521 $nt = nthash($pass); 522 523=head1 MD4 524 525The algorithm used in nthash requires the md4 algorithm. This algorithm 526is included in this module for completeness, but because it is written 527in all-perl code ( rather than in C ), it's not very quick. 528 529However if you have the Digest::MD4 module installed, Crypt::SmbHash will 530try to use that module instead, making it much faster. 531 532A simple test compared calling nthash without Digest::MD4 installed, and 533with, this showed that using nthash on a system with Digest::MD4 installed 534proved to be over 90 times faster. 535 536=head1 AUTHOR 537 538Ported from Samba by Benjamin Kuit <lt>bj@it.uts.edu.au<gt>. 539 540Samba is Copyright(C) Andrew Tridgell 1997-1998 541 542Because this module is a direct port of code within the Samba 543distribution, it follows the same license, that is: 544 545 This program is free software; you can redistribute it and/or modify 546 it under the terms of the GNU General Public License as published by 547 the Free Software Foundation; either version 2 of the License, or 548 (at your option) any later version. 549 550 This program is distributed in the hope that it will be useful, 551 but WITHOUT ANY WARRANTY; without even the implied warranty of 552 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 553 GNU General Public License for more details. 554 555=cut 556