Whine about malformed input
[pgp-tools.git] / gpgsigs / gpgsigs
index 1033f400286bb5f35298e8a6e8eb66b6ce4b4c17..35d6d71f2c5348b7e9406faa713b1c0e1cf6667b 100755 (executable)
@@ -18,7 +18,7 @@
 #   * better charset conversion
 #   * pod documentation
 
-my $VERSION = '$Rev$';
+my $VERSION = qq$Rev$;
 
 use strict;
 use warnings;
@@ -32,7 +32,7 @@ sub version($)
        my ($fd) = @_;
 
        print $fd <<EOF;
-gpgsigs $VERSION - http://pgp-tools.alioth.debian.org/
+gpgsigs $VERSION- http://pgp-tools.alioth.debian.org/
   (c) 2004 Uli Martens <uli\@youam.net>
   (c) 2004, 2005 Peter Palfrader <peter\@palfrader.org>
   (c) 2004, 2005 Christoph Berg <cb\@df7cb.de>
@@ -59,9 +59,10 @@ EOF
 
 
 my ($fromcharset, $charset, $recv_keys);
+Getopt::Long::config('bundling');
 GetOptions(
-       f => \$fromcharset,
-       t => \$charset,
+       '-f=s' => \$fromcharset,
+       '-t=s' => \$charset,
        r => \$recv_keys,
        help => sub { usage(*STDOUT, 0); },
        version => sub { version(*STDOUT); exit 0;},
@@ -142,8 +143,8 @@ map { s/^0x//i; } @mykeys;
 if (!@mykeys || scalar @ARGV) {
        usage(*STDERR, 1);
 }
-if (!grep { /^([0-9A-F]{16,16}|[0-9A-F]{8,8})$/ } @mykeys) {
-       print STDERR "Invalid keyid given\n";
+foreach my $falsekey (grep { $_ !~ /^([0-9A-F]{16,16}|[0-9A-F]{8,8})$/ } @mykeys) {
+       print STDERR "Invalid keyid $falsekey given\n";
        usage(*STDERR, 1);
 }
 
@@ -182,9 +183,34 @@ while (<SIGS>) {
                $uid = myrecode($1);
                next;
        }
-       if ( m/^sig:(?:.*?:){3,3}([0-9A-F]{8})([0-9A-F]{8}):(?:.*?:){3,3}(.*):.*?:/ ) {
-               $sigs->{$key}->{$uid}->{$1.$2} = $3;
-               $sigs->{$key}->{$uid}->{$2} = $3;
+       if ( m/^sig:(?:.*?:){3,3}([0-9A-F]{8})([0-9A-F]{8}):(?:.*?:){5,5}(.*?):/ ) {
+               my $class = $3;
+               if ($class eq '10x') {
+                       $class = 'S';
+               } elsif ($class eq '11x') {
+                       $class = '1';
+               } elsif ($class eq '12x') {
+                       $class = '2';
+               } elsif ($class eq '13x') {
+                       $class = '3';
+               } else {
+                       $class = 's';
+               };
+               # Handle the case where one UID was signed multiple times
+               # with different signature classes.
+               my $before = $sigs->{$key}->{$uid}->{$1.$2};
+               if (defined $before) {
+                       if ($before eq 'S' || $before eq 's') {
+                               $sigs->{$key}->{$uid}->{$1.$2} = $class;
+                       } elsif ($class eq 'S' || $class eq 's') {
+                               # intentionall left blank
+                       } elsif ($before < $class) {
+                               $sigs->{$key}->{$uid}->{$1.$2} = $class;
+                       };
+               } else {
+                       $sigs->{$key}->{$uid}->{$1.$2} .= $class;
+               };
+               $sigs->{$key}->{$uid}->{$2} = $sigs->{$key}->{$uid}->{$1.$2};
                next;
        }
        if ( m/^uat:/ ) {
@@ -225,26 +251,30 @@ sub print_tag
        my ($key, $uid) = @_;
        if (! defined $sigs->{$key}->{$uid}) {
                warn "uid '$uid' not found on key $key\n";
-               return '(_)';
+               return '(' . (' ' x @mykeys) . ')';
        }
        my $r = '(';
        foreach my $mykey (@mykeys) {
-               $r .= defined $sigs->{$key}->{$uid}->{$mykey} ? "S" : " ";
+               $r .= defined $sigs->{$key}->{$uid}->{$mykey} ? $sigs->{$key}->{$uid}->{$mykey} : ' ';
        }
        $r .= ')';
        return $r;
 }
 
+$key = undef;
+$uid = undef;
+my $line = 0;
 print STDERR "Annotating $keytxt, writing into $outfile\n";
 open (TXT, $keytxt) or die ("Cannot open $keytxt\n");
 open (WRITE, '>'.$outfile) or die ("Cannot open $outfile for writing\n");
 while (<TXT>) {
+       $line++;
        $_ = myfromrecode($_);
        if (/^MD5 Checksum:/ && defined $MD5) {
-               s/_[_ ]+_/$MD5/;
+               s/[_[:xdigit:]][_ [:xdigit:]]+_/$MD5/;
        }
        if (/^SHA1 Checksum:/ && defined $SHA1) {
-               s/_[_ ]+_/$SHA1/;
+               s/[_[:xdigit:]][_ [:xdigit:]]+_/$SHA1/;
        }
        if ( m/^pub  +(?:\d+)[DR]\/([0-9A-F]{8}) [0-9]{4}-[0-9]{2}-[0-9]{2} *(.*)/ ) {
                $key = $1;
@@ -256,7 +286,10 @@ while (<TXT>) {
        }
        if ( m/^uid +(.*)$/ ) {
                $uid = $1;
-               die "key is undefined" unless defined $key;
+               unless (defined $key) {
+                       warn "key is undefined - input text is possibly malformed near line $line\n";
+                       next;
+               };
                die "uid is undefined, key $key" unless defined $uid;
                die "bad tag from $key | $uid" unless defined (print_tag($key, $uid));
                print WRITE print_tag($key, $uid) . " $_";