Changeset 413


Ignore:
Timestamp:
09/03/09 04:25:41 (15 years ago)
Author:
nanardon
Message:

In SQL base, allow to have a peer of public/private RSA key, then when user set it password it is stored in it clear form but encrypt using public key
The la-encrypt-passwd tools allow to

  • generate or regenerate a new key
  • read password
  • read password to propagate it into another base

Notice the private key is protected by a passwphrase prompt when setting it

Location:
LATMOS-Accounts
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • LATMOS-Accounts/Makefile.PL

    r258 r413  
    1010        'Unicode::Map8' => undef, 
    1111        'DBD::Pg' => undef, 
     12        'Crypt::RSA' => undef, 
     13        'MIME::Base64' => undef, 
     14        'Term::ReadKey' => undef, 
    1215    }, # e.g., Module::Name => 1.1 
    1316    ($] >= 5.005 ?     ## Add these new keywords supported since 5.005 
  • LATMOS-Accounts/bin/la-warn-expire

    r410 r413  
    1919GetOptions( 
    2020    'c|config=s' => \my $config, 
    21     'b|base=s'   => \my $base, 
     21#    'b|base=s'   => \my $base, 
    2222    'm|mail'     => \my $mail, 
    2323    'help'       => sub { pod2usage(0) }, 
  • LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql.pm

    r329 r413  
    128128}  
    129129 
     130sub get_global_value { 
     131    my ($self, $varname) = @_; 
     132 
     133    my $sth = $self->db->prepare_cached(q{ 
     134        select val from settings where varname = ? 
     135        }); 
     136    $sth->execute($varname); 
     137    my $res = $sth->fetchrow_hashref; 
     138    $sth->finish; 
     139    $res->{val} 
     140} 
     141 
     142sub set_global_value { 
     143    my ($self, $varname, $value) = @_; 
     144    my $sth = $self->db->prepare(q{ 
     145        update settings set val = ? where varname = ? 
     146        }); 
     147    $sth->execute($value, $varname) == 0 and do { 
     148        my $sth2 = $self->db->prepare(q{ 
     149            insert into settings (val, varname) values (?,?) 
     150            }); 
     151        $sth2->execute($value, $varname); 
     152    }; 
     153} 
     154 
    1301551; 
    131156 
  • LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/objects.pm

    r391 r413  
    77use base qw(LATMOS::Accounts::Bases::Objects); 
    88use LATMOS::Accounts::Log; 
     9use Crypt::RSA; 
     10use Crypt::RSA::Key::Public::SSH; 
    911 
    1012our $VERSION = (q$Rev$ =~ /^Rev: (\d+) /)[0]; 
     
    417419} 
    418420 
     421sub set_password { 
     422    my ($self, $clear_pass) = @_; 
     423    if (my $field = $self->base->get_field_name($self->type, 'userPassword')) { 
     424        my @salt_char = (('a' .. 'z'), ('A' .. 'Z'), (0 .. 9), '/', '.'); 
     425        my $salt = join('', map { $salt_char[rand(scalar(@salt_char))] } (1 .. 8)); 
     426        my $res = $self->set_fields($field, crypt($clear_pass, '$1$' . $salt)); 
     427 
     428        if (my $serialize = $self->base->get_global_value('rsa_public_key')) { 
     429            my $public = Crypt::RSA::Key::Public::SSH->new; 
     430            $public->deserialize(String => [ $serialize ]); 
     431            my $rsa = new Crypt::RSA ES => 'PKCS1v15'; 
     432            my $rsa_password = $rsa->encrypt ( 
     433                Message    => $clear_pass, 
     434                Key        => $public, 
     435                Armour     => 1, 
     436            ) || die $self->poll->rsa->errstr(); 
     437            $self->set_c_fields('encryptedPassword', $rsa_password); 
     438        } 
     439    } else { 
     440        $self->log(LA_WARN, 
     441            "Cannot set password: userPassword attributes is unsupported"); 
     442    } 
     443} 
    419444 
    420445sub search { 
  • LATMOS-Accounts/lib/LATMOS/Accounts/Maintenance.pm

    r411 r413  
    55use base qw(LATMOS::Accounts); 
    66use FindBin qw($Bin); 
     7use Crypt::RSA; 
     8use Crypt::RSA::Key::Public::SSH; 
     9use Crypt::RSA::Key::Private::SSH; 
     10use MIME::Base64; 
    711 
    812sub _base { 
     
    8387} 
    8488 
     89sub generate_rsa_key { 
     90    my ($self, $password) = @_; 
     91     
     92    my $rsa = new Crypt::RSA ES => 'PKCS1v15'; 
     93    my ($public, $private) = $rsa->keygen ( 
     94        Identity  => 'LATMOS-Accounts', 
     95        Size      => 768, 
     96        Password  => $password, 
     97        Verbosity => 0, 
     98        KF=>'SSH', 
     99    ) or die 
     100    $self->rsa->errstr(); # TODO avoid die 
     101    return ($public, $private); 
     102} 
     103 
     104sub store_rsa_key { 
     105    my ($self, $public, $private) = @_; 
     106    my $base = $self->_base; 
     107    $base->set_global_value('rsa_private_key', 
     108        encode_base64($private->serialize)); 
     109    $base->set_global_value('rsa_public_key', 
     110        $public->serialize); 
     111    return; 
     112} 
     113 
     114sub private_key { 
     115    my ($self, $password) = @_; 
     116    my $base = $self->_base; 
     117    my $serialize = $base->get_global_value('rsa_private_key') or return; 
     118    my $privkey = Crypt::RSA::Key::Private::SSH->new; 
     119    $privkey->deserialize(String => [ decode_base64($serialize) ], 
     120        Passphrase => $password); 
     121    $privkey 
     122} 
     123 
     124sub get_rsa_password { 
     125    my ($self) = @_; 
     126    my $base = $self->_base; 
     127    my $sth = $base->db->prepare(q{ 
     128        select "name", value from "user" join user_attributes_base 
     129        on "user".ikey = user_attributes_base.okey 
     130        where user_attributes_base.attr = 'encryptedPassword' 
     131    }); 
     132    $sth->execute; 
     133    my %users; 
     134    while (my $res = $sth->fetchrow_hashref) { 
     135        $users{$res->{name}} = $res->{value}; 
     136    } 
     137    %users 
     138} 
     139 
    851401; 
Note: See TracChangeset for help on using the changeset viewer.