[Refdb-cvs] CVS: perlmod/RefDBClient Client.pm,1.9,1.10
Status: Beta
Brought to you by:
mhoenicka
From: Markus H. <mho...@us...> - 2005-01-22 01:11:30
|
Update of /cvsroot/refdb/perlmod/RefDBClient In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20369 Modified Files: Client.pm Log Message: implemented password encryption in Perl Index: Client.pm =================================================================== RCS file: /cvsroot/refdb/perlmod/RefDBClient/Client.pm,v retrieving revision 1.9 retrieving revision 1.10 diff -u -U2 -r1.9 -r1.10 --- Client.pm 17 Feb 2004 22:44:44 -0000 1.9 +++ Client.pm 22 Jan 2005 01:11:04 -0000 1.10 @@ -191,4 +191,257 @@ ###################################################################### ###################################################################### +## defines a helper class for password encryption + +package RefDBClient::Enigma; + +use strict; +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); + + +=head2 new + +Title : new + +Usage : $enigma = new RefDBClient::Enigma; + +Function: creates a new Enigma element + +=cut + +###################################################################### +## new(): creates a new Enigma element +###################################################################### +sub new() { + my $class = shift; + my $self = {}; + + ## the buffer that holds the raw password string + $self->{rawpass} = undef; + + ## the buffer that receives the encoded password string + $self->{encodedpass} = undef; + + ## the buffer that receives the numberized encoded password string + $self->{numberpass} = undef; + + ## the buffer that holds the scramble string + $self->{scramble} = undef; + + ## this array maps the available rotors 0-2 to the slots 0-2 + @{$self->{rotormap}} = (); + + ## this array holds the rotor positions for the rotors in the slots 0-2 + @{$self->{rotorpos}} = (); + + ## the rotor wirings for the rotors 0-2 + @{$self->{rotor}} = ( + # Input "!\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" + ["0", "u", "V", "`", "\$", "/", "z", "G", "7", "3", "L", "a", "*", "N", "[", ";", "U", "F", "Z", "^", "l", "t", "m", "{", "]", "\"", "s", "=", "b", "Q", "+", "?", "O", "A", "g", "w", "T", "5", "c", "W", "v", "#", "~", "}", ")", "o", "M", "S", "\'", "_", "\\", "@", "K", "(", "d", "D", "p", "|", "y", "8", "B", "%", "Y", "x", "J", "2", ":", "9", "&", "r", "4", "!", "k", "f", "-", "j", ".", "h", "1", "6", "I", "C", "i", ",", "R", "n", "e", "<", "E", "P", "q", ">", "X", "H"], # 0 + ["E", "P", "l", "b", "(", "S", "O", "\'", "D", "p", "|", "y", "8", "B", "x", "t", "J", "2", ":", "j", ".", "h", "f", "-", "I", "C", "i", ",", "R", "n", "e", "0", "G", "\"", "1", "6", "9", "&", "%", "Y", "_", "\\", "k", "7", "3", "u", "V", "\$", "/", "z", "N", "@", "F", "Z", "^", "m", "{", "]", "s", "w", "X", "U", "T", "5", "c", "W", "v", "#", "=", "H", "q", "r", "4", "!", "[", ";", "<", ">", "g", "~", "}", ")", "Q", "+", "L", "a", "*", "d", "?", "A", "K", "`", "o", "M"], # 1 + ["r", "4", "!", "[", ";", "<", "/", "z", "\$", "s", "`", "w", "X", "U", "T", "q", "{", "]", ">", "S", "5", ")", "@", "F", "Z", "Q", "D", "M", "|", "y", "8", "c", "W", "0", "G", "\"", "u", "v", "R", "Y", "_", "\\", "#", "=", "p", "a", "*", "d", "?", "A", "K", "+", "L", "E", "P", "l", "b", "(", "\'", "H", "1", "6", "t", "J", "2", ":", "j", ".", "n", "e", "9", "&", "%", "h", "f", "-", "I", "C", "i", "m", "o", "B", "x", ",", "k", "7", "O", "3", "V", "g", "~", "}", "N", "^"] # 2 + ); + + # the reflector array must be symmetrical, e.g. if ! maps to /, / must also map to ! + @{$self->{reflector}} = ( + "/", "-", "Q", "=", "~", "E", "1", ".", "6", "4", "2", "H", "\"", "(", "!", "?", "\'", "+", "X", "*", ">", ")", "S", "c", "v", "@", "<", ";", "\$", "5", "0", ":", "R", "u", "n", "Z", "&", "r", "{", ",", "Y", "M", "s", "p", "J", "^", "z", "q", "#", "A", "7", "g", "\\", "f", "h", "3", "I", "D", "e", "U", "}", "N", "y", "w", "d", "o", "8", "a", "[", "V", "T", "W", "|", "m", "x", "t", "j", "C", "b", "L", "P", "F", "K", "l", "B", "9", "`", "k", "_", "O", "G", "i", "]", "%" + ); + + bless $self, $class; + return $self; +} + +###################################################################### +## init(): set the parameters +## Arguments: - raw password +## - scramble string +###################################################################### +sub init { + my ($self, $rawpass, $scramble) = @_; + + $self->{rawpass} = $rawpass; + $self->{scramble} = $scramble; +} + +###################################################################### +## get_pass(): get the numberized encoded password +###################################################################### +sub get_pass { + my ($self) = @_; + + return $self->{numberpass}; +} + +###################################################################### +## eenc(): encode or decode a password string +## returns the numberized encoded password +###################################################################### +sub eenc { + my ($self) = @_; + + # set initial wheel sequence and wheel positions + $self->_set_wheels(); + + # split the raw password into individual characters + my @pw = split(/ */, $self->{rawpass}); + + my $scrambledchar = undef; + + # this array will receive the permuted characters + my @encchar = (); + + # loop over all characters in the raw password + foreach my $pwchar (@pw) { + + # first send the character through all rotors in the forward direction + $scrambledchar = $self->_wheel($pwchar, 0); + $scrambledchar = $self->_wheel($scrambledchar, 1); + $scrambledchar = $self->_wheel($scrambledchar, 2); + + # send the character through the reflector + $scrambledchar = $self->_reflect($scrambledchar); + + # send the character through all rotors in the reverse direction + $scrambledchar = $self->_rwheel($scrambledchar, 2); + $scrambledchar = $self->_rwheel($scrambledchar, 1); + $scrambledchar = $self->_rwheel($scrambledchar, 0); + + # advance all wheels one position + $self->_move_wheels(); + + # add the permuted character to the encoded password + push @encchar, $scrambledchar; + } + + # glue the permuted characters together + $self->{encodedpass} = join('', @encchar); + + # numberize the encoded password and return it + $self->_numberize(); +} + +###################################################################### +## _set_wheels(): set the wheel position +###################################################################### +sub _set_wheels { + my ($self) = @_; + + # sanity check + if (length($self->{scramble}) < 12) { + return 1; + } + + # use first three characters of the scramble string as rotor map + $self->{rotormap}[0] = ord(substr($self->{scramble}, 0, 1)) - 48; + $self->{rotormap}[1] = ord(substr($self->{scramble}, 1, 1)) - 48; + $self->{rotormap}[2] = ord(substr($self->{scramble}, 2, 1)) - 48; + + # slot values must be between 0 and 2 and we don't use + # a wheel twice + if ($self->{rotormap}[0] == $self->{rotormap}[1] + || $self->{rotormap}[1] == $self->{rotormap}[2] + || $self->{rotormap}[0] == $self->{rotormap}[2] + || $self->{rotormap}[0] < 0 + || $self->{rotormap}[0] > 2 + || $self->{rotormap}[1] < 0 + || $self->{rotormap}[1] > 2 + || $self->{rotormap}[2] < 0 + || $self->{rotormap}[2] > 2) { + return 1; + } + + # loop over slots + foreach my $i (0 .. 2) { + # retrieve wheel positions from scramble string + $self->{rotorpos}->[$i] = substr($self->{scramble}, ($i*3)+4, 2); + if ($self->{rotorpos}->[$i] < 0 + || $self->{rotorpos}->[$i] > 94) { + return 1; # out of range + } + } + + return 0; +} + +###################################################################### +## _wheel(): performs character permutation on a wheel in the forward +## direction +###################################################################### +sub _wheel { + my ($self, $char, $wheel) = @_; + + my $outchar = undef; + + $outchar = $self->{rotor}[$self->{rotormap}[$wheel]][(ord($char)-33+$self->{rotorpos}->[$wheel]) % 94]; + + return $outchar; +} + +###################################################################### +## _reflect(): performs character permutation on the reflector +###################################################################### +sub _reflect { + my ($self, $char) = @_; + + my $outchar = undef; + my $conv = ord($char)-33; + + $outchar = $self->{reflector}[ord($char)-33]; +} + + +###################################################################### +## _rwheel(): performs character permutation on a wheel in the reverse +## direction +###################################################################### +sub _rwheel { + my ($self, $char, $wheel) = @_; + + my $outchar = undef; + my $charindex = 0; + + # loop over all characters in the rotor to do a reverse lookup + foreach my $wheelchar (@{$self->{rotor}[$self->{rotormap}[$wheel]]}) { + if ($char eq $wheelchar) { + $outchar = $charindex + 33 - $self->{rotorpos}[$wheel]; + while ($outchar < 33) { + $outchar += 94; + } + last; # jump out when the character is found + } + $charindex++; + } + +# $outchar = sprintf "%c", $outchar; + $outchar = chr($outchar); +} + +###################################################################### +## _move_wheels(): advance the wheels one position +###################################################################### +sub _move_wheels { + my ($self) = @_; + + $self->{rotorpos}[0] = ($self->{rotorpos}[0]+1) % 94; + $self->{rotorpos}[1] = ($self->{rotorpos}[1]+1) % 94; + $self->{rotorpos}[2] = ($self->{rotorpos}[2]+1) % 94; + +} + +###################################################################### +## _numberize(): converts the encoded password to a numerical form +###################################################################### +sub _numberize { + my ($self) = @_; + + # split password into characters and loop over them + foreach my $char (split(/ */, $self->{encodedpass})) { + $self->{numberpass} .= sprintf("%03d", ord($char)); + } + return $self->{numberpass}; +} + + +###################################################################### +###################################################################### ## defines the main class to talk to the refdbd server @@ -362,11 +615,19 @@ # password encoding is currently done by the external application # "eenc" which is part of the RefDB package proper +# if (length($self->{passwd}) > 0) { +# $self->{numberized_passwd} = `eenc $self->{passwd} -p $self->{scramble_string}`; +# } +# else { +# $self->{numberized_passwd} = ""; +# } + if (length($self->{passwd}) > 0) { - $self->{numberized_passwd} = `eenc $self->{passwd} -p $self->{scramble_string}`; + my $enigma = new RefDBClient::Enigma; + $enigma->init($self->{passwd}, $self->{scramble_string}); + $self->{numberized_passwd} = $enigma->eenc(); } else { $self->{numberized_passwd} = ""; } - #print $self->{numberized_passwd}; |