gpg-key2ps, keylookup: make them less dependent on specific
[pgp-tools.git] / gpg-key2ps / gpg-key2ps
1 #!/usr/bin/perl -w
2 #
3 # gpg-key2ps: convert a PGP/GnuPG key into paper slips.
4 # Copyright (C) 2001-2005 Simon Richter
5 # Copyright (C) 2005-2006 Thijs Kinkhorst
6 # Copyright (C) 2005 Christoph Berg <cb@df7cb.de>
7 # Licenced under the GNU General Public License,
8 # version 2 or later.
9 #
10 # $Id$
11
12 use strict;
13 use Getopt::Long;
14
15 my $version = '$Rev$';
16 $version =~ s/\$Rev:\s*(\d+)\s*\$/$1/;
17 my $revokestyle = "hide";
18 my $creationdate = scalar(localtime);
19
20 sub version($) {
21 my $fd = shift;
22 print $fd "gpg-key2ps $version - (c) 2001-2005 Simon Richter, Thijs Kinkhorst, Christoph Berg\n";
23 }
24
25 sub usage($$) {
26 my ($fd, $exitcode) = @_;
27 version ($fd);
28 print $fd <<EOF;
29 Usage: $0 [-p papersize] [-r revoked-style] keyid-or-name ...
30 Options:
31 -p --paper-size
32 -r --revoked-style
33 hide - Don't show revoked uids (default)
34 grey - Print text in grey
35 note - Add "[revoked]"
36 show - List revoked uids normally
37 strike - Strike through lines
38 -h --help
39 -v --version
40 EOF
41 exit $exitcode;
42 }
43
44 # fetch command line parameters
45 my $opts;
46 Getopt::Long::config('bundling');
47 if (!GetOptions (
48 '-h' => \$opts->{help},
49 '--help' => \$opts->{help},
50 '-v' => \$opts->{version},
51 '--version' => \$opts->{version},
52 '-p=s' => \$opts->{papersize},
53 '--paper-size=s' => \$opts->{papersize},
54 '-r=s' => \$opts->{revokestyle},
55 '--revoked-style=s' => \$opts->{revokestyle},
56 )) {
57 usage(\*STDERR, 1);
58 }
59
60 if ($opts->{help}) {
61 usage (\*STDOUT, 0);
62 }
63
64 if ($opts->{version}) {
65 version (\*STDOUT);
66 exit 0;
67 }
68
69 if ( $opts->{revokestyle} ) { $revokestyle = $opts->{revokestyle}; }
70 if ( $opts->{papersize} ) { $ENV{'PAPERSIZE'} = $opts->{papersize}; }
71
72 if ( $revokestyle !~ /^(grey|hide|note|show|strike)$/ ) {
73 print STDERR "Unknown revoked-style \"$revokestyle\".\n";
74 usage (\*STDERR, 1);
75 }
76
77 usage(\*STDERR, 1) unless scalar @ARGV >= 1;
78
79 # determine the paper size through the paperconf tool
80 my $w; my $h;
81 if ( `which paperconf` && $? == 0 ) {
82 $w=`paperconf -w`;
83 $h=`paperconf -h`;
84 chomp($w);
85 chomp($h);
86 } else {
87 # Default to A4.
88 print STDERR "Warning: libpaper-utils is not installed, defaulting to A4.\n";
89 $w=596;
90 $h=842;
91 }
92
93 # open a gpg process we'll be reading from below
94 map { s/'/'\\''/g; } @ARGV; # quote single quotes
95 open(GPG, "gpg --fingerprint --with-colons '". (join "' '", @ARGV) ."' |");
96
97 sub start_postscript {
98 # start the PostScript output
99 print <<EOF;
100 %!PS-Adobe-3.0
101 %%BoundingBox: 0 0 $w $h
102 %%Title:
103 %%Creator: gpg-key2ps $version
104 %%CreationDate: $creationdate
105 %%Pages: 1
106 %%EndComments
107
108 %%Page: 1 1
109
110 /w $w def
111 /h $h def
112
113 /Times-Roman findfont 9 scalefont setfont
114
115 /newline {
116 /y y 10 sub def
117 } def
118
119 /hline {
120 30 y 3 add moveto
121 w 2 div 30 sub y 3 add lineto stroke
122 newline
123 } def
124
125 /needhline {
126 /condhline { hline } def
127 } def
128
129 /noneedhline {
130 /condhline { } def
131 } def
132
133 /showAlgorithm {
134 << 1 (R) 2 (r) 3 (s) 16 (g) 20 (G) 17 (D) >> exch get
135 show
136 } def
137
138 /pub {
139 condhline
140 50 y moveto (pub) show
141 70 y moveto show showAlgorithm (/) show show
142 150 y moveto show
143 200 y moveto show
144 newline
145 needhline
146 } def
147
148 /fpr {
149 70 y moveto (Key fingerprint = ) show show
150 newline
151 } def
152
153 /uid {
154 50 y moveto (uid) show
155 200 y moveto show
156 newline
157 } def
158
159 EOF
160
161 # output the desired display for revoked uids
162 if ( $revokestyle eq "grey" ) {
163 print "/revuid {\n";
164 print " .5 setgray\n";
165 print " uid\n";
166 print " 0 setgray\n";
167 print "} def\n";
168 } elsif ( $revokestyle eq "note" ) {
169 print "/revuid {\n";
170 print " 50 y moveto (uid) show\n";
171 print " 200 y moveto show ( [revoked]) show\n";
172 print " newline\n";
173 print "} def\n";
174 } elsif ( $revokestyle eq "show" ) {
175 print "/revuid { uid } def\n";
176 } elsif ( $revokestyle eq "strike" ) {
177 print "/revuid {\n";
178 print " uid\n";
179 print " 45 y 9 add moveto h 2 div 45 sub y 18 add lineto stroke\n";
180 print "} def\n";
181 }
182
183 print <<EOF;
184
185 /sbk {
186 50 y moveto (sub) show
187 70 y moveto show showAlgorithm (/) show show
188 150 y moveto show
189 newline
190 } def
191
192 /key {
193 noneedhline
194 EOF
195 } # sub start_postscript
196
197 # walk the output of gpg line by line
198 # $numlines has the total number of lines so we'll know how many to put on page
199 my $numlines = 0;
200 my $started = 0;
201 while(<GPG>) {
202 # we don't use these
203 if ( /^(tru|uat):/ ) { next; }
204 # every primary uid causes an extra line because of the separator
205 if ( /^pub:/ ) {
206 start_postscript() unless $started;
207 $started = 1;
208 $numlines++;
209 }
210 # primary uid
211 s/^pub:[^:]*:([^:]*):([0-9]*):.{8,8}(.{8,8}):([^:]*):[^:]*:[^:]*:[^:]*:([^:]*):[^:]*:[^:]*:.*/ ($5) ($4) ($3) $2 ($1) pub/;
212 # fingerprint, format it nicely with spaces
213 if ( /^fpr:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:([^:]*):.*/ ) {
214 my $fpr = $1;
215 # v4 key
216 $fpr =~ s/(\w{4})(\w{4})(\w{4})(\w{4})(\w{4})(\w{4})(\w{4})(\w{4})(\w{4})(\w{4})/$1 $2 $3 $4 $5 $6 $7 $8 $9 $10/;
217 # v3 key
218 $fpr =~ s/(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})/$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16/g;
219 $_ = " ($fpr) fpr\n";
220 }
221 # user ids
222 s/^uid:[^:r]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:([^:]*):.*/ ($1) uid/;
223 # revoked user id
224 if (s/^uid:r[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:([^:]*):.*/ ($1) revuid/) {
225 next if $revokestyle eq "hide";
226 }
227 # subkey
228 s/^sub:[^:]*:([^:]*):([0-9]*):.{8,8}(.{8,8}):([^:]*):[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:.*/ ($4) ($3) $2 ($1) sbk/;
229 $numlines++;
230 # print this line
231 print;
232 }
233 close(GPG);
234
235 unless ($started) {
236 print STDERR "No public key found.\n";
237 exit 1;
238 }
239
240 # output the remaining postscript
241 print <<EOF;
242 } def
243
244 /numlines $numlines def
245 /num w 16 sub 10 div numlines div def
246
247 /column {
248 /y w 20 sub def
249 1 1 num {
250 gsave
251 0 0 h 2 div w rectclip
252 /upper y 11 add def
253 key
254 newline
255 /lower y 11 add def
256 0 upper h 2 div upper h 2 div lower 0 lower 0 upper moveto lineto lineto lineto lineto stroke
257 grestore
258 } for
259 } def
260
261 w 0 translate
262 90 rotate
263 column
264 h 2 div 0 translate
265 column
266
267 showpage
268
269 %%Trailer
270 %%EOF
271 EOF
272
273 # done!
274 exit 0;
275
276
277 __END__
278
279 =head1 NAME
280
281 B<gpg-key2ps> - generates a PS file from a GnuPG keyring
282
283 =head1 SYNOPSIS
284
285 B<gpg-key2ps> [B<-r> I<revoked-style>] [B<-p> I<papersize>] I<keyid-or-name> [ I<...> ]
286
287 =head1 DESCRIPTION
288
289 gpg-key2ps generates a PostScript file with your OpenPGP key fingerprint (repeated
290 as often as it fits) useful for keysigning parties. The only argument is the same
291 as you would pass to GPG's list-keys command, either a key-id or a (partial) name.
292 The PS data is written to stdout.
293
294 =head1 OPTIONS
295
296 =over
297
298 =item B<-p> B<--paper-size> I<paper-size>
299
300 Select the output paper size. Default is to look into /etc/papersize or A4 if
301 libpaper isn't installed.
302
303 =item B<-r> B<--revoked-style> I<revoked-style>
304
305 Select how to mark revoked UIDs. Five styles are available:
306 B<hide> don't show at all (default),
307 B<show> show normally,
308 B<grey> display in 50% grey,
309 B<note> add "[revoked]", and
310 B<strike> strike through.
311
312 =item I<keyid>
313
314 Keyids to print. Multiple can be separated by spaces.
315
316 =item B<-h> B<--help>
317
318 Print usage and exit.
319
320 =item B<-v> B<--version>
321
322 Print version and exit.
323
324 =back
325
326
327 =head1 SEE ALSO
328
329 gpg(1)
330
331 http://pgp-tools.alioth.debian.org/
332
333 =head1 AUTHORS AND COPYRIGHT
334
335 (c) 2001 - 2005 Simon Richter <sjr@debian.org>
336
337 (c) 2005 Thijs Kinkhorst <thijs@kinkhorst.com>
338
339 (c) 2005 Christoph Berg <cb@df7cb.de>
340