source: trunk/LATMOS-Accounts/bin/la-sql-crypt-passwd @ 1806

Last change on this file since 1806 was 1634, checked in by nanardon, 8 years ago

Don't decrypt all password if not need

  • Property svn:executable set to *
  • Property svn:keywords set to Id Rev
File size: 5.2 KB
RevLine 
[413]1#!/usr/bin/perl
2
3use strict;
4use warnings;
[861]5use LATMOS::Accounts;
[413]6use Getopt::Long;
7use Pod::Usage;
8use Term::ReadKey;
9use Crypt::RSA;
10
11=head1 NAME
12
13    la-crypt-passwd - Tools to managed rsa crypted password in LATMOS Account system
14
15=head1 SYNOPSIS
16
[594]17    la-crypt-passwd [options] [--genkey|--regen] [--set BASE]
[413]18
19=cut
20
21GetOptions(
22    'c|config=s' => \my $config,
23    'help'       => sub { pod2usage(0) },
24    'genkey'     => \my $genkey,
25    'regen'      => \my $regen,
[1314]26    'delkey'     => \my $delkey,
[413]27    'set=s'      => \my $set,
[861]28    'base=s'     => \my $base,
[1239]29    'u|user=s'   => \my @users,
[413]30) or pod2usage();
31
32=head1 OPTIONS
33
34=over 4
35
[861]36=item -c|--config configdir
[413]37
[861]38Use this configuration directory instead of the default one.
[413]39
40=item --genkey
41
42Generate a RSA key and store it into database
43
44If one is already present, use regen to force generation of a new one
45
46=item --regen
47
48Like --genkey but a new key will replace the current one if already present.
49Stored password will be read and encrypted again using the new key.
50
[1314]51=item --delkey
52
53Delete the current peer key and all encrypted password stored.
54
[861]55=item --base base
56
57Work on this specific base instead default one
58
[413]59=item --set BASE
60
61Read password from database, decrypt it and then set it in BASE given as
62argument.
63
[1239]64=item -u|--user USER
65
66Set password only for this user (can be set multiple times).
67
[413]68=back
69
70=cut
71
[861]72my $LA = LATMOS::Accounts->new($config, noacl => 1);
[1044]73my $labase = $LA->base($base);
[861]74$labase && $labase->load or die "Cannot load base";
75$labase->wexported(1);
[413]76
77my $clear;
78
79sub get_clear_password {
[1634]80
81    my @users_to_decode = @_;
82
[413]83    $clear and return $clear;
[861]84    my %encpasswd = $labase->get_rsa_password;
[413]85    scalar(keys %encpasswd) or return {};
86    ReadMode('noecho');
87    print "Enter password for current passphrase: ";
88    my $password = ReadLine(0);
89    ReadMode 0;
90    print "\n";
[861]91    my $private_key = $labase->private_key($password) or
[413]92        die "Cannot get private key\n";
93    my $rsa = new Crypt::RSA ES => 'PKCS1v15';
[1634]94
[413]95    my %clear_passwd;
[1634]96
97    if (!@users_to_decode) {
98        @users_to_decode = sort keys %encpasswd;
99    }
100
101    printf
102        "Trying to get current stored password (%d)\n",
103        scalar(@users_to_decode);
104
105    foreach (@users_to_decode) {
[413]106        my $clearp = $rsa->decrypt (
107                Cyphertext => $encpasswd{$_},
108                Key        => $private_key,
109                Armour     => 1,
110        );
111        if (defined $clearp) {
112            $clear_passwd{$_} = $clearp;
113        } else {
[1314]114            die "Cannot get password for $_, crypt module said :" . $rsa->errstr() .
115                "Was the password correct ?\n";
[413]116        }
117    }
118    return \%clear_passwd;
119}
120
121if ($set) {
[861]122    if (!$labase->get_global_value('rsa_private_key')) {
[413]123        warn "No rsa key found in database\n";
124    }
125    my $destbase = $LA->base($set) or die "Cannot get base $set\n";
[1634]126    my $clearpasswd = get_clear_password(@users);
[1239]127
128    my @userstoset = @users ? @users : keys %$clearpasswd;
129
130    foreach (@userstoset) {
131        $clearpasswd->{$_} or next;
[413]132        my $obj = $destbase->get_object('user', $_) or do {
133            warn "Cannot find user $_ in destination base, need sync ?\n";
134            next;
135        };
136        $obj->set_password($clearpasswd->{$_}) and
137            print "Password set for $_\n";
138    }
139    $destbase->commit;
[434]140} elsif ($regen || $genkey) {
[861]141    if ($labase->get_global_value('rsa_private_key') && !$regen) {
[413]142        die <<EOF;
143A rsa key were found in database please use --regen to force a new key
[1090]144generation. Notice this will force decrypt current stored password to encrypt
145them again
[413]146EOF
147    }
148
149    my $clearpasswd = get_clear_password();
[1314]150
151    my $password;
152    while (1) {
153        ReadMode('noecho');
154        print "Enter password for new key: ";
155        $password = ReadLine(0);
156        print "\n";
157        print "Enter password again for new key: ";
158        my $password2 = ReadLine(0);
159        ReadMode 0;
160        print "\n";
161        if ($password eq $password2) {
162            last;
163        } else {
164            print "Password mismatch, try again:\n";
165        }
166    }
167
168    print "Generating new RSA key...\n";
[861]169    my ($public, $private) = $labase->generate_rsa_key($password);
[413]170
[861]171    $labase->store_rsa_key($public, $private);
[413]172    foreach (keys %$clearpasswd) {
[861]173        my $obj = $labase->get_object('user', $_);
[1314]174        $obj->setCryptPassword($clearpasswd->{$_});
[413]175    }
[861]176    $labase->commit;
[1314]177} elsif ($delkey) {
178    if (! $labase->get_global_value('rsa_public_key')) {
179        die "There is no key in this base, not deleting nothing\n";
180    }
181    my %encpasswd = $labase->get_rsa_password;
182    print "Deleting password...\n";
183    foreach my $user (keys %encpasswd) {
184        my $ouser = $labase->get_object('user', $user) or next;
185        $ouser->set_c_fields('encryptedPassword' => undef) or
186            die "Cannot delete encryptedPassword attribute for $user\n";
187    }
188    $labase->set_global_value('rsa_public_key', undef);
189    $labase->set_global_value('rsa_private_key', undef);
190    $labase->commit;
[434]191} else {
[861]192    if ($labase->get_global_value('rsa_private_key')) {
[434]193        my $clearpasswd = get_clear_password();
194        foreach (keys %$clearpasswd) {
195            printf("%s: %s\n", $_, $clearpasswd->{$_});
196        }
197    } else {
198        warn "No rsa key found in database\n";
199    }
[413]200}
Note: See TracBrowser for help on using the repository browser.