root/examples/password-manager.p5

Revision 16177, 3.1 kB (checked in by rhr, 20 months ago)

Add p5 version of password-manager

  • Property svn:executable set to *
Line 
1#!/usr/bin/perl
2
3use Term::ReadLine;
4
5sub commit {
6        unlink "pwd.gpg.old" or die "Couldn't unlink: $!";
7        rename "pwd.gpg", "pwd.gpg.old" or die "Couldn't rename: $!";
8        open PWD, "|gpg --symmetric --force-mdc --cipher-algo AES256 --output pwd.gpg" or die "Couldn't encrypt: $!";
9        for $i (keys %pw) {
10                print PWD "$i\t$pw{$i}{pw}\t$pw{$i}{us}\n";
11        }
12        close PWD or warn "Couldn't write pwd: $!";
13        $changed = 0;
14}
15
16sub randpass { return join("", @chars[map{rand @chars} (1..8)]); }
17
18sub xclip {
19        open(XCLIP, "|/usr/X11R6/bin/xclip") or warn("No xclip - use .p\n"),
20                return;
21        print XCLIP $_[0];
22        close XCLIP;
23}
24
25$ENV{PATH} = "/bin:/usr/bin";
26umask 077;
27
28@achars = ("A" .. "Z", "a" .. "z", "0" .. "9");
29for($i = 33; $i <= 126; $i++) {
30        #alphanum and punct, no space
31        @apchars[$i-33] = chr $i;
32}
33@chars =@apchars;
34
35chdir "$ENV{HOME}/pw" or die "Couldn't cd: $!";
36open PWD, "gpg --output - --decrypt pwd.gpg|" or die "Couldn't decrypt: $!";
37while(<PWD>) {
38        chomp;
39        /^([^\t]+)\t([^\t]+)\t([^\t]+)$/ or warn "Malformed line $.: $_\n";
40        $pw{$1}{pw} = $2;
41        $pw{$1}{us} = $3;
42}
43close PWD;
44
45$term = new Term::ReadLine "pw";
46$attribs = $term->Attribs;
47$attribs->{completion_entry_function} = $attribs->{list_completion_function};
48$attribs->{completion_word} = [keys %pw];
49
50while(defined($_ = $term->readline("> "))) {
51        chomp;
52        if(/^\/(.*)/) {
53                $s = $1;
54                for $i (keys %pw) {
55                        print "$pw{$i}{us}\t$i\n" if $i =~ /$s/;
56                }
57        } elsif(/^\.(.)/) {
58                if($1 eq "n") {
59                        /^\.n\t([^\t]+)\t([^\t]+)\t([^\t]+)$/ or warn(".n [tab] account [tab] password [tab] username\n"), next;
60                        $changed++;
61                        if($2 eq "R") {
62                                $p = randpass;
63                                xclip($p);
64                        } else {
65                                $p = $2;
66                        }
67                        $pw{$1}{pw} = $p;
68                        $pw{$1}{us} = $3;
69                } elsif($1 eq "d") {
70                        /^\.d\s+([^\t]+?)\s*$/ or warn(".d account\n"), next;
71                        warn("No account $1\n"), next unless exists $pw{$1};
72                        $changed++;
73                        delete $pw{$1};
74                } elsif($1 eq "p") {
75                        /^\.p\s+([^\t]+?)\s*$/ or warn(".p account\n"), next;
76                        warn("No account $1\n"), next unless exists $pw{$1};
77                        print "$pw{$1}{us}\t$pw{$1}{pw}\n";
78                } elsif($1 eq "x") {
79                        /^\.x\s+([^\t]+?)\s*$/ or warn(".x account\n"), next;
80                        warn("No account $1\n"), next unless exists $pw{$1};
81                        xclip($pw{$1}{pw});
82                } elsif($1 eq "c") {
83                        commit;
84                } elsif($1 eq "r") {
85                        xclip(randpass);
86                } elsif($1 eq "R") {
87                        print randpass, "\n";
88                } elsif($1 eq "a") {
89                        @chars =@achars;
90                } elsif($1 eq "A") {
91                        @chars =@apchars;
92                } elsif($1 eq "h") {
93                        print "<account>\txclip account password and exit\n/<regex>\tsearch accounts\n.n\t\tnew account\n.d\t\tdelete account\n.p\t\tprint account\n.x\t\txclip account password\n.c\t\tcommit changes\n.r\t\txclip random password\n.R\t\tprint random password\n.a\t\tswitch to alphanum\n.A\t\tswitch to alphanum and punct\n.h\t\thelp\n";
94                } else {
95                        warn "Bad command .$1\n";
96                }
97        } else {
98                /^ *([^\t]+?)\s*$/ or next;
99                $s = $1;
100                for $i (keys %pw) {
101                        $p = $pw{$i}{pw}, last if $i eq $s;
102                        $p = $pw{$i}{pw} if $i =~ /\Q$s/;
103                }
104                warn("Couldn't find account $s\n"), next unless length $p;
105                xclip($p);
106                commit if $changed;
107                sleep 10;
108                xclip("");
109                exit;
110        }
111} continue { $attribs->{completion_word} = [keys %pw]; }
112
113commit if $changed;
Note: See TracBrowser for help on using the browser.