package Crypt::Imail;

use 5.008;
use strict;
use warnings;

our $VERSION = '0.01';

sub new { bless {}, ref($_[0]) || $_[0] }

sub decrypt {
    my $self = shift;
    my ($user, $epass) = @_;

    my @user = map ord($_), split //, $user;

    my @key = map $user[0] - $_, @user;
       @key = map @key, (0..20);

    my @epass = ($epass =~ /(..)/g);

    my %data = $self->_data('decrypt');

    my @pass;
    {
      my $counter = 0;
      @pass = map $data{$_} + $key[$counter++], @epass;
    }

join '', map chr($_ - ($user[0] - 97)), @pass;
}

sub encrypt {
    my $self = shift;
    my ($user, $pass) = @_;

    my @auser = map ord($_), split //, $user;
    my @apass = map ord($_), split //, $pass;

    my @key = map $auser[0] - $_, @auser;
       @key = map @key, (0 .. 12); # hack - be sure it's large enough

    my $offset = $auser[0] - 97;
    my @epass = map {($apass[$_] + $offset) - $key[$_]} (0..$#apass);

    my %data = $self->_data('encrypt');

join '', map $data{$_}, @epass;
}

sub _data {
    my $self = shift;

    my $count = -97;
    my @nums = (0..9,'A'..'F');

    my %hash;
    for my $base (@nums) {
	for (@nums) {
	    if ($_[0] eq 'decrypt') {
	     $hash{$base.$_} = $count++;
	    }elsif ($_[0] eq 'encrypt') {
	     $hash{$count++} = $base.$_;
            }else{
	     warn "pass either encrypt or decrypt to the data function";
	    }
	}
     }

%hash;
}

1;
__END__

=head1 NAME

Crypt::Imail - encrypt and decrypt IMail passwords

=head1 SYNOPSIS

  use Crypt::Imail;

  $im = Crypt::Imail->new();

  my $encrypted_pass = $im->encrypt($user, $password);

  my $password = $im->decrypt($user, $encrypted_pass);
  

=head1 ABSTRACT

Used to Encrypt and Decrypt passwords generated by imail.

=head1 DESCRIPTION

This package is used to encrypt and decrypt passwords generated by IMail.

See: http://www.ipswitch.com/products/imail_server/

This came about because I kept reading newsgroup posts about how horrible
IMails encryption scheme was.  Then one day I get a call that a friend needs
to move all the email accounts from and NT box running imail to linux and 
wants to have as little disruption as possible to everyone's services.  So 
I wrote this object for him.  I hope two things come out of it.  First,
I hope this proves helpful to others.  Secondly, I hope it doesn't because
Imail got their act together and fixed their "encryption" scheme.

=head2 EXPORT

None by default.

=head1 SEE ALSO

perl(1);

=head1 AUTHOR

Stephen D. Wells, E<lt>wells@cedarnet.orgE<gt>

=head1 COPYRIGHT AND LICENSE

Copyright 2003 by Stephen D. Wells. All rights reserved.

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself. 

=cut
