#!/usr/bin/perl # keyparty 1.2 (2009/10/16) # # Copyright (C) 2009 Patrick Bernier # All rights reserved # # This program is free software; you can redistribute it and/or modify it under # the same terms as Perl itself. # # Get the latest version at http://www.TZoNE.ORG/~pat/sw/ # # KNOWN BUGS: # - Won't deal with more than one picture UID per key # # TODO: # - Show key creation date, expiration date # - Commandline switch to provide the title # - Usage message # - Output currently sorted by keyring order. Re-sort? use strict; use warnings; use POSIX qw(strftime); use CGI qw(escapeHTML); ############################################################################### my $VERSION = '1.1'; my $TITLE = 'An unnamed keysigning event'; my $EMAIL = 'sink@TZoNE.ORG'; my $GPGPATH = 'gpg'; my $MAXPICSIZE = 65536; ############################################################################### # Self-call while getting pictures if (@ARGV == 3 && $ARGV[0] eq '--getpic') { getpic(); exit 0; } # Get keyspecs from commandline and STDIN my @keyspecs; unshift @keyspecs, unless (-t 0); unshift @keyspecs, @ARGV; chomp @keyspecs; # Feed keyspecs to gpg using xargs to split up invocations as needed if (open(XARGS, "-|") == 0) { if (open(STDIN, "-|") == 0) { print "@keyspecs" or die "feeding keyspecs: $!"; exit 0; } else { exec 'xargs', '-r', '--', $GPGPATH, '--batch', '--fixed-list-mode', '--with-colons', '--list-keys', '--with-fingerprint', '--with-fingerprint' # twice to get subkey fingerprints or die "exec xargs: $!"; } } # Close stdout to get rid of gpg output from --getpic calls open OUTPUT, ">&1" or die "cannot dup stdout: $!"; close STDOUT or die "closing stdout: $!"; # Parse the results my $keycount = 0; my $lasttype; my $key = undef; while () { chomp; my @v = split /:/; SWITCH: for ($v[0]) { /^pub$/ && do { if ($keycount++) { describe($key); } else { header(); } undef $key; $lasttype = 'pub'; $key->{'trust'} = $v[1]; $key->{'id'} = $v[4]; $key->{'len'} = $v[2]; $key->{'algo'} = $v[3]; $key->{'created'} = $v[5]; $key->{'expires'} = $v[6]; $key->{'uid'} = [ ]; $key->{'uat'} = [ ]; last SWITCH; }; /^sub$/ && do { $lasttype = 'sub'; last SWITCH; }; /^fpr$/ && do { $key->{'fp'} = $v[9] if ($lasttype eq 'pub'); last SWITCH; }; /^uid$/ && do { push @{$key->{'uid'}}, $v[9] unless ($v[1] =~ /^(i|d|r|e)$/); # invalid/disabled/revoked/expired last SWITCH; }; /^uat$/ && do { push @{$key->{'uat'}}, $v[9]; last SWITCH; }; } } describe($key); # describe the last key footer(); close XARGS or warn "close xargs: $!"; exit 0; # all done ############################################################################### sub describe { my $key = shift; # Get first picture ID if any if (@{$key->{'uat'}} > 0) { system $GPGPATH, '--batch', '--show-photos', '--photo-viewer', "$0 --getpic \%f \%t", '--list-keys', $key->{'fp'}; } # Format the fingerprints in the traditional fashion my $f_fp = $key->{'fp'}; if (length($f_fp) == 32) { $f_fp =~ s/(..)/$1 /g; $f_fp =~ s/\s$//; substr $f_fp, 23, 1, "
"; } elsif (length($f_fp) == 40) { $f_fp =~ s/(....)/$1 /g; $f_fp =~ s/\s$//; substr $f_fp, 24, 1, "
"; } print OUTPUT << "EOT"; $key->{'id'} $f_fp Fingerprint? EOT my $picfn = "$key->{'fp'}.jpeg"; my $firstuid = escapeHTML(shift @{$key->{'uid'}}); if (-f $picfn) { my $picsize = -s $picfn; my $rowspan = 2 + @{$key->{'uid'}}; print OUTPUT << "EOT"; photo uid < < < [image of size $picsize] Picture? $firstuid Name? Address? EOT } else { my $rowspan = 1 + @{$key->{'uid'}}; print OUTPUT << "EOT"; No picture $firstuid Name? Address? EOT } foreach my $uid (@{$key->{'uid'}}) { my $f_uid = escapeHTML($uid); print OUTPUT << "EOT"; $f_uid Name? Address? EOT } } ############################################################################### sub getpic { my $fp = $ARGV[1]; my $ext = $ARGV[2]; $ext =~ s/^jpg$/jpeg/; my $pic; (my $br = read STDIN, $pic, $MAXPICSIZE) or die "reading picture: $!"; if ($br >= $MAXPICSIZE) { print STDERR "Picture ID too big\n"; exit 1; } open PIC, ">$fp.$ext" or die "creating picture file $fp.$ext : $!"; print PIC $pic or die "writing picture file : $!"; close PIC or warn "closing pic: $!"; } ############################################################################### sub header { print OUTPUT << "EOT"; $TITLE

$TITLE

E-mail me to be added to this list.

EOT } ############################################################################### sub footer { my $now = strftime('%Y/%m/%d', localtime()); print OUTPUT << "EOT";
Generated on $now using keyparty $VERSION
EOT } __END__ ### keyparty ##################################################################