File Coverage

blib/lib/App/Tel/Passwd/Pass.pm
Criterion Covered Total %
statement 18 72 25.0
branch 0 18 0.0
condition 0 11 0.0
subroutine 6 10 60.0
pod 2 2 100.0
total 26 113 23.0


line stmt bran cond sub pod time code
1             package App::Tel::Passwd::Pass;
2              
3             =head1 name
4              
5             App::Tel::Passwd::Pass - Tel Passwd module for Pass
6              
7             =cut
8              
9 1     1   795 use strict;
  1         9  
  1         26  
10 1     1   5 use warnings;
  1         1  
  1         27  
11 1     1   875 use IO::Handle;
  1         7171  
  1         41  
12 1     1   786 use IO::File;
  1         2225  
  1         144  
13 1     1   5 use Carp;
  1         2  
  1         48  
14 1     1   5 use Module::Load;
  1         2  
  1         7  
15              
16             our $_debug = 0;
17              
18             =head1 METHODS
19              
20             A note on private subroutines in this file: Anything with two underscores
21             preceeding it is a private non-class sub.
22              
23             =head2 new
24              
25             my $passwd = App::Tel::Passwd::Pass->new( file => $filename, passwd => $password );
26              
27             Initializes a new passwdobject. This will return a Passwd::Pass Object if the module
28             exists and return undef if it doesn't.
29              
30             Requires filename and password for the file.
31              
32             =cut
33              
34             sub new {
35 0     0 1   my $proto = shift;
36 0   0       my $class = ref($proto) || $proto;
37 0           my %args = @_;
38              
39 0           my $self = { debug => $_debug,
40             %args
41             };
42 0           $self->{file} = __find_password_store($self->{file});
43 0 0 0       $self->{gpg} ||= ($^O=~/(freebsd|openbsd|netbsd|solaris)/) ? '/usr/local/bin/gpg' : '/usr/bin/gpg';
44              
45 0 0         if (! -x $self->{gpg}) {
46 0           croak "$class: gpg executable not found.";
47             }
48              
49 0 0 0       if (!defined($self->{file}) || ! -r $self->{file} ) {
50 0   0       $self->{file} ||= '<undefined>';
51 0           croak "$class: Can't read file $self->{file}";
52             }
53              
54 0           $self->{gnupg} = eval {
55 0           load GnuPG::Interface;
56 0           return GnuPG::Interface->new();
57             };
58              
59 0 0         if ($@) {
60 0           croak $@;
61             }
62              
63 0           bless( $self, $class );
64 0           $self->{pass} = $self->_run($self->{gpg}, $self->{file}, $self->{passwd});
65 0           return $self;
66             }
67              
68             sub _run {
69 0     0     my ($self, $call, $file, $passphrase) = @_;
70              
71 0           my $gnupg = $self->{gnupg};
72 0           $gnupg->call($call);
73 0           $gnupg->options->no_greeting(1);
74 0           $gnupg->options->quiet(1);
75 0           $gnupg->options->batch(1);
76              
77             # This time we'll catch the standard error for our perusing
78             # as well as passing in the passphrase manually
79             # as well as the status information given by GnuPG
80 0           my ( $input, $output, $error, $passphrase_fh, $status_fh )
81             = ( IO::Handle->new(),
82             IO::Handle->new(),
83             IO::Handle->new(),
84             IO::Handle->new(),
85             IO::Handle->new(),
86             );
87              
88 0           my $handles = GnuPG::Handles->new( stdin => $input,
89             stdout => $output,
90             stderr => $error,
91             passphrase => $passphrase_fh,
92             status => $status_fh,
93             );
94              
95             # this time we'll also demonstrate decrypting
96             # a file written to disk
97             # Make sure you "use IO::File" if you use this module!
98 0           my $cipher_file = IO::File->new( $file );
99              
100             # this sets up the communication
101 0           my $pid = $gnupg->decrypt( handles => $handles );
102              
103             # This passes in the passphrase
104 0           print $passphrase_fh $passphrase;
105 0           close $passphrase_fh;
106              
107             # this passes in the plaintext
108 0           print $input $_ while <$cipher_file>;
109              
110             # this closes the communication channel,
111             # indicating we are done
112 0           close $input;
113 0           close $cipher_file;
114              
115 0           my @plaintext = <$output>; # reading the output
116 0           my @error_output = <$error>; # reading the error
117 0           my @status_info = <$status_fh>; # read the status info
118 0           chomp(@plaintext);
119              
120 0           for (@status_info) {
121 0 0         croak @error_output if (/BAD_PASSPHRASE|DECRYPTION_FAILED/);
122             }
123              
124             # clean up...
125 0           close $output;
126 0           close $error;
127 0           close $status_fh;
128              
129 0           waitpid $pid, 0; # clean up the finished GnuPG process
130 0           return $plaintext[0];
131             }
132              
133             sub __find_password_store {
134 0     0     my $file = shift;
135              
136 0 0         return if (!defined($file));
137 0 0         if ($file !~ /.gpg$/) {
138 0           $file .= '.gpg';
139             }
140             # if it's an absolute path then treat it as-is.
141 0 0         return $file if ($file =~ m#^/#);
142              
143 0 0         if (defined($ENV{PASSWORD_STORE_DIR})) {
144 0           return "$ENV{PASSWORD_STORE_DIR}/$file";
145             }
146              
147 0           return "$ENV{HOME}/.password-store/$file";
148             }
149              
150             =head2 passwd
151              
152             $passwd->passwd($entry);
153              
154             This requires a password for the router. It will return a blank line if not
155             found.
156              
157             =cut
158              
159             sub passwd {
160 0     0 1   $_[0]->{pass};
161             }
162              
163             1;