1#!/usr/bin/env perl 2 3## 4## Author......: See docs/credits.txt 5## License.....: MIT 6## 7 8use strict; 9use warnings; 10 11use Convert::EBCDIC qw (ascii2ebcdic); 12use Crypt::DES; 13 14sub module_constraints { [[0, 8], [1, 8], [-1, -1], [-1, -1], [-1, -1]] } 15 16sub racf_hash 17{ 18 my ($username, $password) = @_; 19 20 $username = substr ($username . " " x 8, 0, 8); 21 $password = substr ($password . " " x 8, 0, 8); 22 23 my $username_ebc = ascii2ebcdic ($username); 24 my $password_ebc = ascii2ebcdic ($password); 25 26 my @pw = split ("", $password_ebc); 27 28 for (my $i = 0; $i < 8; $i++) 29 { 30 $pw[$i] = unpack ("C", $pw[$i]); 31 $pw[$i] ^= 0x55; 32 $pw[$i] <<= 1; 33 $pw[$i] = pack ("C", $pw[$i] & 0xff); 34 } 35 36 my $key = join ("", @pw); 37 38 my $cipher = new Crypt::DES $key; 39 40 my $ciphertext = $cipher->encrypt ($username_ebc); 41 42 my $ct = unpack ("H16", $ciphertext); 43 44 return $ct; 45} 46 47sub module_generate_hash 48{ 49 my $word = shift; 50 my $salt = shift; 51 52 my $hash_buf = racf_hash (uc $salt, $word); 53 54 my $hash = sprintf ('$racf$*%s*%s', uc $salt, uc $hash_buf); 55 56 return $hash; 57} 58 59sub module_verify_hash 60{ 61 my $line = shift; 62 63 my @line_elements = split (":", $line); 64 65 return if scalar @line_elements < 2; 66 67 my $hash_in = shift @line_elements; 68 69 my $word = join (":", @line_elements); 70 71 # check signature 72 73 my @hash_elements = split ('\*', $hash_in); 74 75 return unless ($hash_elements[0] eq '$racf$'); 76 77 my $salt = $hash_elements[1]; 78 79 return unless defined $salt; 80 return unless defined $word; 81 82 $word = pack_if_HEX_notation ($word); 83 84 my $new_hash = module_generate_hash ($word, $salt); 85 86 return ($new_hash, $word); 87} 88 891; 90