File Coverage

blib/lib/Data/Encrypted.pm
Criterion Covered Total %
statement 9 91 9.8
branch 0 58 0.0
condition 0 27 0.0
subroutine 3 10 30.0
pod n/a
total 12 186 6.4


line stmt bran cond sub pod time code
1             package Data::Encrypted;
2              
3 1     1   1083 use strict;
  1         2  
  1         47  
4 1     1   6 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $VAR1);
  1         2  
  1         291  
5              
6             require Exporter;
7              
8             require Crypt::RSA;
9             require Crypt::RSA::Key::Public::SSH;
10             require Crypt::RSA::Key::Private::SSH;
11              
12             require Term::ReadPassword;
13             require File::HomeDir;
14             require Storable;
15             require Fcntl;
16              
17 1     1   6 use Carp;
  1         1  
  1         2057  
18              
19             $VERSION = '0.07';
20             @ISA = qw(Exporter);
21             @EXPORT = qw();
22             @EXPORT_OK = qw(encrypted encrypt finish finished);
23              
24             my $RESET = 0;
25             my ($FILE, $FH);
26             my ($PK, $SK, $PW);
27              
28             sub import {
29              
30 0     0     @_ = _get_args(@_);
31              
32             # let Exporter finish it's work:
33 0           Data::Encrypted->export_to_level(1, @_);
34             }
35              
36             sub _get_args {
37              
38 0     0     for (my $i = 0 ; $i < @_ ; $i++) {
39 0 0         if ($_[$i] =~ m/-?reset/oi) {
    0          
    0          
    0          
    0          
    0          
40 0           $RESET = 1;
41 0           splice(@_, $i--, 1);
42             } elsif ($_[$i] =~ m/-?file/oi) {
43 0           $FILE = $_[$i+1];
44 0           splice(@_, $i--, 2);
45 0           _get_filehandle();
46             } elsif ($_[$i] =~ m/-?fh/oi) {
47 0           $FH = $_[$i+1];
48 0           splice(@_, $i--, 2);
49             } elsif ($_[$i] =~ m/-?pk/oi) {
50 0           $PK = $_[$i+1];
51 0           splice(@_, $i--, 2);
52             } elsif ($_[$i] =~ m/-?sk/oi) {
53 0           $SK = $_[$i+1];
54 0           splice(@_, $i--, 2);
55             } elsif ($_[$i] =~ m/-?pw/oi) {
56 0           $PW = $_[$i+1];
57 0           splice(@_, $i--, 2);
58             }
59             }
60              
61 0           return @_;
62             }
63              
64             sub new {
65              
66 0     0     my $class = shift;
67 0   0       $class = ref $class || $class;
68 0           my $self = bless {}, $class;
69              
70 0           _get_args(@_);
71              
72 0 0         unless (defined $FH) {
73 0           _get_filehandle()
74             }
75              
76 0 0 0       $self->{_public} = ref $PK ? $PK : new Crypt::RSA::Key::Public::SSH
77             Filename => $PK || (File::HomeDir::home() . '/.ssh/identity.pub');
78 0 0 0       $self->{_private} = ref $SK ? $SK : new Crypt::RSA::Key::Private::SSH
79             (Filename => $SK || (File::HomeDir::home() . '/.ssh/identity'),
80             Password => $PW );
81              
82 0           $self->{_rsa} = new Crypt::RSA;
83              
84 0           return $self;
85             }
86              
87             sub _get_filehandle {
88              
89 0 0   0     if ($FILE =~ m/^~([^\/]*)\//o) {
90 0           my $user = $1;
91 0           my $path;
92 0 0         if ($user) {
93 0           $path = File::HomeDir::home($user);
94             } else {
95 0           $path = File::HomeDir::home();
96             }
97 0 0         unless ($path) {
98 0           croak "No home directory for user: $user\n";
99             }
100 0           $FILE =~ s/^~$user/$path/;
101             }
102              
103 0 0         sysopen(FH, $FILE, Fcntl::O_RDWR() | Fcntl::O_CREAT() )
104             or croak "Can't open $FILE: $!";
105 0 0         flock(FH, Fcntl::LOCK_EX())
106             or croak "Can't flock file: $!";
107 0           $FH = \*FH;
108             }
109              
110             sub encrypted {
111              
112 0     0     my $self = shift;
113 0           my $arg = shift;
114              
115 0 0         unless (ref $self) {
116 0 0         my $newself = Data::Encrypted->new(defined $arg ? $arg : (), @_);
117 0           ($self, $arg) = ($newself, $self);
118             }
119              
120 0 0         unless ($arg) {
121 0           croak "Must supply argument to encrypted!";
122             }
123              
124 0 0         unless (exists $self->{_data}) {
125 0           $self->{_data} = '';
126 0           while (<$FH>) {
127 0           $self->{_data} .= $_;
128             }
129            
130 0           $self->{_data} =~ s/\s*$//os;
131              
132 0 0         if ($self->{_data}) {
133 0           $self->{_data} = $self->{_rsa}->decrypt(Cyphertext => $self->{_data},
134             Key => $self->{_private},
135             Armour => 1
136             );
137 0           $self->{_data} = Storable::thaw($self->{_data});
138             } else {
139 0           $self->{_data} = {};
140             }
141             }
142              
143 0 0 0       if ($RESET || ! exists $self->{_data}->{$arg}) {
144 0           $self->{_data}->{$arg} =
145             Term::ReadPassword::read_password(ref($self) .
146             " value for '$arg' not found," .
147             " please enter: ", 0, 1, 1);
148             }
149 0           return $self->{_data}->{$arg};
150             }
151            
152             *encrypt = \&encrypted;
153              
154             sub finished {
155              
156 0 0   0     if ($FH) {
157 0           flock($FH, Fcntl::LOCK_UN());
158 0           close($FH);
159 0           undef $FH;
160             }
161             }
162              
163             *finish = \&finished;
164              
165             sub DESTROY {
166              
167 0     0     my $self = shift;
168              
169 0 0 0       if ($self && ($FH || $FILE)) {
      0        
170 0 0         unless ($FH) {
171 0 0         sysopen(FH, $FILE, Fcntl::O_RDWR() | Fcntl::O_CREAT())
172             or croak "Can't open $FILE: $!";
173 0 0         flock(FH, Fcntl::LOCK_EX())
174             or croak "Can't flock file: $!";
175 0           $FH = \*FH;
176             }
177 0           seek($FH, 0, 0);
178 0 0         unless ($RESET) {
179             # need to rebuild our cryptosystem, ugh.
180 0 0 0       $self->{_public} = ref $PK ? $PK : new Crypt::RSA::Key::Public::SSH
181             Filename => $PK || (File::HomeDir::home() . '/.ssh/identity.pub');
182 0 0 0       $self->{_private} = ref $SK ? $SK : new Crypt::RSA::Key::Private::SSH
183             (Filename => $SK || (File::HomeDir::home() . '/.ssh/identity'),
184             Password => $PW );
185 0           $self->{_rsa} = new Crypt::RSA;
186 0           $self->{_data} = Storable::freeze($self->{_data});
187 0           $self->{_data} = $self->{_rsa}->encrypt(Message => $self->{_data},
188             Key => $self->{_public},
189             Armour => 1
190             );
191 0           print $FH $self->{_data};
192             }
193 0           delete $self->{_data};
194             }
195              
196 0 0 0       unless (exists $INC{'Inline/Files.pm'} || ! $FILE) {
197 0           flock($FH, Fcntl::LOCK_UN());
198 0           close($FH);
199 0           undef $FH;
200             }
201              
202             }
203              
204             1;
205              
206             __END__