line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package PGP::Pipe; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
require 5.000; |
4
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
12237
|
use English; |
|
1
|
|
|
|
|
6599
|
|
|
1
|
|
|
|
|
9
|
|
6
|
1
|
|
|
1
|
|
981
|
use Carp; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
135
|
|
7
|
1
|
|
|
1
|
|
8
|
use File::Basename; |
|
1
|
|
|
|
|
23
|
|
|
1
|
|
|
|
|
147
|
|
8
|
1
|
|
|
1
|
|
1476
|
use IPC::Open3; |
|
1
|
|
|
|
|
4921
|
|
|
1
|
|
|
|
|
48
|
|
9
|
1
|
|
|
1
|
|
8371
|
use Time::Local; |
|
1
|
|
|
|
|
3001
|
|
|
1
|
|
|
|
|
97
|
|
10
|
1
|
|
|
1
|
|
6216
|
use Data::Dumper; |
|
1
|
|
|
|
|
42816
|
|
|
1
|
|
|
|
|
7806
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
# $debug = 1; |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
=over 4 |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 NAME |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
PGP - perl module to work with PGP messages |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 SYNOPSIS |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
use PGP; |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
$message = new PGP $pgppath; |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
=head1 DESCRIPTION |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
The PGP module allow a perl script to work with PGP related files. |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
=cut |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
# $Log: Pipe.pm,v $ |
33
|
|
|
|
|
|
|
# Revision 0.3 1996/08/14 19:04:21 hickey |
34
|
|
|
|
|
|
|
# + moved module to PGP::Pipe to prevent conflicts |
35
|
|
|
|
|
|
|
# + upgraded to Data::Dumper |
36
|
|
|
|
|
|
|
# + added the Sign_Key method to PGP::Keyring (not debugged yet) |
37
|
|
|
|
|
|
|
# + PGP::Pipe::Exec places filehandles in caller's package |
38
|
|
|
|
|
|
|
# |
39
|
|
|
|
|
|
|
# Revision 0.2 1996/01/27 15:40:57 hickey |
40
|
|
|
|
|
|
|
# + PGP::Keyring and PGP::Key now inherits PGP object |
41
|
|
|
|
|
|
|
# + PGP::Keyring::Find now correctly works (filter on anything) |
42
|
|
|
|
|
|
|
# + Timestamps are now correctly reported back to caller |
43
|
|
|
|
|
|
|
# + Activated %r (path to keyring) in the PGP::Exec_PGP method |
44
|
|
|
|
|
|
|
# + Added support for multiple ID keys. (PGP::Key::Add_ID) |
45
|
|
|
|
|
|
|
# |
46
|
|
|
|
|
|
|
# Revision 0.1 1996/01/10 02:22:18 hickey |
47
|
|
|
|
|
|
|
# Initial alpha release |
48
|
|
|
|
|
|
|
# |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
$VERSION = '0.3'; |
51
|
|
|
|
|
|
|
$RCSID = '$Id: Pipe.pm,v 0.3 1996/08/14 19:04:21 hickey Exp hickey $'; |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
=item * PGP::new |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
$pgp = new PGP [$pgppath], [$pgpexec]; |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
Create the PGP encapsulation object. The standard location for the |
58
|
|
|
|
|
|
|
PGP executable is /usr/local/bin/pgp. |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
=cut |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
sub new |
63
|
|
|
|
|
|
|
{ |
64
|
0
|
|
|
0
|
|
|
my $class = shift; |
65
|
0
|
|
0
|
|
|
|
my $pgppath = shift || "$ENV{HOME}/.pgp"; |
66
|
0
|
|
0
|
|
|
|
my $pgpexec = shift || "/usr/local/bin/pgp"; |
67
|
|
|
|
|
|
|
|
68
|
0
|
0
|
0
|
|
|
|
if (! -e "$pgppath/config.txt" && |
69
|
|
|
|
|
|
|
! -e "/usr/local/lib/pgp/config.txt" ) |
70
|
|
|
|
|
|
|
{ |
71
|
0
|
|
|
|
|
|
carp "PGP configuration file not found."; |
72
|
0
|
|
|
|
|
|
return (0); |
73
|
|
|
|
|
|
|
}; |
74
|
|
|
|
|
|
|
|
75
|
0
|
|
|
|
|
|
$self = { PGPPATH => $pgppath, |
76
|
|
|
|
|
|
|
PGPexec => $pgpexec |
77
|
|
|
|
|
|
|
}; |
78
|
0
|
|
|
|
|
|
$ENV{PGPPATH} = $pgppath; |
79
|
|
|
|
|
|
|
|
80
|
0
|
|
|
|
|
|
bless $self, $class; |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
# The following function was suggested by Alva Couch. Can anyone |
84
|
|
|
|
|
|
|
# think why they would call it rather than the new() method? |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
# projector function eliminates all non-PGP data and |
87
|
|
|
|
|
|
|
# returns a 'pure' PGP instance. |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
sub PGP |
90
|
|
|
|
|
|
|
{ |
91
|
0
|
|
|
0
|
|
|
my $self = shift; |
92
|
0
|
|
|
|
|
|
bless { PGPPATH => $self->{PGPPATH}, |
93
|
|
|
|
|
|
|
PGPexec => $self->{PGPexec}, |
94
|
|
|
|
|
|
|
}, PGP; |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
sub Debug |
99
|
|
|
|
|
|
|
{ |
100
|
0
|
|
|
0
|
|
|
my (@args) = @_; |
101
|
|
|
|
|
|
|
|
102
|
0
|
0
|
|
|
|
|
return if (! defined $PGP::Pipe::debug); |
103
|
|
|
|
|
|
|
|
104
|
0
|
|
|
|
|
|
print STDERR @args, "\n"; |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=item * PGP::Exec |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
$pid = Exec $pgp $args, $in, $out, $err, $nobatchmode; |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
Execute the PGP command and attach the C<$in>, C<$out>, C<$err> file handles. |
113
|
|
|
|
|
|
|
This should be fine for the moment, but need to look into making |
114
|
|
|
|
|
|
|
sure that data is not written to a temporary file anywhere. The C<$nobatchmode> |
115
|
|
|
|
|
|
|
parameter causes the PGP command to be executed without the +batchmode |
116
|
|
|
|
|
|
|
parameter. This seems to only be necessary when a key is being signed. |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
The $args variable can have several substituted strings: |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
%p PGP path variable |
121
|
|
|
|
|
|
|
%r Path to PGP keyring |
122
|
|
|
|
|
|
|
%k Specified user |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
B The above substitutions may change at any time. It is not |
125
|
|
|
|
|
|
|
advised that you write applications with substitutions. Almost |
126
|
|
|
|
|
|
|
certainly, the next release will not include substitutions. |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
The file handle variables--C<$in>, C<$out> and C<$err>--are send as |
129
|
|
|
|
|
|
|
normal filehandle names, but they reside in the PGP package. For |
130
|
|
|
|
|
|
|
example, the following procedure call is made: |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
PGP->Exec ($args, FIN, FOUT, FERR); |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
Even though the file handles were specified as C, C and |
135
|
|
|
|
|
|
|
C; they must be referred to as C, C and |
136
|
|
|
|
|
|
|
C in the orignal procedure that made the call. |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
=cut |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
sub Exec |
142
|
|
|
|
|
|
|
{ |
143
|
0
|
|
|
0
|
|
|
my ($self, $args, $in, $out, $err, $nobatchmode) = @_; |
144
|
0
|
|
|
|
|
|
my ($pgppath, $pgpcmd, $baseopts); |
145
|
0
|
|
|
|
|
|
my ($fin, $fout, $ferr); |
146
|
|
|
|
|
|
|
|
147
|
0
|
0
|
|
|
|
|
if ($nobatchmode) |
148
|
0
|
|
|
|
|
|
{ $baseopts = '+force +verbose=1' } |
149
|
|
|
|
|
|
|
else |
150
|
0
|
|
|
|
|
|
{ $baseopts = '+force +batchmode +verbose=1' }; |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
# Variable substitutions |
153
|
0
|
|
|
|
|
|
$args =~ s/%p/$self->{PGPPATH}/g; |
154
|
0
|
|
|
|
|
|
$args =~ s/%r/$self->{PGPPATH}\/$self->{Keyring}/g; # PGP::Keyring |
155
|
0
|
|
|
|
|
|
$args =~ s/%k/0x$self->{Keyid}/g; # PGP::Key |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
# Put the file descriptors in the callers package |
158
|
0
|
|
|
|
|
|
$fin = (caller)[0] . "::$in"; |
159
|
0
|
|
|
|
|
|
$fout = (caller)[0] . "::$out"; |
160
|
0
|
|
|
|
|
|
$ferr = (caller)[0] . "::$err"; |
161
|
|
|
|
|
|
|
|
162
|
0
|
|
|
|
|
|
Debug ("PGP::Exec=$self->{PGPexec} $baseopts $args"); |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
# just to make sure that PGPPATH is exported! |
165
|
0
|
|
|
|
|
|
$ENV{PGPPATH} = $self->{PGPPATH}; |
166
|
0
|
|
0
|
|
|
|
$result = open3 ($fin, $fout, $ferr, "$self->{PGPexec} $baseopts $args") || croak "PGP command error"; |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
=item * PGP::Sign |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
$signed_document = Sign $pgp %args; |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
The C procedure will take a file or data and sign with a PGP |
175
|
|
|
|
|
|
|
secret key. The default behavior is to sign the data with the last |
176
|
|
|
|
|
|
|
secret key added to the keyring, but that can be overridden with the |
177
|
|
|
|
|
|
|
I argument. This method always returns the signed document. |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
The C<%args> consist of a series of keys and values. Since there are |
180
|
|
|
|
|
|
|
several variations in the way data can be signed, not all the |
181
|
|
|
|
|
|
|
following options must be specified. This approach also makes it much |
182
|
|
|
|
|
|
|
easier to scale to new versions of PGP with more options. |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
Armor The output should be ASCII armored |
185
|
|
|
|
|
|
|
Clear Produce a "clear" signature |
186
|
|
|
|
|
|
|
Encrypt Encrypt the resulting signed document with |
187
|
|
|
|
|
|
|
the given keyobj |
188
|
|
|
|
|
|
|
Detach Create a detached signature |
189
|
|
|
|
|
|
|
File Sign the specified file |
190
|
|
|
|
|
|
|
Key Sign with the specified key object |
191
|
|
|
|
|
|
|
Nosave Do not allow user to save message |
192
|
|
|
|
|
|
|
Password The password to use for signing |
193
|
|
|
|
|
|
|
Signfile The filename of the signed document |
194
|
|
|
|
|
|
|
Text Data to be signed. |
195
|
|
|
|
|
|
|
Wipe Remove the orignal file |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
The only absolute argument that is always required is the C. |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
B |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
Sign $pgp Password => 'xyz', File => '/etc/motd', Clear => 1, Armor => 1; |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
This would return a signed copy of the F file. In this |
204
|
|
|
|
|
|
|
case, we use a file as the input, but the output is returned at the |
205
|
|
|
|
|
|
|
method's termination. The orignal file remains in the clear, and the |
206
|
|
|
|
|
|
|
signature is ASCII armored (Base64). |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
Sign $pgp Password => 'abc', Text => 'Important info', Armor => 1, |
209
|
|
|
|
|
|
|
Signfile => 'signed.asc', Key => $keyobj; |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
This is sort of the reverse of the first example. It takes what is in |
212
|
|
|
|
|
|
|
the C field and signs it. It then puts the result in the file |
213
|
|
|
|
|
|
|
F and returns it to the caller. In this case, the entire |
214
|
|
|
|
|
|
|
message is ASCII armored including the orignal text (i.e. C). |
215
|
|
|
|
|
|
|
We also specify another secret key to produce the signature. For more |
216
|
|
|
|
|
|
|
information on the the key objects, please see L<"PGP::Key"> section. |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
=cut |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
sub Sign |
222
|
|
|
|
|
|
|
{ |
223
|
0
|
|
|
0
|
|
|
my ($self, %args) = @_; |
224
|
0
|
|
|
|
|
|
my ($options, $key, $document); |
225
|
|
|
|
|
|
|
|
226
|
0
|
|
|
|
|
|
Debug ("PGP::Sign Args=", Dumper \%args); |
227
|
|
|
|
|
|
|
|
228
|
0
|
|
|
|
|
|
$options = '-f -s'; |
229
|
0
|
0
|
|
|
|
|
$options .= 'a' if ($args{Armor} == 1); |
230
|
0
|
0
|
|
|
|
|
$options .= 'b' if ($args{Detach} == 1); |
231
|
0
|
0
|
|
|
|
|
$options .= 't' if (exists $args{Clear}); |
232
|
0
|
0
|
|
|
|
|
$options .= 'w' if ($args{Wipe} == 1); |
233
|
0
|
0
|
|
|
|
|
$options .= 'm' if ($args{Nosave} == 1); |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
# setup of encryption if we are doing any |
236
|
0
|
0
|
|
|
|
|
if (defined $args{Encrypt}) |
237
|
|
|
|
|
|
|
{ |
238
|
0
|
|
|
|
|
|
$options .= 'e'; |
239
|
0
|
|
|
|
|
|
foreach $key (@{$args{Encrypt}}) |
|
0
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
{ |
241
|
0
|
|
|
|
|
|
$options .= " 0x$key->{Keyid}"; |
242
|
|
|
|
|
|
|
}; |
243
|
|
|
|
|
|
|
}; |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
# When signing a document, we always have a password. |
246
|
0
|
|
|
|
|
|
$options .= " -z $args{Password}"; |
247
|
|
|
|
|
|
|
|
248
|
0
|
|
|
|
|
|
Debug ("PGP::Sign Options=$options"); |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
# procede to send the document to PGP. |
251
|
0
|
|
|
|
|
|
$self->Exec ($options, FIN, FOUT, FERR); |
252
|
|
|
|
|
|
|
|
253
|
0
|
0
|
|
|
|
|
if ($args{File}) |
254
|
|
|
|
|
|
|
{ |
255
|
0
|
0
|
|
|
|
|
open (PLAIN, "< $args{File}") || carp "$args{File} not found"; |
256
|
0
|
|
|
|
|
|
print FIN ; |
257
|
0
|
|
|
|
|
|
close (PLAIN); |
258
|
|
|
|
|
|
|
} else |
259
|
|
|
|
|
|
|
{ |
260
|
0
|
|
|
|
|
|
print FIN $args{Text}; |
261
|
|
|
|
|
|
|
}; |
262
|
0
|
|
|
|
|
|
close (FIN); |
263
|
|
|
|
|
|
|
|
264
|
0
|
|
|
|
|
|
$document = join ('', ()); |
265
|
|
|
|
|
|
|
|
266
|
0
|
0
|
|
|
|
|
if ($args{Signfile}) |
267
|
|
|
|
|
|
|
{ |
268
|
0
|
0
|
|
|
|
|
open (SIGN, "> $args{Signfile}") || carp "Can not create $args{Signfile}"; |
269
|
0
|
|
|
|
|
|
print SIGN $document; |
270
|
0
|
|
|
|
|
|
close (SIGN); |
271
|
|
|
|
|
|
|
}; |
272
|
|
|
|
|
|
|
|
273
|
0
|
|
|
|
|
|
return ($document); |
274
|
|
|
|
|
|
|
} |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
=item * PGP::Encrypt |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
$encrypted_document = Encrypt $pgp %args; |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
The C method produces an encrypted document with the given |
282
|
|
|
|
|
|
|
public keys specified by C. The C method follow the |
283
|
|
|
|
|
|
|
same conventions as the C method. The data to be encrypted can |
284
|
|
|
|
|
|
|
be sent to the method or can reside in a file. The resulting |
285
|
|
|
|
|
|
|
encrypted data can also reside in a file or be sent back to the caller. |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
In addition to encrypting a document, the document can also be signed |
288
|
|
|
|
|
|
|
by using the C key in the C<%args> array. If the document is to |
289
|
|
|
|
|
|
|
be signed by the default secret key (last key added to the secret |
290
|
|
|
|
|
|
|
keyring), then C can be left undefined or contain something |
291
|
|
|
|
|
|
|
other than a reference to a key object. Otherwise the C key |
292
|
|
|
|
|
|
|
should contain a reference to a specific key object (see |
293
|
|
|
|
|
|
|
L<"PGP::Key">). |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
Armor The output should be ASCII armored |
296
|
|
|
|
|
|
|
Encryptfile The filename of the encrypted document |
297
|
|
|
|
|
|
|
File Encrypt the specified file |
298
|
|
|
|
|
|
|
Key Encrypt with the specified key object |
299
|
|
|
|
|
|
|
Nosave Do not allow user to save message |
300
|
|
|
|
|
|
|
Password The password to use for signing |
301
|
|
|
|
|
|
|
Sign In addition to encrypting, sign the document |
302
|
|
|
|
|
|
|
Text Data to be encrypted |
303
|
|
|
|
|
|
|
Wipe Remove orignal file |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
=cut |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
sub Encrypt |
309
|
|
|
|
|
|
|
{ |
310
|
0
|
|
|
0
|
|
|
my ($self, %args) = @_; |
311
|
0
|
|
|
|
|
|
local ($options, $document, $key, @keys); |
312
|
|
|
|
|
|
|
|
313
|
0
|
|
|
|
|
|
Debug ("PGP::Encrypt Args=", Dumper \%args); |
314
|
|
|
|
|
|
|
|
315
|
0
|
|
|
|
|
|
$options = '-f -e'; |
316
|
0
|
0
|
|
|
|
|
$options .= 'a' if ($args{'Armor'} == 1); |
317
|
0
|
0
|
|
|
|
|
$options .= 's' if (exists $args{'Sign'}); |
318
|
0
|
0
|
|
|
|
|
$options .= 'w' if ($args{'Wipe'} == 1); |
319
|
0
|
0
|
|
|
|
|
$options .= 'm' if ($args{'Nosave'} == 1); |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
# process the Key variable |
322
|
0
|
0
|
|
|
|
|
if (ref $args{'Key'} eq 'ARRAY') |
323
|
|
|
|
|
|
|
{ |
324
|
0
|
|
|
|
|
|
foreach $key (@keys) |
325
|
|
|
|
|
|
|
{ |
326
|
0
|
|
|
|
|
|
$options .= " 0x$key->{'Keyid'}"; |
327
|
|
|
|
|
|
|
}; |
328
|
|
|
|
|
|
|
} |
329
|
|
|
|
|
|
|
else |
330
|
|
|
|
|
|
|
{ |
331
|
0
|
|
|
|
|
|
$options .= " 0x$args{'Key'}->{'Keyid'}"; |
332
|
|
|
|
|
|
|
}; |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
# If we are also signing, we need to tell which key and password. |
335
|
0
|
0
|
|
|
|
|
$options .= " -u 0x$args{'Sign'}->{'Keyid'}" if (defined $args{'Sign'}->{'Keyid'}); |
336
|
0
|
0
|
|
|
|
|
$options .= " -z '$args{'Password'}'" if (defined $args{'Password'}); |
337
|
|
|
|
|
|
|
|
338
|
0
|
|
|
|
|
|
Debug ("PGP::Encrypt Options=$options"); |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
# procede to send the document to PGP. |
341
|
0
|
|
|
|
|
|
$self->Exec ($options, FIN, FOUT, FERR); |
342
|
|
|
|
|
|
|
|
343
|
0
|
0
|
|
|
|
|
if ($args{'File'}) |
344
|
|
|
|
|
|
|
{ |
345
|
0
|
0
|
|
|
|
|
open (PLAIN, "< $args{'File'}") || carp "$args{'File'} not found"; |
346
|
0
|
|
|
|
|
|
print FIN ; |
347
|
0
|
|
|
|
|
|
close (PLAIN); |
348
|
|
|
|
|
|
|
} else |
349
|
|
|
|
|
|
|
{ |
350
|
0
|
|
|
|
|
|
print FIN $args{'Text'}; |
351
|
|
|
|
|
|
|
}; |
352
|
0
|
|
|
|
|
|
close (FIN); |
353
|
|
|
|
|
|
|
|
354
|
0
|
|
|
|
|
|
$document = join ('', ); |
355
|
|
|
|
|
|
|
|
356
|
0
|
0
|
|
|
|
|
if ($args{'Encryptfile'}) |
357
|
|
|
|
|
|
|
{ |
358
|
0
|
0
|
|
|
|
|
open (ENCRYPT, "> $args{'Encryptfile'}") || carp "Can not create $args{'Encryptfile'}"; |
359
|
0
|
|
|
|
|
|
print ENCRYPT $document; |
360
|
0
|
|
|
|
|
|
close (ENCRYPT); |
361
|
|
|
|
|
|
|
}; |
362
|
|
|
|
|
|
|
|
363
|
0
|
|
|
|
|
|
return ($document); |
364
|
|
|
|
|
|
|
} |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
=item * PGP::Decrypt |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
\%stats = Decrypt $pgp %args; |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
C will use a PGP secret key to decrypt a message. The secret |
372
|
|
|
|
|
|
|
key must reside on the secret keyring. The C method follows |
373
|
|
|
|
|
|
|
the same conventions for data transfer that C and C |
374
|
|
|
|
|
|
|
follow. The resulting associative array that is sent back contains |
375
|
|
|
|
|
|
|
three fields: |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
Text The decrypted document |
378
|
|
|
|
|
|
|
Signature PGP::Key object of the signer (if any) |
379
|
|
|
|
|
|
|
Time Time document was signed (if any) |
380
|
|
|
|
|
|
|
Key PGP::Key object used to decrypt document |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
The following are the accepted arguments: |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
Password Password to use for decrypting |
385
|
|
|
|
|
|
|
File File to decrypt |
386
|
|
|
|
|
|
|
Keyring Needed to return info about document |
387
|
|
|
|
|
|
|
Plainfile File to put the data in |
388
|
|
|
|
|
|
|
Text Document to decrypt |
389
|
|
|
|
|
|
|
Wipe Remove original file |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
The C argument is required to perform the decryption of the |
392
|
|
|
|
|
|
|
document. The C argument is also required if any document |
393
|
|
|
|
|
|
|
information is to be returned. |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
=cut |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
sub Decrypt |
399
|
|
|
|
|
|
|
{ |
400
|
0
|
|
|
0
|
|
|
my ($self, %args) = @_; |
401
|
0
|
|
|
|
|
|
local ($options, $document, $key, @keys); |
402
|
|
|
|
|
|
|
|
403
|
0
|
|
|
|
|
|
Debug ("PGP::Decrypt Args=", Dumper \%args); |
404
|
|
|
|
|
|
|
|
405
|
0
|
|
|
|
|
|
$options = "-f "; |
406
|
0
|
0
|
|
|
|
|
$options = "-z '$args{Password}'" if (defined $args{Password}); |
407
|
|
|
|
|
|
|
|
408
|
0
|
|
|
|
|
|
Debug ("PGP::Decrypt Options=$options"); |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
# procede to send the document to PGP. |
411
|
0
|
|
|
|
|
|
$self->Exec ($options, FIN, FOUT, FERR); |
412
|
|
|
|
|
|
|
|
413
|
0
|
0
|
|
|
|
|
if (defined $args{File}) |
414
|
|
|
|
|
|
|
{ |
415
|
0
|
0
|
|
|
|
|
open (ENCRYPT, "< $args{File}") || carp "$args{File} not found"; |
416
|
0
|
|
|
|
|
|
print FIN ; |
417
|
0
|
|
|
|
|
|
close (ENCRYPT); |
418
|
|
|
|
|
|
|
} else |
419
|
|
|
|
|
|
|
{ |
420
|
0
|
|
|
|
|
|
print FIN $args{Text}; |
421
|
|
|
|
|
|
|
}; |
422
|
0
|
|
|
|
|
|
close (FIN); |
423
|
|
|
|
|
|
|
|
424
|
0
|
|
|
|
|
|
$document = join ('', ); |
425
|
|
|
|
|
|
|
|
426
|
0
|
0
|
|
|
|
|
if ($args{Plainfile}) |
427
|
|
|
|
|
|
|
{ |
428
|
0
|
0
|
|
|
|
|
open (PLAIN, "> $args{Plainfile}") || carp "Can not create $args{Plainfile}"; |
429
|
0
|
|
|
|
|
|
print PLAIN $document; |
430
|
0
|
|
|
|
|
|
close (PLAIN); |
431
|
|
|
|
|
|
|
}; |
432
|
|
|
|
|
|
|
|
433
|
0
|
0
|
|
|
|
|
if (defined $args{Keyring}) |
434
|
|
|
|
|
|
|
{ |
435
|
0
|
|
|
|
|
|
$keyring = $args{Keyring}; |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
# gather stats on the decrypted document |
438
|
0
|
|
|
|
|
|
while () |
439
|
|
|
|
|
|
|
{ |
440
|
|
|
|
|
|
|
# Encryption fields |
441
|
|
|
|
|
|
|
/Key ID (\w+)\,/i && do |
442
|
0
|
0
|
|
|
|
|
{ $key = Find $keyring Keyid => $1 }; |
|
0
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
# Signature fields |
445
|
|
|
|
|
|
|
/^Good signature from user "(.+)"/i && do |
446
|
0
|
0
|
|
|
|
|
{ $signature = Find $keyring Desc => $1 }; |
|
0
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
/^Signature made (\d+)\/(\d+)\/(\d+) (\d+):(\d+)/ && do |
448
|
0
|
0
|
|
|
|
|
{ $time = &timegm (0, $5, $4, $3, $2-1, ($1 > 1900) ? $1 - 1900 : $1) }; |
|
0
|
0
|
|
|
|
|
|
449
|
|
|
|
|
|
|
}; |
450
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
return ({ |
452
|
0
|
|
|
|
|
|
Text => $document, |
453
|
|
|
|
|
|
|
Signature => $signature, |
454
|
|
|
|
|
|
|
Time => $time, |
455
|
|
|
|
|
|
|
Key => $key |
456
|
|
|
|
|
|
|
}); |
457
|
|
|
|
|
|
|
} |
458
|
|
|
|
|
|
|
else |
459
|
|
|
|
|
|
|
{ |
460
|
0
|
|
|
|
|
|
return ( { Text => $document } ); |
461
|
|
|
|
|
|
|
}; |
462
|
|
|
|
|
|
|
} |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
=item * PGP::Info |
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
\%doc = Info $pgp %args; |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
C returns an associative array or a reference to an |
470
|
|
|
|
|
|
|
associative array to the caller. This returned structure contains |
471
|
|
|
|
|
|
|
information about the document that is sent to the C |
472
|
|
|
|
|
|
|
method. The returned structure is fairly straight forward: |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
Text The decrypted document |
475
|
|
|
|
|
|
|
Signature PGP::Key object of the signer (if any) |
476
|
|
|
|
|
|
|
Time Time document was signed (if any) |
477
|
|
|
|
|
|
|
Key PGP::Key object used to decrypt document |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
The C method currently accepts the following arguments: |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
File File to decrypt |
482
|
|
|
|
|
|
|
Text Document to decrypt |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
At this point, we cheat with the C method. Basically |
485
|
|
|
|
|
|
|
we send the document through the C method and grab the |
486
|
|
|
|
|
|
|
results. |
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
=cut |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
sub Info |
492
|
|
|
|
|
|
|
{ |
493
|
0
|
|
|
0
|
|
|
my ($self, %args) = @_; |
494
|
|
|
|
|
|
|
|
495
|
0
|
|
|
|
|
|
$info = $self->Decrypt (%args, Plainfile => '/dev/null'); |
496
|
|
|
|
|
|
|
|
497
|
0
|
|
|
|
|
|
return ($info); |
498
|
|
|
|
|
|
|
} |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
=head2 PGP::Keyring |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
The C object is used to perform key management functions. |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
=cut |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
package PGP::Keyring; |
509
|
|
|
|
|
|
|
@ISA = qw(PGP::Pipe); |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
=item * PGP::Keyring::new |
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
$Keyring = new PGP::Keyring $pgpkeyring; |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
=cut |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
sub new |
521
|
|
|
|
|
|
|
{ |
522
|
0
|
|
|
0
|
|
|
my ($class, $keydir) = @_; |
523
|
0
|
|
|
|
|
|
my ($pgp) = new PGP::Pipe $keydir; # inherit the PGP variables |
524
|
|
|
|
|
|
|
|
525
|
0
|
|
|
|
|
|
$self = { %$pgp, |
526
|
|
|
|
|
|
|
Keys => [], |
527
|
|
|
|
|
|
|
Modified => 1 |
528
|
|
|
|
|
|
|
}; |
529
|
|
|
|
|
|
|
|
530
|
0
|
|
|
|
|
|
bless $self, $class; |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
# Need to update the Keys field so that it is useful. |
533
|
0
|
|
|
|
|
|
$self->List_Keys; |
534
|
|
|
|
|
|
|
|
535
|
0
|
|
|
|
|
|
$self; |
536
|
|
|
|
|
|
|
}; |
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
=item * PGP::Keyring::Add_Key |
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
Add_Key $Keyring %args; |
542
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
Add a signature to the keyring. At this point, there is no error |
544
|
|
|
|
|
|
|
checking or verification that the key has been added. |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
The C<%args> associative array may contain the following: |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
Text The value is the public key |
549
|
|
|
|
|
|
|
File File where the public key is stored |
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
=cut |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
sub Add_Key |
554
|
|
|
|
|
|
|
{ |
555
|
0
|
|
|
0
|
|
|
my ($self, %args) = @_; |
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
# PGP does not seem to like to take a keyring from stdin. |
558
|
|
|
|
|
|
|
# must place everything in a temporary file for processing. |
559
|
|
|
|
|
|
|
|
560
|
0
|
0
|
|
|
|
|
if ($args{Text}) |
561
|
|
|
|
|
|
|
{ |
562
|
0
|
|
|
|
|
|
open (TEMP, ">/tmp/.pgp.$$"); |
563
|
0
|
|
|
|
|
|
print TEMP $args{Text}; |
564
|
0
|
|
|
|
|
|
close TEMP; |
565
|
|
|
|
|
|
|
} |
566
|
|
|
|
|
|
|
else |
567
|
|
|
|
|
|
|
{ |
568
|
|
|
|
|
|
|
# Is this portable? (i.e. PC-based perl) |
569
|
0
|
|
|
|
|
|
system ("$Config{'cp'} $args{File} /tmp/.pgp.$$"); |
570
|
|
|
|
|
|
|
}; |
571
|
|
|
|
|
|
|
|
572
|
0
|
|
|
|
|
|
$self->Exec ("-ka /tmp/.pgp.$$", FIN, FOUT, FERR); |
573
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
# # send the key to the PGP process |
575
|
|
|
|
|
|
|
# if ($args{Text}) |
576
|
|
|
|
|
|
|
# { print FIN "$args{Text}\n" } |
577
|
|
|
|
|
|
|
# else |
578
|
|
|
|
|
|
|
# { |
579
|
|
|
|
|
|
|
# open (KEY, "<$args{File}"); |
580
|
|
|
|
|
|
|
# print FIN ; |
581
|
|
|
|
|
|
|
# close KEY; |
582
|
|
|
|
|
|
|
# }; |
583
|
|
|
|
|
|
|
# close FIN; |
584
|
|
|
|
|
|
|
|
585
|
0
|
|
|
|
|
|
$self->{Modified}++; |
586
|
|
|
|
|
|
|
} |
587
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
=item * PGP::Keyring::Remove_Key |
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
Remove_Key $Keyring $key; |
592
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
Remove a signature from a keyring. |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
=cut |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
sub Remove_Key |
599
|
|
|
|
|
|
|
{ |
600
|
0
|
|
|
0
|
|
|
my ($self, $key) = @_; |
601
|
|
|
|
|
|
|
|
602
|
0
|
|
|
|
|
|
$self->Exec ("-kr -f 0x$key->{Keyid}", FIN, FOUT, FERR); |
603
|
|
|
|
|
|
|
|
604
|
0
|
|
|
|
|
|
$self->{Modified}++; |
605
|
|
|
|
|
|
|
} |
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
|
608
|
|
|
|
|
|
|
=item * PGP::Keyring::Extract_Key |
609
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
$key = Extract_Key $Keyring $keyobj; |
611
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
Extract a key from the specified keyring. A real simple dirty way of |
613
|
|
|
|
|
|
|
extracting the key. |
614
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
=cut |
616
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
sub Extract_Key |
619
|
|
|
|
|
|
|
{ |
620
|
0
|
|
|
0
|
|
|
my ($self, %args) = @_; |
621
|
|
|
|
|
|
|
|
622
|
0
|
|
|
|
|
|
$self->Exec ("-kxa -f 0x$args{Keyid}", FIN, FOUT, FERR); |
623
|
|
|
|
|
|
|
|
624
|
0
|
|
|
|
|
|
@key = ; |
625
|
0
|
|
|
|
|
|
return (join ('', @key)); |
626
|
|
|
|
|
|
|
} |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
=item * PGP::Keyring::Sign_Key |
630
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
Sign_Key $Keyring %args; |
632
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
This method will sign a designated key with the |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
=cut |
637
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
sub Sign_Key |
639
|
|
|
|
|
|
|
{ |
640
|
0
|
|
|
0
|
|
|
my ($self, %args) = @_; |
641
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
# We absolutely need a password to continue! |
643
|
0
|
0
|
|
|
|
|
return if (! exists $args{Password}); |
644
|
|
|
|
|
|
|
|
645
|
0
|
|
|
|
|
|
$result = $self->Exec ("-ks 0x$args{Keyid}", FIN, FOUT, FERR, 1); |
646
|
|
|
|
|
|
|
|
647
|
0
|
|
|
|
|
|
open (KEYB, ">/dev/tty"); |
648
|
|
|
|
|
|
|
|
649
|
|
|
|
|
|
|
# now we get to act as a user to get the key signed! |
650
|
0
|
|
|
|
|
|
while ($output = ) |
651
|
|
|
|
|
|
|
{ |
652
|
0
|
|
|
|
|
|
PGP::Pipe::Debug ("FOUT: $output"); |
653
|
0
|
0
|
|
|
|
|
last if ($output =~ /user ID/ ); |
654
|
|
|
|
|
|
|
}; |
655
|
|
|
|
|
|
|
|
656
|
0
|
|
|
|
|
|
print KEYB "y\n"; # say yes it is the key we want |
657
|
0
|
|
|
|
|
|
print "Sent a 'y' keystroke..."; |
658
|
|
|
|
|
|
|
|
659
|
0
|
|
|
|
|
|
while ($output = ) |
660
|
|
|
|
|
|
|
{ |
661
|
0
|
|
|
|
|
|
PGP::Pipe::Debug ("FOUT: $output"); |
662
|
0
|
0
|
|
|
|
|
last if ($output =~ /Enter pass phrase:/); |
663
|
|
|
|
|
|
|
}; |
664
|
|
|
|
|
|
|
|
665
|
0
|
|
|
|
|
|
print KEYB "$args{Password}\n"; |
666
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
# right now, we just hope that it signed it fine! |
668
|
0
|
|
|
|
|
|
close (FIN); |
669
|
0
|
|
|
|
|
|
close (FOUT); |
670
|
0
|
|
|
|
|
|
close (FERR); |
671
|
|
|
|
|
|
|
# Keyring has been modified. |
672
|
0
|
|
|
|
|
|
$self->{Modified}++; |
673
|
|
|
|
|
|
|
|
674
|
0
|
|
|
|
|
|
$self->Extract_Key (Keyid => $args{Keyid}); |
675
|
|
|
|
|
|
|
} |
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
|
678
|
|
|
|
|
|
|
=item * PGP::Keyring::Generate_Key |
679
|
|
|
|
|
|
|
|
680
|
|
|
|
|
|
|
Generate_Key $Keyring; |
681
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
Generate a new secret and public key set. This routine will not be |
683
|
|
|
|
|
|
|
present in the first rev of code. It is also subject to change. |
684
|
|
|
|
|
|
|
|
685
|
|
|
|
|
|
|
=cut |
686
|
|
|
|
|
|
|
|
687
|
|
|
|
|
|
|
|
688
|
|
|
|
|
|
|
sub Generate_Key |
689
|
|
|
|
|
|
|
{ |
690
|
0
|
|
|
0
|
|
|
my ($self) = shift; |
691
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
# be sure to use +nomanual as an option |
693
|
0
|
|
|
|
|
|
$self->{Modified}++; |
694
|
|
|
|
|
|
|
} |
695
|
|
|
|
|
|
|
|
696
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
=item * PGP::Keyring::Revoke_Key |
698
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
$certificate = Revoke_Key $Keyring $Keyobj; |
700
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
Produce a revocation certificate for the given key. Revocation is |
702
|
|
|
|
|
|
|
actually a two step process. We must first mark the key as revoked. |
703
|
|
|
|
|
|
|
This is the same as the C method. After flaging the key, |
704
|
|
|
|
|
|
|
the key must be extracted to produce a revocation certificate. |
705
|
|
|
|
|
|
|
|
706
|
|
|
|
|
|
|
=cut |
707
|
|
|
|
|
|
|
|
708
|
|
|
|
|
|
|
sub Revoke_Key |
709
|
|
|
|
|
|
|
{ |
710
|
0
|
|
|
0
|
|
|
my ($self, $key) = @_; |
711
|
|
|
|
|
|
|
|
712
|
0
|
|
|
|
|
|
$self->Remove_Key ($key); |
713
|
0
|
|
|
|
|
|
return ($self->Extract_Key ($key)); |
714
|
|
|
|
|
|
|
} |
715
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
|
717
|
|
|
|
|
|
|
=item * PGP::Keyring::List_Keys |
718
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
@{$keyobj} = List_Keys $Keyring; |
720
|
|
|
|
|
|
|
|
721
|
|
|
|
|
|
|
List the keys on a given keyring. This routine simply captures the output |
722
|
|
|
|
|
|
|
of the command C and does a quick parse on it. It |
723
|
|
|
|
|
|
|
takes the lines that it parses, and constructs L objects. |
724
|
|
|
|
|
|
|
In the near future, this function will also pass the trust factors to the |
725
|
|
|
|
|
|
|
PGP::Key object. We got it in the output, so why not use it. |
726
|
|
|
|
|
|
|
|
727
|
|
|
|
|
|
|
=cut |
728
|
|
|
|
|
|
|
|
729
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
sub List_Keys |
731
|
|
|
|
|
|
|
{ |
732
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
733
|
0
|
|
|
|
|
|
my ($keyid, $trust, $validity, $desc); |
734
|
|
|
|
|
|
|
|
735
|
|
|
|
|
|
|
# do not call PGP if the keys have not been modified |
736
|
0
|
0
|
|
|
|
|
if (!$self->{Modified}) |
737
|
|
|
|
|
|
|
{ |
738
|
0
|
0
|
|
|
|
|
return (wantarray ? @{$self->{Keys}} : $self->{Keys}); |
|
0
|
|
|
|
|
|
|
739
|
|
|
|
|
|
|
}; |
740
|
|
|
|
|
|
|
|
741
|
|
|
|
|
|
|
# clear the old array and get a list of all the keys again |
742
|
0
|
|
|
|
|
|
$self->{Keys} = undef; |
743
|
0
|
|
|
|
|
|
$self->Exec ("-kc", FIN, FOUT, FERR); |
744
|
|
|
|
|
|
|
|
745
|
0
|
|
|
|
|
|
while () |
746
|
|
|
|
|
|
|
{ |
747
|
|
|
|
|
|
|
# public key entry |
748
|
|
|
|
|
|
|
/^pub/ && do |
749
|
0
|
0
|
|
|
|
|
{ push (@{$self->{Keys}}, PGP::Key->new ($_)) }; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
/^sig/ && do |
751
|
0
|
0
|
|
|
|
|
{ $self->{Keys}->[$#{$self->{Keys}}]->Add_Sig ($_) }; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
752
|
|
|
|
|
|
|
# more IDs to current key? |
753
|
|
|
|
|
|
|
/^\s{30,32}(.+)$/ && do |
754
|
0
|
0
|
|
|
|
|
{ $self->{Keys}->[$#{$self->{Keys}}]->AddID ($1) }; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
755
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
# public key trust entries follow |
757
|
0
|
0
|
|
|
|
|
last if (/^\s+KeyID\s+Trust\s+Validity\s+User ID/); |
758
|
|
|
|
|
|
|
}; |
759
|
|
|
|
|
|
|
|
760
|
0
|
|
|
|
|
|
while () |
761
|
|
|
|
|
|
|
{ |
762
|
|
|
|
|
|
|
# valid entry? |
763
|
|
|
|
|
|
|
/^..(\w+)\s+(\w+)\s+(\w+)\s+(.+)/ && do |
764
|
0
|
0
|
|
|
|
|
{ |
765
|
0
|
|
|
|
|
|
$keyid = $1; $trust = $2; $validity = $3; $desc = $4; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
766
|
0
|
|
|
|
|
|
$key = Find $self Keyid => $keyid; |
767
|
|
|
|
|
|
|
|
768
|
0
|
|
|
|
|
|
$key->Trust ($trust); |
769
|
0
|
|
|
|
|
|
$key->Validity ($validity); |
770
|
|
|
|
|
|
|
}; |
771
|
|
|
|
|
|
|
}; |
772
|
|
|
|
|
|
|
|
773
|
|
|
|
|
|
|
# Now that we have the latest keyring data, reset the modified flag |
774
|
0
|
|
|
|
|
|
undef $self->{Modified}; |
775
|
|
|
|
|
|
|
|
776
|
0
|
0
|
|
|
|
|
return (wantarray ? @{$self->{Keys}} : $self->{Keys}); |
|
0
|
|
|
|
|
|
|
777
|
|
|
|
|
|
|
} |
778
|
|
|
|
|
|
|
|
779
|
|
|
|
|
|
|
|
780
|
|
|
|
|
|
|
=item * PGP::Keyring::Find |
781
|
|
|
|
|
|
|
|
782
|
|
|
|
|
|
|
@keys = Find $keyring %criteria; |
783
|
|
|
|
|
|
|
\@keys = Find $keyring %criteria; |
784
|
|
|
|
|
|
|
$key = Find $keyring %criteria; (Single match) |
785
|
|
|
|
|
|
|
|
786
|
|
|
|
|
|
|
Function to locate a keys matching some criteria. This is not |
787
|
|
|
|
|
|
|
implemented as nicely as it should be (read kludge). The |
788
|
|
|
|
|
|
|
C<%criteria> array is used to specify what keys are to be selected. |
789
|
|
|
|
|
|
|
The keys for the C<%criteria> array are as follows: |
790
|
|
|
|
|
|
|
|
791
|
|
|
|
|
|
|
Keyid Key with specifed keyid |
792
|
|
|
|
|
|
|
Owner Name of the owner of the key |
793
|
|
|
|
|
|
|
Email Email address of owner |
794
|
|
|
|
|
|
|
Bits Size of the key in bits |
795
|
|
|
|
|
|
|
Date Date that the key was generated |
796
|
|
|
|
|
|
|
Desc Owner and Email keys combined |
797
|
|
|
|
|
|
|
|
798
|
|
|
|
|
|
|
The values for each specifed key (assocative array) are compared |
799
|
|
|
|
|
|
|
using a case-insensitive regular expression. This means that |
800
|
|
|
|
|
|
|
only a portion of the key data needs to be specified to have it |
801
|
|
|
|
|
|
|
selected. This also means that specifing too little criteria |
802
|
|
|
|
|
|
|
can cause several keys to be selected. |
803
|
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
=cut |
805
|
|
|
|
|
|
|
|
806
|
|
|
|
|
|
|
|
807
|
|
|
|
|
|
|
sub Find |
808
|
|
|
|
|
|
|
{ |
809
|
0
|
|
|
0
|
|
|
my ($self, %criteria) = @_; |
810
|
0
|
|
|
|
|
|
my ($key, @match, $crit); |
811
|
|
|
|
|
|
|
|
812
|
0
|
|
|
|
|
|
NONMATCH: |
813
|
0
|
|
|
|
|
|
foreach $key (@{$self->{Keys}}) |
814
|
|
|
|
|
|
|
{ |
815
|
0
|
|
|
|
|
|
foreach $crit (keys %criteria) |
816
|
|
|
|
|
|
|
{ |
817
|
0
|
0
|
|
|
|
|
if ($crit eq 'Desc') |
|
|
0
|
|
|
|
|
|
818
|
|
|
|
|
|
|
{ |
819
|
1
|
|
|
1
|
|
1353
|
for ($[ .. $#{$key->{Owner}}) |
|
1
|
|
|
|
|
2016
|
|
|
1
|
|
|
|
|
385
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
{ |
821
|
0
|
|
|
|
|
|
($keydesc = "$key->{Owner}->[$_] $key->{Email}->[$_]") =~ tr/a-zA-Z0-9@.!\-//cd; |
822
|
0
|
|
|
|
|
|
$keydesc =~ tr/ / /s; |
823
|
|
|
|
|
|
|
|
824
|
0
|
|
|
|
|
|
$desc = $criteria{$crit}; |
825
|
0
|
|
|
|
|
|
$desc =~ tr/a-zA-Z0-9@.!\-//cd; # update the tr/// above too! |
826
|
0
|
|
|
|
|
|
$desc =~ tr/ / /s; |
827
|
|
|
|
|
|
|
|
828
|
0
|
0
|
|
|
|
|
next NONMATCH if ($keydesc !~ /$desc/i); |
829
|
|
|
|
|
|
|
}; |
830
|
|
|
|
|
|
|
} |
831
|
|
|
|
|
|
|
elsif (ref ($key->{$crit}) ne 'ARRAY') |
832
|
0
|
0
|
|
|
|
|
{ next NONMATCH if ($key->{$crit} !~ /$criteria{$crit}/i) } |
833
|
|
|
|
|
|
|
else |
834
|
|
|
|
|
|
|
{ |
835
|
0
|
|
|
|
|
|
for ($[ .. $#{$key->{$crit}}) |
|
0
|
|
|
|
|
|
|
836
|
0
|
0
|
|
|
|
|
{ next NONMATCH if ($key->{$crit}->[$_] !~ /$criteria{$crit}/i) }; |
837
|
|
|
|
|
|
|
}; |
838
|
|
|
|
|
|
|
}; |
839
|
0
|
|
|
|
|
|
push (@match, $key); |
840
|
|
|
|
|
|
|
}; |
841
|
|
|
|
|
|
|
|
842
|
|
|
|
|
|
|
# return a scalar if there is only one match |
843
|
0
|
0
|
|
|
|
|
return ($match[$[]) if ($#match == 0); |
844
|
0
|
0
|
|
|
|
|
return (wantarray ? @match : \@match); |
845
|
|
|
|
|
|
|
} |
846
|
|
|
|
|
|
|
|
847
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
|
849
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
package PGP::Key; |
851
|
|
|
|
|
|
|
@ISA = qw(PGP::Pipe); |
852
|
|
|
|
|
|
|
|
853
|
1
|
|
|
1
|
|
10
|
use Time::Local; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
137
|
|
854
|
1
|
|
|
1
|
|
224825
|
use Dumper; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
855
|
|
|
|
|
|
|
|
856
|
|
|
|
|
|
|
=head2 PGP::Key |
857
|
|
|
|
|
|
|
|
858
|
|
|
|
|
|
|
The C object is used to store the individual key |
859
|
|
|
|
|
|
|
information. It is primarily used by the C object and |
860
|
|
|
|
|
|
|
for passing to the various methods that accept key parameters to |
861
|
|
|
|
|
|
|
encrypt and sign documents. |
862
|
|
|
|
|
|
|
|
863
|
|
|
|
|
|
|
Future revisions will provide actual methods to do key comparison for |
864
|
|
|
|
|
|
|
the trust and validity factors. These methods will provide a |
865
|
|
|
|
|
|
|
standardized way to determine which keys can be trusted and which |
866
|
|
|
|
|
|
|
keys should not be used at all. |
867
|
|
|
|
|
|
|
|
868
|
|
|
|
|
|
|
=cut |
869
|
|
|
|
|
|
|
|
870
|
|
|
|
|
|
|
=item * PGP::Key::new |
871
|
|
|
|
|
|
|
|
872
|
|
|
|
|
|
|
$key = new PGP::Key $keyline; |
873
|
|
|
|
|
|
|
|
874
|
|
|
|
|
|
|
This is the constructor for the C object. This is primarily |
875
|
|
|
|
|
|
|
used by the C methods. The C methods keep |
876
|
|
|
|
|
|
|
track of the keys and maintain the Trust and Validity components. |
877
|
|
|
|
|
|
|
About the only useful method is the C, which |
878
|
|
|
|
|
|
|
will return a string that is the finger print of the given key. |
879
|
|
|
|
|
|
|
|
880
|
|
|
|
|
|
|
=cut |
881
|
|
|
|
|
|
|
|
882
|
|
|
|
|
|
|
sub new |
883
|
|
|
|
|
|
|
{ |
884
|
|
|
|
|
|
|
my ($class, $keyline) = @_; |
885
|
|
|
|
|
|
|
my ($bits, $keyid, $date, $owner, $pgp); |
886
|
|
|
|
|
|
|
|
887
|
|
|
|
|
|
|
chomp $keyline; |
888
|
|
|
|
|
|
|
($bits, $keyid, $date, $owner) = PGP::Key->_keyparse ($keyline); |
889
|
|
|
|
|
|
|
|
890
|
|
|
|
|
|
|
$pgp = new PGP::Pipe; # inherit the PGP variables |
891
|
|
|
|
|
|
|
$self = { %$pgp, |
892
|
|
|
|
|
|
|
Bits => $bits, |
893
|
|
|
|
|
|
|
Keyid => $keyid, |
894
|
|
|
|
|
|
|
Date => $date, |
895
|
|
|
|
|
|
|
Owner => [], |
896
|
|
|
|
|
|
|
Email => [] |
897
|
|
|
|
|
|
|
}; |
898
|
|
|
|
|
|
|
|
899
|
|
|
|
|
|
|
bless $self, $class; |
900
|
|
|
|
|
|
|
|
901
|
|
|
|
|
|
|
# Add on the ID information to the key object |
902
|
|
|
|
|
|
|
$self->Add_ID ($owner); |
903
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
$self; |
905
|
|
|
|
|
|
|
} |
906
|
|
|
|
|
|
|
|
907
|
|
|
|
|
|
|
|
908
|
|
|
|
|
|
|
=item + PGP::Key::Add_ID |
909
|
|
|
|
|
|
|
|
910
|
|
|
|
|
|
|
Add_ID $key $desc; |
911
|
|
|
|
|
|
|
|
912
|
|
|
|
|
|
|
The C method will add identification information to the owner |
913
|
|
|
|
|
|
|
and email portions of the given C object. This is to support |
914
|
|
|
|
|
|
|
keys that multiple identification packets associated with them. |
915
|
|
|
|
|
|
|
|
916
|
|
|
|
|
|
|
=cut |
917
|
|
|
|
|
|
|
|
918
|
|
|
|
|
|
|
sub Add_ID |
919
|
|
|
|
|
|
|
{ |
920
|
|
|
|
|
|
|
my ($self, $desc) = @_; |
921
|
|
|
|
|
|
|
|
922
|
|
|
|
|
|
|
# we have a total of three types of entries for the description |
923
|
|
|
|
|
|
|
# full name /\<.+\>/ |
924
|
|
|
|
|
|
|
# email@domain /[\w\.\-\+]@[\w\.\-\+]/ |
925
|
|
|
|
|
|
|
# full name all other |
926
|
|
|
|
|
|
|
|
927
|
|
|
|
|
|
|
if ($desc =~ /\<.+\>/) |
928
|
|
|
|
|
|
|
{ |
929
|
|
|
|
|
|
|
$desc =~ /([^\<]+)\s+\<(.+)\>/; |
930
|
|
|
|
|
|
|
push (@{$self->{Owner}}, $1); |
931
|
|
|
|
|
|
|
push (@{$self->{Email}}, $2); |
932
|
|
|
|
|
|
|
} |
933
|
|
|
|
|
|
|
elsif ($desc =~ /[\w\.\-\+]@[\w\.\-\+]/) |
934
|
|
|
|
|
|
|
{ |
935
|
|
|
|
|
|
|
push (@{$self->{Owner}}, undef); |
936
|
|
|
|
|
|
|
push (@{$self->{Email}}, $desc); |
937
|
|
|
|
|
|
|
} |
938
|
|
|
|
|
|
|
else |
939
|
|
|
|
|
|
|
{ |
940
|
|
|
|
|
|
|
push (@{$self->{Owner}}, $desc); |
941
|
|
|
|
|
|
|
push (@{$self->{Email}}, undef); |
942
|
|
|
|
|
|
|
}; |
943
|
|
|
|
|
|
|
} |
944
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
|
946
|
|
|
|
|
|
|
=item * PGP::Key::Add_Sig |
947
|
|
|
|
|
|
|
|
948
|
|
|
|
|
|
|
|
949
|
|
|
|
|
|
|
|
950
|
|
|
|
|
|
|
=cut |
951
|
|
|
|
|
|
|
|
952
|
|
|
|
|
|
|
sub Add_Sig |
953
|
|
|
|
|
|
|
{ |
954
|
|
|
|
|
|
|
my ($self, $line) = @_; |
955
|
|
|
|
|
|
|
|
956
|
|
|
|
|
|
|
|
957
|
|
|
|
|
|
|
} |
958
|
|
|
|
|
|
|
|
959
|
|
|
|
|
|
|
|
960
|
|
|
|
|
|
|
=item * PGP::Key::Trust |
961
|
|
|
|
|
|
|
|
962
|
|
|
|
|
|
|
This will set and/or retrieve the trust factor. Currently, this routine |
963
|
|
|
|
|
|
|
will just store what is sent to it. Need to define some "trust" |
964
|
|
|
|
|
|
|
variables and provide useful routines to use them. |
965
|
|
|
|
|
|
|
|
966
|
|
|
|
|
|
|
=cut |
967
|
|
|
|
|
|
|
|
968
|
|
|
|
|
|
|
|
969
|
|
|
|
|
|
|
sub Trust |
970
|
|
|
|
|
|
|
{ |
971
|
|
|
|
|
|
|
my ($self, $trust) = @_; |
972
|
|
|
|
|
|
|
|
973
|
|
|
|
|
|
|
$self->{Trust} = $trust if ($trust); |
974
|
|
|
|
|
|
|
$self->{Trust}; |
975
|
|
|
|
|
|
|
} |
976
|
|
|
|
|
|
|
|
977
|
|
|
|
|
|
|
|
978
|
|
|
|
|
|
|
=item * PGP::Key::Validity |
979
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
This function will set and/or return the validity factor. This |
981
|
|
|
|
|
|
|
subroutine is very much like PGP::Key::Trust. It also needs to be |
982
|
|
|
|
|
|
|
worked on quite a bit. |
983
|
|
|
|
|
|
|
|
984
|
|
|
|
|
|
|
=cut |
985
|
|
|
|
|
|
|
|
986
|
|
|
|
|
|
|
|
987
|
|
|
|
|
|
|
sub Validity |
988
|
|
|
|
|
|
|
{ |
989
|
|
|
|
|
|
|
my ($self, $validity) = @_; |
990
|
|
|
|
|
|
|
|
991
|
|
|
|
|
|
|
$self->{Validity} = $validity if ($validity); |
992
|
|
|
|
|
|
|
$self->{Validity}; |
993
|
|
|
|
|
|
|
} |
994
|
|
|
|
|
|
|
|
995
|
|
|
|
|
|
|
|
996
|
|
|
|
|
|
|
=item * PGP::Key::Fingerprint |
997
|
|
|
|
|
|
|
|
998
|
|
|
|
|
|
|
$fingerprint = Fingerprint $key; |
999
|
|
|
|
|
|
|
|
1000
|
|
|
|
|
|
|
|
1001
|
|
|
|
|
|
|
=cut |
1002
|
|
|
|
|
|
|
|
1003
|
|
|
|
|
|
|
# does the Fingerprint method belong in the key management stuff? |
1004
|
|
|
|
|
|
|
|
1005
|
|
|
|
|
|
|
sub Fingerprint |
1006
|
|
|
|
|
|
|
{ |
1007
|
|
|
|
|
|
|
my ($self) = shift; |
1008
|
|
|
|
|
|
|
|
1009
|
|
|
|
|
|
|
$self->Exec ("-kvc", FIN, FOUT, FERR); |
1010
|
|
|
|
|
|
|
|
1011
|
|
|
|
|
|
|
while () |
1012
|
|
|
|
|
|
|
{ |
1013
|
|
|
|
|
|
|
/Key fingerprint = (.+)[\n\r]$/ && do |
1014
|
|
|
|
|
|
|
{ $fingerprint = $1 }; |
1015
|
|
|
|
|
|
|
}; |
1016
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
return $fingerprint; |
1018
|
|
|
|
|
|
|
}; |
1019
|
|
|
|
|
|
|
|
1020
|
|
|
|
|
|
|
|
1021
|
|
|
|
|
|
|
=item * PGP::Key::Format |
1022
|
|
|
|
|
|
|
|
1023
|
|
|
|
|
|
|
$formatted_text = Format $key %args; |
1024
|
|
|
|
|
|
|
|
1025
|
|
|
|
|
|
|
This method will return a formatted text string for a key. It |
1026
|
|
|
|
|
|
|
is essentially the same as do a 'pgp -kv' or 'pgp -kvv' for |
1027
|
|
|
|
|
|
|
a key object. Currently the only argument that C will |
1028
|
|
|
|
|
|
|
recognize is the C argument. The C parameter |
1029
|
|
|
|
|
|
|
will list the signatures that have certified the current |
1030
|
|
|
|
|
|
|
key object. |
1031
|
|
|
|
|
|
|
|
1032
|
|
|
|
|
|
|
=cut |
1033
|
|
|
|
|
|
|
|
1034
|
|
|
|
|
|
|
sub Format |
1035
|
|
|
|
|
|
|
{ |
1036
|
|
|
|
|
|
|
my ($self, %args) = @_; |
1037
|
|
|
|
|
|
|
my ($day, $month, $year) = $self->_date ($self->{Date}); |
1038
|
|
|
|
|
|
|
|
1039
|
|
|
|
|
|
|
$text = sprintf ("pub %4d/%s %4d/%02d/%02d %s\n", $self->{Bits}, $self->{Keyid}, |
1040
|
|
|
|
|
|
|
$year, ($month+0), ($day+0), |
1041
|
|
|
|
|
|
|
$self->_desc ($self->{Owner}->[0], $self->{Email}->[0])); |
1042
|
|
|
|
|
|
|
|
1043
|
|
|
|
|
|
|
|
1044
|
|
|
|
|
|
|
my $index = 1; |
1045
|
|
|
|
|
|
|
while ($self->{Owner}->[$index] || $self->{Email}->[$index]) |
1046
|
|
|
|
|
|
|
{ |
1047
|
|
|
|
|
|
|
$text .= sprintf ("%s%s\n", ' ' x 30, $self->_desc ($self->{Owner}->[$index], |
1048
|
|
|
|
|
|
|
$self->{Email}->[$index])); |
1049
|
|
|
|
|
|
|
if (exists $args{Verbose}) # produce a list of signatures |
1050
|
|
|
|
|
|
|
{ |
1051
|
|
|
|
|
|
|
|
1052
|
|
|
|
|
|
|
|
1053
|
|
|
|
|
|
|
}; |
1054
|
|
|
|
|
|
|
$index++; |
1055
|
|
|
|
|
|
|
}; |
1056
|
|
|
|
|
|
|
|
1057
|
|
|
|
|
|
|
$text; |
1058
|
|
|
|
|
|
|
} |
1059
|
|
|
|
|
|
|
|
1060
|
|
|
|
|
|
|
|
1061
|
|
|
|
|
|
|
|
1062
|
|
|
|
|
|
|
sub _keyparse |
1063
|
|
|
|
|
|
|
{ |
1064
|
|
|
|
|
|
|
my ($self, $keyline) = @_; |
1065
|
|
|
|
|
|
|
my ($bits, $keyid, $year, $mon, $day, $desc); |
1066
|
|
|
|
|
|
|
|
1067
|
|
|
|
|
|
|
($bits, $keyid, $year, $mon, $day, $desc) = |
1068
|
|
|
|
|
|
|
($keyline =~ /^pub\s+(\d+)\/(\w+)\s+(\d+)\/(\d+)\/(\d+)\s+(.+)$/); |
1069
|
|
|
|
|
|
|
|
1070
|
|
|
|
|
|
|
$date = &Time::Local::timegm (0, 0, 0, $day, $mon, $year-1900); |
1071
|
|
|
|
|
|
|
|
1072
|
|
|
|
|
|
|
return ($bits, $keyid, $date, $desc); |
1073
|
|
|
|
|
|
|
} |
1074
|
|
|
|
|
|
|
|
1075
|
|
|
|
|
|
|
|
1076
|
|
|
|
|
|
|
sub _date |
1077
|
|
|
|
|
|
|
{ |
1078
|
|
|
|
|
|
|
my $self = shift; |
1079
|
|
|
|
|
|
|
my (@tm) = gmtime (shift); |
1080
|
|
|
|
|
|
|
return ($tm[3], $tm[4], $tm[5]+1900); |
1081
|
|
|
|
|
|
|
} |
1082
|
|
|
|
|
|
|
|
1083
|
|
|
|
|
|
|
|
1084
|
|
|
|
|
|
|
sub _desc |
1085
|
|
|
|
|
|
|
{ |
1086
|
|
|
|
|
|
|
my ($self, $owner, $email) = @_; |
1087
|
|
|
|
|
|
|
|
1088
|
|
|
|
|
|
|
return ("$owner <$email>") if ($owner && $email); |
1089
|
|
|
|
|
|
|
return ("$owner") if (!$email); |
1090
|
|
|
|
|
|
|
return ("$email") if (!$owner); |
1091
|
|
|
|
|
|
|
return ("*** No ID on key ***"); |
1092
|
|
|
|
|
|
|
} |
1093
|
|
|
|
|
|
|
|
1094
|
|
|
|
|
|
|
|
1095
|
|
|
|
|
|
|
=head2 Known Bugs and Limitations |
1096
|
|
|
|
|
|
|
|
1097
|
|
|
|
|
|
|
=item + Hopefully none, proabably many! |
1098
|
|
|
|
|
|
|
|
1099
|
|
|
|
|
|
|
=head2 Author |
1100
|
|
|
|
|
|
|
|
1101
|
|
|
|
|
|
|
Gerard Hickey |
1102
|
|
|
|
|
|
|
RR 2 Box 409 |
1103
|
|
|
|
|
|
|
Lower Main St. |
1104
|
|
|
|
|
|
|
North Berwick, ME 03906 |
1105
|
|
|
|
|
|
|
hickey@ctron.com |
1106
|
|
|
|
|
|
|
|
1107
|
|
|
|
|
|
|
=head2 Copyrights |
1108
|
|
|
|
|
|
|
|
1109
|
|
|
|
|
|
|
Copyleft (l) 1996, by Gerard Hickey |
1110
|
|
|
|
|
|
|
|
1111
|
|
|
|
|
|
|
What this means is that this program may be copied freely given that |
1112
|
|
|
|
|
|
|
there is no payment in exchange for this program, and that all the |
1113
|
|
|
|
|
|
|
source is left intact with all comments and documentation. If you |
1114
|
|
|
|
|
|
|
wish to modify this program to correct bugs or to extend it's |
1115
|
|
|
|
|
|
|
usefullness, please coordinate such actions with the author. |
1116
|
|
|
|
|
|
|
|
1117
|
|
|
|
|
|
|
=cut |
1118
|
|
|
|
|
|
|
|