]>
git.sthu.org Git - pgp-tools.git/blob - gpgsigs/gpgsigs
3 # See the pod documentation at the end of this file for author,
4 # copyright, and licence information.
7 # libintl-perl (Locale::Recode)
8 # OR libtext-iconv-perl (Text::Iconv),
9 # OR the "recode" binary
14 # * use the user's normal keyring to find signatures
15 # * support for multiple user keys
16 # * better charset conversion
31 gpgsigs $VERSION - http://pgp-tools.alioth.debian.org/
32 (c) 2004 Uli Martens <uli\@youam.net>
33 (c) 2004 Peter Palfrader <peter\@palfrader.org>
34 (c) 2004, 2005 Christoph Berg <cb\@df7cb.de>
43 Usage: $PROGRAM_NAME [-r] [-t <charset>] <keyid> <keytxt> [<outfile>]
45 keyid is a long or short keyid (e.g. DE7AAF6E94C09C7F or 94C09C7F)
46 separate multiple keyids with ','
47 -r call gpg --recv-keys before proceeding
48 -f <charset> convert <keytxt> from charset
49 -t <charset> convert UIDs to charset in output
55 my ($fromcharset, $charset, $recv_keys);
60 help
=> sub { usage
(0); },
61 version
=> sub { version
(); exit 0;},
66 $fromcharset ||= "ISO-8859-1";
67 $charset ||= $ENV{LC_ALL
} || $ENV{LC_CTYPE
} || $ENV{LANG
} || "ISO-8859-1";
68 $charset = "ISO-8859-1" unless $charset =~ /[\.-]/;
72 my ($rf, $rt, $if, $it);
73 if (eval "require Locale::Recode") {
74 $rf = Locale
::Recode
->new (from
=> $fromcharset, to
=> $charset) if $fromcharset;
75 $rt = Locale
::Recode
->new (from
=> 'UTF-8', to
=> $charset);
76 } elsif (eval "require Text::Iconv") {
77 $if = Text
::Iconv
->new($fromcharset, $charset) if $fromcharset;
78 $it = Text
::Iconv
->new("UTF-8", $charset);
87 } elsif (defined $if) {
88 return $if->convert($text);
90 my $pid = open3
(\
*WTRFH
, \
*RDRFH
, \
*ERRFH
, 'recode', "$fromcharset..$charset");
98 die ("'recode' failed, is it installed?\n") unless defined $result;
109 } elsif (defined $it) {
110 my $result = $it->convert($text);
111 warn ("Could not convert '$text'\n") unless defined $result;
112 return (defined $result) ?
$result : $text
114 my $pid = open3
(\
*WTRFH
, \
*RDRFH
, \
*ERRFH
, 'recode', "utf8..$charset");
118 my $result = <RDRFH
>;
122 warn ("'recode' failed, is it installed?\n") unless defined $result;
123 return (defined $result) ?
$result : $text
129 my $mykey = uc(shift @ARGV);
130 my $keytxt = (shift @ARGV) || usage
(1);
131 my $outfile = (shift @ARGV) || '-';
133 my @mykeys = split /,/, $mykey;
134 map { s/^0x//i; } @mykeys;
136 if (!@mykeys || scalar @ARGV) {
139 if (!grep { /^([0-9A-F]{16,16}|[0-9A-F]{8,8})$/ } @mykeys) {
140 print STDERR
"Invalid keyid given\n";
144 -r
$keytxt or die ("$keytxt does not exist\n");
147 # get list of keys in file
149 open (TXT
, $keytxt) or die ("Cannot open $keytxt\n");
151 if ( m/^pub +(?:\d+)[DR]\/([0-9A
-F
]{8}) [0-9]{4}-[0-9]{2}-[0-9]{2} *(.*)/ ) {
158 # get all known signatures
160 print STDERR
"Requesting keys from keyserver\n";
161 system "gpg --recv-keys @keys";
164 print STDERR
"Running --list-sigs, this will take a while ";
165 open SIGS
, "gpg --fixed-list-mode --with-colons --list-sigs @keys 2>/dev/null |"
166 or die "can't get gpg listing";
168 my ($key, $uid, $sigs);
170 if ( m/^pub:(?:.*?:){3,3}([0-9A-F]{16,16}):/ ) {
175 if ( m/^uid:(?:.*?:){8,8}(.*):/s ) {
179 if ( m/^sig:(?:.*?:){3,3}([0-9A-F]{8})([0-9A-F]{8}):(?:.*?:){3,3}(.*):.*?:/ ) {
180 $sigs->{$key}->{$uid}->{$1.$2} = $3;
181 $sigs->{$key}->{$uid}->{$2} = $3;
188 next if ( m/^(rev|sub|tru):/ );
189 warn "unknown value: '$_', key: ".(defined $key ?
$key :'none')."\n";
194 for my $k ( keys %{$sigs} ) {
195 if ( $k =~ m/^[0-9A-F]{8}([0-9A-F]{8})$/ ) {
196 $sigs->{$1} = $sigs->{$k};
202 open MD
, "gpg --print-md md5 $keytxt|" or warn "can't get gpg md5\n";
205 open MD
, "gpg --print-md sha1 $keytxt|" or warn "can't get gpg sha1\n";
211 my $metatxt = quotemeta($keytxt);
212 $MD5 =~ s/^$metatxt:\s*//;
213 $SHA1 =~ s/^$metatxt:\s*//;
219 my ($key, $uid) = @_;
220 if (! defined $sigs->{$key}->{$uid}) {
221 warn "uid '$uid' not found on key $key\n";
225 foreach my $mykey (@mykeys) {
226 $r .= defined $sigs->{$key}->{$uid}->{$mykey} ?
"S" : " ";
232 print STDERR
"Annotating $keytxt, writing into $outfile\n";
233 open (TXT
, $keytxt) or die ("Cannot open $keytxt\n");
234 open (WRITE
, '>'.$outfile) or die ("Cannot open $outfile for writing\n");
236 $_ = myfromrecode
($_);
237 if (/^MD5 Checksum:/ && defined $MD5) {
240 if (/^SHA1 Checksum:/ && defined $SHA1) {
243 if ( m/^pub +(?:\d+)[DR]\/([0-9A
-F
]{8}) [0-9]{4}-[0-9]{2}-[0-9]{2} *(.*)/ ) {
246 #if ($uid) { # in gpg 1.2, the first uid is here
247 # print WRITE print_tag($key, $uid) . " $_";
251 if ( m/^uid +(.*)$/ ) {
253 die "key is undefined" unless defined $key;
254 die "uid is undefined, key $key" unless defined $uid;
255 die "bad tag from $key | $uid" unless defined (print_tag
($key, $uid));
256 print WRITE print_tag
($key, $uid) . " $_";
262 print WRITE
"Legend:\n";
263 foreach my $i (0 .. @mykeys - 1) {
264 print WRITE
'('. ' 'x
$i . 'S' . ' 'x
(@mykeys-$i-1) . ") signed with $mykeys[$i]\n";
272 B<gpgsigs> - annotate list of GnuPG keys with already done signatures
276 B<gpgsigs> [-r] [-f I<charset>] [-t I<charset>] I<keyid> F<keytxt> [F<outfile>]
280 B<gpgsigs> was written to assist the user in signing keys during a keysigning
281 party. It takes as input a file containing keys in C<gpg --list-keys> format
282 and prepends every line with a tag indicating if the user has already signed
283 that uid. When the file contains C<MD5 Checksum:> or C<SHA1 Checksum:> lines
284 and placeholders (C<__ __>), the checksum is inserted.
292 Call I<gpg --recv-keys> before creating the output.
296 Convert F<keytxt> from I<charset>. The default is ISO-8859-1.
300 Convert UIDs to I<charset>. The default is derived from LC_ALL, LC_CTYPE, and
301 LANG, and if all these are unset, the default is ISO-8859-1.
305 Use this keyid (8 or 16 byte) for annotation. Multiple keyids can be separated
310 Read input from F<keytxt>.
314 Write output to F<outfile>. Default is stdout.
320 The following key signing parties are using B<gpgsigs>:
322 http://www.palfrader.org/ksp-lt2k4.html
324 http://www.palfrader.org/ksp-lt2k5.html
328 B<GnuPG> is known to change its output format quite often. This version has
329 been tested with gpg 1.2.5 and gpg 1.4.1. YMMV.
335 http://pgp-tools.alioth.debian.org/
337 =head1 AUTHORS AND COPYRIGHT
339 (c) 2004 Uli Martens <uli@youam.net>
341 (c) 2004 Peter Palfrader <peter@palfrader.org>
343 (c) 2004, 2005 Christoph Berg <cb@df7cb.de>
349 Redistribution and use in source and binary forms, with or without
350 modification, are permitted provided that the following conditions
353 1. Redistributions of source code must retain the above copyright
354 notice, this list of conditions and the following disclaimer.
356 2. Redistributions in binary form must reproduce the above copyright
357 notice, this list of conditions and the following disclaimer in the
358 documentation and/or other materials provided with the distribution.
360 3. The name of the author may not be used to endorse or promote products
361 derived from this software without specific prior written permission.
363 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
364 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
365 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
366 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
367 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
368 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
369 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
370 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
371 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
372 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.