chiark / gitweb /
REORG Delete everything that's not innduct or build system or changed for innduct
[inn-innduct.git] / control / pgpverify.in
diff --git a/control/pgpverify.in b/control/pgpverify.in
deleted file mode 100644 (file)
index feee446..0000000
+++ /dev/null
@@ -1,876 +0,0 @@
-#! /usr/bin/perl -w
-# do '@LIBDIR@/innshellvars.pl';
-# If running inside INN, uncomment the above and point to innshellvars.pl.
-#
-# Written April 1996, <tale@isc.org> (David C Lawrence)
-# Currently maintained by Russ Allbery <rra@stanford.edu>
-# Version 1.27, 2005-07-02
-#
-# NOTICE TO INN MAINTAINERS:  The version that is shipped with INN is the
-# same as the version that I make available to the rest of the world
-# (including non-INN sites), so please make all changes through me.
-#
-# This program requires Perl 5, probably at least about Perl 5.003 since
-# that's when FileHandle was introduced.  If you want to use this program
-# and your Perl is too old, please contact me (rra@stanford.edu) and tell
-# me about it; I want to know what old versions of Perl are still used in
-# practice.
-#
-# Changes from 1.26 -> 1.27
-# -- Default to pubring.gpg when trustedkeys.gpg is not found in the
-#    default key location, for backward compatibility.
-#
-# Changes from 1.25 -> 1.26
-# -- Return the correct status code when the message isn't verified
-#    instead of always returning 255.
-#
-# Changes from 1.24 -> 1.25
-# -- Fix the -test switch to actually do something.
-# -- Improve date generation when logging to standard output.
-#
-# Changes from 1.23 -> 1.24
-# -- Fix bug in the recognition of wire-format articles.
-#
-# Changes from 1.15 -> 1.23
-# -- Bump version number to match CVS revision number.
-# -- Replaced all signature verification code with code that uses detached
-#    signatures.  Signatures generated by GnuPG couldn't be verified using
-#    attached signatures without adding a Hash: header, and this was the
-#    path of least resistance plus avoids munging problems in the future.
-#    Code taken from PGP::Sign.
-#
-# Changes from 1.14 -> 1.15
-# -- Added POD documentation.
-# -- Fixed the -test switch so that it works again.
-# -- Dropped Perl 4 compatibility and reformatted.  Now passes use strict.
-#
-# Changes from 1.13.1 -> 1.14
-# -- Native support for GnuPG without the pgpgpg wrapper, using GnuPG's
-#    program interface by Marco d'Itri.
-# -- Always use Sys::Syslog without any setlogsock call for Perl 5.6.0 or
-#    later, since Sys::Syslog in those versions of Perl uses the C library
-#    interface and is now portable.
-# -- Default to expecting the key ring in $inn'newsetc/pgp if it exists.
-# -- Fix a portability problem for Perl 4 introduced in 1.12.
-#
-# Changes from 1.13 -> 1.13.1
-# -- Nothing functional, just moved the innshellvars.pl line to the head of
-#    the script, to accomodate the build process of INN.
-#
-# Changes from 1.12 -> 1.13
-# -- Use INN's syslog_facility if available.
-#
-# Changes from 1.11 -> 1.12
-# -- Support for GnuPG.
-# -- Use /usr/ucb/logger, if present, instead of /usr/bin/logger (the latter
-#    of which, on Solaris at least, is some sort of brain damaged POSIX.2
-#    command which doesn't use syslog).
-# -- Made syslog work for dec_osf (version 4, at least).
-# -- Fixed up priority of '.' operator vs bitwise operators.
-#
-# Changes from 1.10 -> 1.11
-# -- Code to log error messages to syslog.
-#    See $syslog and $syslog_method configurable variables.
-# -- Configurably allow date stamp on stderr error messages.
-# -- Added locking for multiple concurrent pgp instances.
-# -- More clear error message if pgp exits abnormally.
-# -- Identify PGP 5 "BAD signature" string.
-# -- Minor diddling for INN (path to innshellvars.pl changed).
-#
-# Changes from 1.9 -> 1.10
-# -- Minor diddling for INN 2.0:  use $inn'pathtmp if it exists, and
-#    work with the new subst method to find innshellvars.pl.
-# -- Do not truncate the tmp file when opening, in case it is really
-#    linked to another file.
-#
-# Changes from 1.8 -> 1.9
-# -- Match 'Bad signature' pgp output to return exit status 3 by removing
-#    '^' in regexp matched on multiline string.
-#
-# Changes from 1.7 -> 1.8
-# -- Ignore final dot-CRLF if article is in NNTP format.
-#
-# Changes from 1.6 -> 1.7
-# -- Parse PGP 5.0 'good signature' lines.
-# -- Allow -test switch; prints pgp input and output.
-# -- Look for pgp in INN's innshellvars.pl.
-# -- Changed regexp delimiters for stripping $0 to be compatible with old
-#    Perl.
-#
-# Changes from 1.5 -> 1.6
-# -- Handle articles encoded in NNTP format ('.' starting line is doubled,
-#    \r\n at line end) by stripping NNTP encoding.
-# -- Exit 255 with pointer to $HOME or $PGPPATH if pgp can't find key
-#    ring.  (It probably doesn't match the necessary error message with
-#    ViaCrypt PGP.)
-# -- Failures also report Message-ID so the article can be looked up to
-#    retry.
-#
-# Changes from 1.4 -> 1.5
-# -- Force English language for 'Good signature from user' by passing
-#    +language=en on pgp command line, rather than setting the
-#    environment variable LANGUAGE to 'en'.
-#
-# 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.
-
-# Path to the GnuPG gpgv binary, if you have GnuPG.  If you do, this will
-# be used in preference to PGP.  For most current control messages, you
-# need a version of GnuPG that can handle RSA signatures.  If you have INN
-# and the script is able to successfully include your innshellvars.pl
-# file, the value of $inn::gpgv will override this.
-# $gpgv = '/usr/local/bin/gpgv';
-
-# Path to pgp binary; for PGP 5.0, set the path to the pgpv binary.  If
-# you have INN and the script is able to successfully include your
-# innshellvars.pl file, the value of $inn::pgp will override this.
-$pgp = '/usr/local/bin/pgp';
-
-# If you keep your keyring somewhere that is not the default used by pgp,
-# uncomment the next line and set appropriately.  If you have INN and the
-# script is able to successfully include your innshellvars.pl file, this
-# will be set to $inn::newsetc/pgp if that directory exists unless you set
-# it explicitly.  GnuPG will use a file named pubring.gpg in this
-# directory.
-# $keyring = '/path/to/your/pgp/config';
-
-# If you have INN and the script is able to successfully include your
-# innshellvars.pl file, the value of $inn::pathtmp and $inn::locks will
-# override these.
-$tmpdir = "/tmp";
-$lockdir = $tmpdir;
-
-# How should syslog be accessed?
-#
-# As it turns out, syslogging is very hard to do portably in versions of
-# Perl prior to 5.6.0.  Sys::Syslog should work without difficulty in
-# 5.6.0 or later and will be used automatically for those versions of Perl
-# (unless $syslog_method is '').  For earlier versions of Perl, 'inet' is
-# all that's available up to version 5.004_03.  If your syslog does not
-# accept UDP log packets, such as when syslogd runs with the -l flag,
-# 'inet' will not work.  A value of 'unix' will try to contact syslogd
-# directly over a Unix domain socket built entirely in Perl code (no
-# subprocesses).  If that is not working for you, and you have the
-# 'logger' program on your system, set this variable to its full path name
-# to have a subprocess contact syslogd.  If the method is just "logger",
-# the script will search some known directories for that program.  If it
-# can't be found & used, everything falls back on stderr logging.
-#
-# You can test the script's syslogging by running "pgpverify <
-# /some/text/file" on a file that is not a valid news article.  The
-# "non-header at line #" error should be syslogged.
-#
-# $syslog_method = 'unix';    # Unix doman socket, Perl 5.004_03 or higher.
-# $syslog_method = 'inet';    # UDP to port 514 of localhost.
-# $syslog_method = '';        # Don't ever try to do syslogging.
-$syslog_method = 'logger';    # Search for the logger program.
-
-# The next two variables are the values to be used for syslog's facility
-# and level to use, as would be found in syslog.conf.  For various
-# reasons, it is impossible to economically have the script figure out how
-# to do syslogging correctly on the machine.  If you have INN and the
-# script is able to successfully include you innshellvars.pl file, then
-# the value of $inn::syslog_facility will override this value of
-# $syslog_facility; $syslog_level is unaffected.
-$syslog_facility = 'news';
-$syslog_level = 'err';
-
-# Prepend the error message with a timestamp?  This is only relevant if
-# not syslogging, when errors go to stderr.
-#
-# $log_date = 0;  # Zero means don't do it.
-# $log_date = 1;  # Non-zero means do it.
-$log_date = -t STDOUT; # Do it if STDOUT is to a terminal.
-
-# End of configuration section.
-
-
-require 5;
-
-use strict;
-use vars qw($gpgv $pgp $keyring $tmp $tmpdir $lockdir $syslog_method
-            $syslog_facility $syslog_level $log_date $test $messageid);
-
-use Fcntl qw(O_WRONLY O_CREAT O_EXCL);
-use FileHandle;
-use IPC::Open3 qw(open3);
-use POSIX qw(strftime);
-
-# Turn on test mode if the first argument is '-test'.
-if (@ARGV && $ARGV[0] eq '-test') {
-  shift @ARGV;
-  $test = 1;
-}
-
-# Not syslogged, such an error is almost certainly from someone running
-# the script manually.
-die "Usage: $0 < message\n" if @ARGV != 0;
-
-# Grab various defaults from innshellvars.pl if running inside INN.
-$pgp = $inn::pgp
-    if $inn::pgp && $inn::pgp ne "no-pgp-found-during-configure";
-$gpgv = $inn::gpgv if $inn::gpgv;
-$tmp = ($inn::pathtmp ? $inn::pathtmp : $tmpdir) . "/pgp$$";
-$lockdir = $inn::locks if $inn::locks;
-$syslog_facility = $inn::syslog_facility if $inn::syslog_facility;
-if (! $keyring && $inn::newsetc) {
-  $keyring = $inn::newsetc . '/pgp' if -d $inn::newsetc . '/pgp';
-}
-
-# Trim /path/to/prog to prog for error messages.
-$0 =~ s%^.*/%%;
-
-# Make sure that the signature verification program can be executed.
-if ($gpgv) {
-  if (! -x $gpgv) {
-    &fail("$0: $gpgv: " . (-e _ ? "cannot execute" : "no such file") . "\n");
-  }
-} elsif (! -x $pgp) {
-  &fail("$0: $pgp: " . (-e _ ? "cannot execute" : "no such file") . "\n");
-}
-
-# Parse the article headers and generate the PGP message.
-my ($nntp_format, $header, $dup) = &parse_header();
-exit 1 unless $$header{'X-PGP-Sig'};
-my ($message, $signature, $version)
-    = &generate_message($nntp_format, $header, $dup);
-if ($test) {
-  print "-----MESSAGE-----\n$message\n-----END MESSAGE-----\n\n";
-  print "-----SIGNATURE-----\n$signature\n-----SIGNATURE-----\n\n";
-}
-
-# The call to pgp needs to be locked because it tries to both read and
-# write a file named randseed.bin but doesn't do its own locking as it
-# should, and the consequences of a multiprocess conflict is failure to
-# verify.
-my $lock;
-unless ($gpgv) {
-  $lock = "$lockdir/LOCK.$0";
-  until (&shlock($lock) > 0) {
-    sleep(2);
-  }
-}
-
-# Verify the message.
-my ($ok, $signer) = pgp_verify($signature, $version, $message);
-unless ($gpgv) {
-  unlink ($lock) or &errmsg("$0: unlink $lock: $!\n");
-}
-print "$signer\n" if $signer;
-unless ($ok == 0) {
-  &errmsg("$0: verification failed\n");
-}
-exit $ok;
-
-
-# Parse the article headers and return a flag saying whether the message
-# is in NNTP format and then two references to hashes.  The first hash
-# contains all the header/value pairs, and the second contains entries for
-# every header that's duplicated.  This is, by design, case-sensitive with
-# regards to the headers it checks.  It's also insistent about the
-# colon-space rule.
-sub parse_header {
-  my (%header, %dup, $label, $value, $nntp_format);
-  while (<>) {
-    # If the first header line ends with \r\n, this article is in the
-    # encoding it would be in during an NNTP session.  Some article
-    # storage managers keep them this way for efficiency.
-    $nntp_format = /\r\n$/ if $. == 1;
-    s/\r?\n$//;
-
-    last if /^$/;
-    if (/^(\S+):[ \t](.+)/) {
-      ($label, $value) = ($1, $2);
-      $dup{$label} = 1 if $header{$label};
-      $header{$label} = $value;
-    } elsif (/^\s/) {
-      &fail("$0: non-header at line $.: $_\n") unless $label;
-      $header{$label} .= "\n$_";
-    } else {
-      &fail("$0: non-header at line $.: $_\n");
-    }
-  }
-  $messageid = $header{'Message-ID'};
-  return ($nntp_format, \%header, \%dup);
-}
-
-# Generate the PGP message to verify.  Takes a flag indicating wire
-# format, the hash of headers and header duplicates returned by
-# parse_header and returns a list of three elements.  The first is the
-# message to verify, the second is the signature, and the third is the
-# version number.
-sub generate_message {
-  my ($nntp_format, $header, $dup) = @_;
-
-  # The regexp below might be too strict about the structure of PGP
-  # signature lines.
-
-  # 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*
-  my $sep = "[ \t]*(\n?[ \t]+)+";
-
-  # Match all of the characters in a radix64 string.
-  my $r64 = '[a-zA-Z0-9+/]';
-
-  local $_ = $$header{'X-PGP-Sig'};
-  &fail("$0: X-PGP-Sig not in expected format\n")
-    unless /^(\S+)$sep(\S+)(($sep$r64{64})+$sep$r64+=?=?$sep=$r64{4})$/;
-
-  my ($version, $signed_headers, $signature) = ($1, $3, $4);
-  $signature =~ s/$sep/\n/g;
-  $signature =~ s/^\s+//;
-
-  my $message = "X-Signed-Headers: $signed_headers\n";
-  my $label;
-  foreach $label (split(",", $signed_headers)) {
-    &fail("$0: duplicate signed $label header, can't verify\n")
-      if $$dup{$label};
-    $message .= "$label: ";
-    $message .= "$$header{$label}" if $$header{$label};
-    $message .= "\n";
-  }
-  $message .= "\n";             # end of headers
-
-  while (<>) {                  # read body lines
-    if ($nntp_format) {
-      # Check for end of article; some news servers (eg, Highwind's
-      # "Breeze") include the dot-CRLF of the NNTP protocol in the article
-      # data passed to this script.
-      last if $_ eq ".\r\n";
-
-      # Remove NNTP encoding.
-      s/^\.\./\./;
-      s/\r\n$/\n/;
-    }
-    $message .= $_;
-  }
-
-  # Strip off all trailing whitespaces for compatibility with the way that
-  # pgpverify used to work, using attached signatures.
-  $message =~ s/[ \t]+\n/\n/g;
-
-  return ($message, $signature, $version);
-}
-
-# Check a detached signature for given data.  Takes a signature block (in
-# the form of an ASCII-armored string with embedded newlines), a version
-# number (which may be undef), and the message.  We return an exit status
-# and the key id if the signature is verified.  0 means good signature, 1
-# means bad data, 2 means an unknown signer, and 3 means a bad signature.
-# In the event of an error, we report with errmsg.
-#
-# This code is taken almost verbatim from PGP::Sign except for the code to
-# figure out the PGP style.
-sub pgp_verify {
-  my ($signature, $version, $message) = @_;
-  chomp $signature;
-
-  # Ignore SIGPIPE, since we're going to be talking to PGP.
-  local $SIG{PIPE} = 'IGNORE';
-
-  # Set the PGP style based on whether $gpgv is set.
-  my $pgpstyle = ($gpgv ? 'GPG' : 'PGP2');
-
-  # Because this is a detached signature, we actually need to save both
-  # the signature and the data to files and then run PGP on the signature
-  # file to make it verify the signature.  Because this is a detached
-  # signature, though, we don't have to do any data mangling, which makes
-  # our lives much easier.  It would be nice to do this without having to
-  # use temporary files, but I don't see any way to do so without running
-  # into mangling problems.
-  #
-  # PGP v5 *requires* there be some subheader or another.  *sigh*.  So we
-  # supply one if Version isn't given.  :)
-  my $umask = umask 077;
-  my $filename = $tmpdir . '/pgp' . time . '.' . $$;
-  my $sigfile = new FileHandle "$filename.asc", O_WRONLY|O_EXCL|O_CREAT;
-  unless ($sigfile) {
-    &errmsg ("Unable to open temp file $filename.asc: $!\n");
-    return (255, undef);
-  }
-  if ($pgpstyle eq 'PGP2') {
-    print $sigfile "-----BEGIN PGP MESSAGE-----\n";
-  } else {
-    print $sigfile "-----BEGIN PGP SIGNATURE-----\n";
-  }
-  if (defined $version) {
-    print $sigfile "Version: $version\n";
-  } elsif ($pgpstyle ne 'GPG') {
-    print $sigfile "Comment: Use GnuPG; it's better :)\n";
-  }
-  print $sigfile "\n", $signature;
-  if ($pgpstyle eq 'PGP2') {
-    print $sigfile "\n-----END PGP MESSAGE-----\n";
-  } else {
-    print $sigfile "\n-----END PGP SIGNATURE-----\n";
-  }
-  close $sigfile;
-
-  # Signature saved.  Now save the actual message.
-  my $datafile = new FileHandle "$filename", O_WRONLY|O_EXCL|O_CREAT;
-  unless ($datafile) {
-    &errmsg ("Unable to open temp file $filename: $!\n");
-    unlink "$filename.asc";
-    return (255, undef);
-  }
-  print $datafile $message;
-  close $datafile;
-
-  # Figure out what command line we'll be using.
-  my @command;
-  if ($pgpstyle eq 'GPG') {
-    @command = ($gpgv, qw/--quiet --status-fd=1 --logger-fd=1/);
-  } else {
-    @command = ($pgp, '+batchmode', '+language=en');
-  }
-
-  # Now, call PGP to check the signature.  Because we've written
-  # everything out to a file, this is actually fairly simple; all we need
-  # to do is grab stdout.  PGP prints its banner information to stderr, so
-  # just ignore stderr.  Set PGPPATH if desired.
-  #
-  # For GnuPG, use pubring.gpg if an explicit keyring was configured or
-  # found.  Otherwise, use trustedkeys.gpg in the default keyring location
-  # if found and non-zero, or fall back on pubring.gpg.  This is
-  # definitely not the logic that I would use if writing this from
-  # scratch, but it has the most backward compatibility.
-  local $ENV{PGPPATH} = $keyring if ($keyring && $pgpstyle ne 'GPG');
-  if ($pgpstyle eq 'GPG') {
-    if ($keyring) {
-      push (@command, "--keyring=$keyring/pubring.gpg");
-    } else {
-      my $home = $ENV{GNUPGHOME} || $ENV{HOME};
-      $home .= '/.gnupg' if $home;
-      if ($home && ! -s "$home/trustedkeys.gpg" && -f "$home/pubring.gpg") {
-        push (@command, "--keyring=pubring.gpg");
-      }
-    }
-  }
-  push (@command, "$filename.asc");
-  push (@command, $filename);
-  my $input = new FileHandle;
-  my $output = new FileHandle;
-  my $pid = eval { open3 ($input, $output, $output, @command) };
-  if ($@) {
-    &errmsg ($@);
-    &errmsg ("Execution of $command[0] failed.\n");
-    unlink ($filename, "$filename.asc");
-    return (255, undef);
-  }
-  close $input;
-
-  # Check for the message that gives us the key status and return the
-  # appropriate thing to our caller.  This part is a zoo due to all of the
-  # different formats used.  GPG has finally done the right thing and
-  # implemented a separate status stream with parseable data.
-  #
-  # MIT PGP 2.6.2 and PGP 6.5.2:
-  #   Good signature from user "Russ Allbery <rra@stanford.edu>".
-  # ViaCrypt PGP 4.0:
-  #   Good signature from user:  Russ Allbery <rra@stanford.edu>
-  # PGP 5.0:
-  #   Good signature made 1999-02-10 03:29 GMT by key:
-  #     1024 bits, Key ID 0AFC7476, Created 1999-02-10
-  #      "Russ Allbery <rra@stanford.edu>"
-  #
-  # Also, PGP v2 prints out "Bad signature" while PGP v5 uses "BAD
-  # signature", and PGP v6 reverts back to "Bad signature".
-  local $_;
-  local $/ = '';
-  my $signer;
-  my $ok = 255;
-  while (<$output>) {
-    print if $test;
-    if ($pgpstyle eq 'GPG') {
-      if (/\[GNUPG:\]\s+GOODSIG\s+\S+\s+(\S+)/) {
-        $ok = 0;
-        $signer = $1;
-      } elsif (/\[GNUPG:\]\s+NODATA/ || /\[GNUPG:\]\s+UNEXPECTED/) {
-        $ok = 1;
-      } elsif (/\[GNUPG:\]\s+NO_PUBKEY/) {
-        $ok = 2;
-      } elsif (/\[GNUPG:\]\s+BADSIG\s+/) {
-        $ok = 3;
-      }
-    } else {
-      if (/^Good signature from user(?::\s+(.*)|\s+\"(.*)\"\.)$/m) {
-        $signer = $+;
-        $ok = 0;
-        last;
-      } elsif (/^Good signature made .* by key:\n.+\n\s+\"(.*)\"/m) {
-        $signer = $1;
-        $ok = 0;
-        last;
-      } elsif (/^\S+: Good signature from \"(.*)\"/m) {
-        $signer = $1;
-        $ok = 0;
-        last;
-      } elsif (/^(?:\S+: )?Bad signature /im) {
-        $ok = 3;
-        last;
-      }
-    }
-  }
-  close $input;
-  waitpid ($pid, 0);
-  unlink ($filename, "$filename.asc");
-  umask $umask;
-  return ($ok, $signer || '');
-}
-
-# Log an error message, attempting syslog first based on $syslog_method
-# and falling back on stderr.
-sub errmsg {
-  my ($message) = @_;
-  $message =~ s/\n$//;
-
-  my $date = '';
-  if ($log_date) {
-    $date = strftime ('%Y-%m-%d %T ', localtime);
-  }
-
-  if ($syslog_method && $] >= 5.006) {
-    eval "use Sys::Syslog";
-    $syslog_method = 'internal';
-  }
-
-  if ($syslog_method eq "logger") {
-    my @loggers = ('/usr/ucb/logger', '/usr/bin/logger',
-                   '/usr/local/bin/logger');
-    my $try;
-    foreach $try (@loggers) {
-      if (-x $try) {
-        $syslog_method = $try;
-        last;
-      }
-    }
-    $syslog_method = '' if $syslog_method eq 'logger';
-  }
-
-  if ($syslog_method ne '' && $syslog_method !~ m%/logger$%) {
-    eval "use Sys::Syslog";
-  }
-
-  if ($@ || $syslog_method eq '') {
-    warn $date, "$0: trying to use Perl's syslog: $@\n" if $@;
-    warn $date, $message, "\n";
-    warn $date, "... while processing $messageid\n"
-      if $messageid;
-
-  } else {
-    $message .= " processing $messageid"
-      if $messageid;
-
-    if ($syslog_method =~ m%/logger$%) {
-      unless (system($syslog_method, "-i", "-p",
-                     "$syslog_facility.$syslog_level", $message) == 0) {
-        if ($? >> 8) {
-          warn $date, "$0: $syslog_method exited status ",  $? >>  8, "\n";
-        } else {
-          warn $date, "$0: $syslog_method died on signal ", $? & 255, "\n";
-        }
-        $syslog_method = '';
-        &errmsg($message);
-      }
-
-    } else {
-      # setlogsock arrived in Perl 5.004_03 to enable Sys::Syslog to use a
-      # Unix domain socket to talk to syslogd, which is the only way to do
-      # it when syslog runs with the -l switch.
-      if ($syslog_method eq "unix") {
-        if ($^O eq "dec_osf" && $] >= 5) {
-          eval 'sub Sys::Syslog::_PATH_LOG { "/dev/log" }';
-        }
-        if ($] <= 5.00403 || ! eval "setlogsock('unix')") {
-          warn $date, "$0: cannot use syslog_method 'unix' on this system\n";
-          $syslog_method = '';
-          &errmsg($message);
-          return;
-        }
-      }
-
-      # Unfortunately, there is no way to definitively know in this
-      # program if the message was logged.  I wish there were a way to
-      # send a message to stderr if and only if the syslog attempt failed.
-      &openlog($0, 'pid', $syslog_facility);
-      &syslog($syslog_level, $_[0]);
-      &closelog();
-    }
-  }
-}
-
-sub fail {
-  &errmsg($_[0]);
-  exit 255;
-}
-
-# Get a lock in essentially the same fashion as INN's shlock.  return 1 on
-# success, 0 for normal failure, -1 for abnormal failure.  "normal
-# failure" is that a lock is apparently in use by someone else.
-sub shlock {
-  my ($file) = @_;
-  my ($ltmp, $pid);
-
-  unless (defined(&ENOENT)) {
-    eval "require POSIX qw(:errno_h)";
-    if ($@) {
-      # values taken from BSD/OS 3.1
-      sub ENOENT {  2 }
-      sub ESRCH  {  3 }
-      sub EEXIST { 17 }
-    }
-  }
-
-  $ltmp = ($file =~ m%(.*/)%)[0] . "shlock$$";
-
-  # This should really attempt to use another temp name.
-  -e $ltmp && (unlink($ltmp) || return -1);
-
-  open(LTMP, ">$ltmp") || return -1;
-  print LTMP "$$\n" || (unlink($ltmp), return -1);
-  close(LTMP) || (unlink($ltmp), return -1);
-
-  if (!link($ltmp, $file)) {
-    if ($! == &EEXIST) {
-      if (open(LOCK, "<$file")) {
-        $pid = <LOCK>;
-        if ($pid =~ /^\d+$/ && (kill(0, $pid) == 1 || $! != &ESRCH)) {
-          unlink($ltmp);
-          return 0;
-        }
-
-        # OK, the pid in the lockfile is not a number or no longer exists.
-        close(LOCK);            # silent failure is ok here
-
-        # Unlink failed.
-        if (unlink($file) != 1 && $! != &ENOENT) {
-          unlink($ltmp);
-          return 0;
-        }
-
-      # Check if open failed for reason other than file no longer present.
-      } elsif ($! != &ENOENT) {
-        unlink($ltmp);
-        return -1;
-      }
-
-      # Either this process unlinked the lockfile because it was bogus, or
-      # between this process's link() and open() the other process holding
-      # the lock unlinked it.  This process can now try to acquire.
-      if (! link($ltmp, $file)) {
-        unlink($ltmp);
-        return $! == &EEXIST ? 0 : -1; # Maybe another proc grabbed the lock.
-      }
-
-    } else {                    # First attempt to link failed.
-      unlink($ltmp);
-      return 0;
-    }
-  }
-  unlink($ltmp);
-  return 1;
-}
-
-=head1 NAME
-
-pgpverify - Cryptographically verify Usenet control messages
-
-=head1 SYNOPSIS
-
-B<pgpverify> [B<-test>] < I<message>
-
-=head1 DESCRIPTION
-
-The B<pgpverify> program reads (on standard input) a Usenet control
-message that has been cryptographically signed using the B<signcontrol>
-program (or some other program that produces a compatible format).
-B<pgpverify> then uses a PGP implementation to determine who signed the
-control message.  If the control message has a valid signature,
-B<pgpverify> prints (to stdout) the user ID of the key that signed the
-message.  Otherwise, it exits with a non-zero exit status.
-
-If B<pgpverify> is installed as part of INN, it uses INN's configuration
-to determine what signature verification program to use, how to log
-errors, what temporary directory to use, and what keyring to use.
-Otherwise, all of those parameters can be set by editing the beginning of
-this script.
-
-By default, when running as part of INN, B<pgpverify> expects the PGP key
-ring to be found in I<pathetc>/pgp (as either F<pubring.pgp> or
-F<pubring.gpg> depending on whether PGP or GnuPG is used to verify
-signatures).  If that directory doesn't exist, it will fall back on using
-the default key ring, which is in a F<.pgp> or F<.gnupg> subdirectory of
-the running user's home directory.
-
-INN, when using GnuPG, configures B<pgpverify> to use B<gpgv>, which by
-default expects keys to be in a keyring named F<trustedkeys.gpg>, since it
-doesn't implement trust checking directly.  B<pgpverify> uses that file if
-present but falls back to F<pubring.gpg> if it's not found.  This bypasses
-the trust model for checking keys, but is compatible with the way that
-B<pgpverify> used to behave.  Of course, if a keyring is found in
-I<pathetc>/pgp or configured at the top of the script, that overrides all of
-this behavior.
-
-=head1 OPTIONS
-
-The B<-test> flag causes B<pgpverify> to print out the input that it is
-passing to PGP (which is a reconstructed version of the input that
-supposedly created the control message) as well as the output from PGP's
-analysis of the message.
-
-=head1 EXIT STATUS
-
-B<pgpverify> may exit with the following statuses:
-
-=over 4
-
-=item 0Z<>
-
-The control message had a good PGP signature.
-
-=item 1
-
-The control message had no PGP signature.
-
-=item 2
-
-The control message had an unknown PGP signature.
-
-=item 3
-
-The control message had a bad PGP signature.
-
-=item 255
-
-A problem occurred not directly related to PGP analysis of signature.
-
-=back
-
-=head1 ENVIRONMENT
-
-B<pgpverify> does not modify or otherwise alter the environment before
-invoking the B<pgp> or B<gpgv> program.  It is the responsibility of the
-person who installs B<pgpverify> to ensure that when B<pgp> or B<gpgv>
-runs, it has the ability to locate and read a PGP key file that contains
-the PGP public keys for the appropriate Usenet hierarchy administrators.
-B<pgpverify> can be pointed to an appropriate key ring by editing
-variables at the beginning of this script.
-
-=head1 NOTES
-
-Historically, Usenet news server administrators have configured their news
-servers to automatically honor Usenet control messages based on the
-originator of the control messages and the hierarchies for which the
-control messages applied.  For example, in the past, David Lawrence always
-issued control messages for the S<"Big 8"> hierarchies (comp, humanities,
-misc, news, rec, sci, soc, talk).  Usenet news administrators would
-configure their news server software to automatically honor newgroup and
-rmgroup control messages that originated from David Lawrence and applied
-to any of the S<Big 8> hierarchies.
-
-Unfortunately, Usenet news articles (including control messages) are
-notoriously easy to forge.  Soon, malicious users realized they could
-create or remove (at least temporarily) any S<Big 8> newsgroup they wanted by
-simply forging an appropriate control message in David Lawrence's name.
-As Usenet became more widely used, forgeries became more common.
-
-The B<pgpverify> program was designed to allow Usenet news administrators
-to configure their servers to cryptographically verify control messages
-before automatically acting on them.  Under the B<pgpverify> system, a Usenet
-hierarchy maintainer creates a PGP public/private key pair and
-disseminates the public key.  Whenever the hierarchy maintainer issues a
-control message, he uses the B<signcontrol> program to sign the control
-message with the PGP private key.  Usenet news administrators configure
-their news servers to run the B<pgpverify> program on the appropriate
-control messages, and take action based on the PGP key User ID that signed
-the control message, not the name and address that appear in the control
-message's From: or Sender: headers.
-
-Thus, appropriate use of the B<signcontrol> and B<pgpverify> programs
-essentially eliminates the possibility of malicious users forging Usenet
-control messages that sites will act upon, as such users would have to
-obtain the PGP private key in order to forge a control message that would
-pass the cryptographic verification step.  If the hierarchy administrators
-properly protect their PGP private keys, the only way a malicious user
-could forge a validly-signed control message would be by breaking the
-public key encryption algorithm, which (at least at this time) is believed
-to be prohibitively difficult for PGP keys of a sufficient bit length.
-
-=head1 HISTORY
-
-B<pgpverify> was written by David C Lawrence <tale@isc.org>.  Manual page
-provided by James Ralston.  It is currently maintained by Russ Allbery
-<rra@stanford.edu>.
-
-=head1 COPYRIGHT AND LICENSE
-
-David Lawrence wrote:  "Our lawyer told me to include the following.  The
-upshot of it is that you can use the software for free as much as you
-like."
-
-Copyright (c) 1996 UUNET Technologies, Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-=over 4
-
-=item 1.
-
-Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimer.
-
-=item 2.
-
-Redistributions in binary form must reproduce the above copyright notice,
-this list of conditions and the following disclaimer in the documentation
-and/or other materials provided with the distribution.
-
-=item 3.
-
-All advertising materials mentioning features or use of this software must
-display the following acknowledgement:
-
-  This product includes software developed by UUNET Technologies, Inc.
-
-=item 4.
-
-The name of UUNET Technologies ("UUNET") may not be used to endorse or
-promote products derived from this software without specific prior written
-permission.
-
-=back
-
-THIS SOFTWARE IS PROVIDED BY UUNET "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
-NO EVENT SHALL UUNET BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-=head1 SEE ALSO
-
-gpgv(1), pgp(1).
-
-L<ftp://ftp.isc.org/pub/pgpcontrol/> is where the most recent versions of
-B<signcontrol> and B<pgpverify> live, along with PGP public keys used for
-hierarchy administration.
-
-=cut
-
-# Local variables:
-# cperl-indent-level: 2
-# fill-column: 74
-# End: