diff --git a/pgpverify b/pgpverify index 651d1d1..b361607 100755 --- a/pgpverify +++ b/pgpverify @@ -1,6 +1,12 @@ #! /usr/bin/perl -w # written April 1996, tale@uunet.uu.net (David C Lawrence) -# Version 1.3 +# Version 1.4 +# +# Changes from 1.3 -> 1.4 +# -- now handles wrapped headers that have been unfolded. +# (though I do believe news software oughtn't be unfolding them.) +# -- checks to ensure that the temporary file is really a file, and +# not a link or some other weirdness $pgp = '/usr/local/bin/pgp'; # if you keep your keyring somewhere that is not the default used by pgp, @@ -40,14 +46,23 @@ while (<>) { $pgpheader = "X-PGP-Sig"; exit 1 unless $_ = $header{$pgpheader}; # no signature -# this regexp might be too strict about the structure of pgp signature lines -$sep = "\n[ \t]+"; -$r64 = '[a-zA-Z0-9+/]'; -&fail("$0: $pgpheader not in expected format\n") - unless /^(\S+) (\S+)(($sep$r64{64})+$sep$r64+=?=?$sep=$r64{4})$/; +# the regexp below might be too strict about the structure of pgp sig lines -($version, $signed_headers, $signature) = ($1, $2, $3); -$signature =~ s/\n[ \t]+/\n/g; +# the $sep value means the separator between the radix64 signature lines +# can have any amount of spaces or tabs, but must have at least one space +# or tab, if there is a newline then the space or tab has to follow the +# newline. any number of newlines can appear as long as each is followed +# by at least one space or tab. *phew* +$sep = "[ \t]*(\n?[ \t]+)+"; + +# match all of the characters in a radix64 string +$r64 = '[a-zA-Z0-9+/]'; + +&fail("$0: $pgpheader not in expected format\n") + unless /^(\S+)$sep(\S+)(($sep$r64{64})+$sep$r64+=?=?$sep=$r64{4})$/; + +($version, $signed_headers, $signature) = ($1, $3, $4); +$signature =~ s/$sep/\n/g; $message = "-----BEGIN PGP SIGNED MESSAGE-----\n\n"; $message .= "X-Signed-Headers: $signed_headers\n"; @@ -71,6 +86,12 @@ $message .= $signature; $message .= "\n-----END PGP SIGNATURE-----\n"; open(TMP,"> $tmp") || &fail("$0: open > $tmp: $!\n"); + +-f TMP || + &fail("$0: $tmp not a plain file, possible security violation attempt\n"); +(stat(_))[3] == 1 || + &fail("$0: $tmp has hard links, possible security violation attempt\n"); + print TMP $message; close(TMP) || warn "$0: close > $tmp: $!\n"; &fail("$0: write error for message to check\n")