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

Last change on this file since 1239 was 1239, checked in by nanardon, 10 years ago

add options to set password from reversible crypted storage for only one user

  • Property svn:executable set to *
  • Property svn:keywords set to Id Rev
File size: 3.8 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    'set=s'      => \my $set,
27    'base=s'     => \my $base,
28    'u|user=s'   => \my @users,
29) or pod2usage();
30
31=head1 OPTIONS
32
33=over 4
34
35=item -c|--config configdir
36
37Use this configuration directory instead of the default one.
38
39=item --genkey
40
41Generate a RSA key and store it into database
42
43If one is already present, use regen to force generation of a new one
44
45=item --regen
46
47Like --genkey but a new key will replace the current one if already present.
48Stored password will be read and encrypted again using the new key.
49
50=item --base base
51
52Work on this specific base instead default one
53
54=item --set BASE
55
56Read password from database, decrypt it and then set it in BASE given as
57argument.
58
59=item -u|--user USER
60
61Set password only for this user (can be set multiple times).
62
63=back
64
65=cut
66
67my $LA = LATMOS::Accounts->new($config, noacl => 1);
68my $labase = $LA->base($base);
69$labase && $labase->load or die "Cannot load base";
70$labase->wexported(1);
71
72my $clear;
73
74sub get_clear_password {
75    $clear and return $clear;
76    my %encpasswd = $labase->get_rsa_password;
77    scalar(keys %encpasswd) or return {};
78    ReadMode('noecho');
79    print "Enter password for current passphrase: ";
80    my $password = ReadLine(0);
81    ReadMode 0;
82    print "\n";
83    my $private_key = $labase->private_key($password) or
84        die "Cannot get private key\n";
85    my $rsa = new Crypt::RSA ES => 'PKCS1v15';
86    my %clear_passwd;
87    foreach (keys %encpasswd) {
88        my $clearp = $rsa->decrypt (
89                Cyphertext => $encpasswd{$_},
90                Key        => $private_key,
91                Armour     => 1,
92        );
93        if (defined $clearp) {
94            $clear_passwd{$_} = $clearp;
95        } else {
96            warn "$_ :" . $rsa->errstr();
97        }
98    }
99    return \%clear_passwd;
100}
101
102if ($set) {
103    if (!$labase->get_global_value('rsa_private_key')) {
104        warn "No rsa key found in database\n";
105    }
106    my $destbase = $LA->base($set) or die "Cannot get base $set\n";
107    my $clearpasswd = get_clear_password();
108
109    my @userstoset = @users ? @users : keys %$clearpasswd;
110
111    foreach (@userstoset) {
112        $clearpasswd->{$_} or next;
113        my $obj = $destbase->get_object('user', $_) or do {
114            warn "Cannot find user $_ in destination base, need sync ?\n";
115            next;
116        };
117        $obj->set_password($clearpasswd->{$_}) and
118            print "Password set for $_\n";
119    }
120    $destbase->commit;
121} elsif ($regen || $genkey) {
122    if ($labase->get_global_value('rsa_private_key') && !$regen) {
123        die <<EOF;
124A rsa key were found in database please use --regen to force a new key
125generation. Notice this will force decrypt current stored password to encrypt
126them again
127EOF
128    }
129
130    my $clearpasswd = get_clear_password();
131    ReadMode('noecho');
132    print "Enter password for new key: ";
133    my $password = ReadLine(0);
134    ReadMode 0;
135    print "\n";
136    my ($public, $private) = $labase->generate_rsa_key($password);
137
138    $labase->store_rsa_key($public, $private);
139    foreach (keys %$clearpasswd) {
140        my $obj = $labase->get_object('user', $_);
141        $obj->set_password($clearpasswd->{$_});
142    }
143    $labase->commit;
144} else {
145    if ($labase->get_global_value('rsa_private_key')) {
146        my $clearpasswd = get_clear_password();
147        foreach (keys %$clearpasswd) {
148            printf("%s: %s\n", $_, $clearpasswd->{$_});
149        }
150    } else {
151        warn "No rsa key found in database\n";
152    }
153}
Note: See TracBrowser for help on using the repository browser.