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

Last change on this file since 2380 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
Line 
1#!/usr/bin/perl
2
3use strict;
4use warnings;
5use LATMOS::Accounts;
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
17    la-crypt-passwd [options] [--genkey|--regen] [--set BASE]
18
19=cut
20
21GetOptions(
22    'c|config=s' => \my $config,
23    'help'       => sub { pod2usage(0) },
24    'genkey'     => \my $genkey,
25    'regen'      => \my $regen,
26    'delkey'     => \my $delkey,
27    'set=s'      => \my $set,
28    'base=s'     => \my $base,
29    'u|user=s'   => \my @users,
30) or pod2usage();
31
32=head1 OPTIONS
33
34=over 4
35
36=item -c|--config configdir
37
38Use this configuration directory instead of the default one.
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
51=item --delkey
52
53Delete the current peer key and all encrypted password stored.
54
55=item --base base
56
57Work on this specific base instead default one
58
59=item --set BASE
60
61Read password from database, decrypt it and then set it in BASE given as
62argument.
63
64=item -u|--user USER
65
66Set password only for this user (can be set multiple times).
67
68=back
69
70=cut
71
72my $LA = LATMOS::Accounts->new($config, noacl => 1);
73my $labase = $LA->base($base);
74$labase && $labase->load or die "Cannot load base";
75$labase->wexported(1);
76
77my $clear;
78
79sub get_clear_password {
80
81    my @users_to_decode = @_;
82
83    $clear and return $clear;
84    my %encpasswd = $labase->get_rsa_password;
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";
91    my $private_key = $labase->private_key($password) or
92        die "Cannot get private key\n";
93    my $rsa = new Crypt::RSA ES => 'PKCS1v15';
94
95    my %clear_passwd;
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) {
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 {
114            die "Cannot get password for $_, crypt module said :" . $rsa->errstr() .
115                "Was the password correct ?\n";
116        }
117    }
118    return \%clear_passwd;
119}
120
121if ($set) {
122    if (!$labase->get_global_value('rsa_private_key')) {
123        warn "No rsa key found in database\n";
124    }
125    my $destbase = $LA->base($set) or die "Cannot get base $set\n";
126    my $clearpasswd = get_clear_password(@users);
127
128    my @userstoset = @users ? @users : keys %$clearpasswd;
129
130    foreach (@userstoset) {
131        $clearpasswd->{$_} or next;
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;
140} elsif ($regen || $genkey) {
141    if ($labase->get_global_value('rsa_private_key') && !$regen) {
142        die <<EOF;
143A rsa key were found in database please use --regen to force a new key
144generation. Notice this will force decrypt current stored password to encrypt
145them again
146EOF
147    }
148
149    my $clearpasswd = get_clear_password();
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";
169    my ($public, $private) = $labase->generate_rsa_key($password);
170
171    $labase->store_rsa_key($public, $private);
172    foreach (keys %$clearpasswd) {
173        my $obj = $labase->get_object('user', $_);
174        $obj->setCryptPassword($clearpasswd->{$_});
175    }
176    $labase->commit;
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;
191} else {
192    if ($labase->get_global_value('rsa_private_key')) {
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    }
200}
Note: See TracBrowser for help on using the repository browser.