PGP-Sign-0.20/0000755000175000000000000000000010614542010011555 5ustar eaglerootPGP-Sign-0.20/data/0000755000175000000000000000000010614542010012466 5ustar eaglerootPGP-Sign-0.20/data/secring.skr0000644000175000000000000000144410613034124014645 0ustar eagleroot6ƹ'C +&Lg~h* y80ٹnܯ LRfqi4aY#woAcķ9d՘]YϠ~|8RtSV-~MMLΉf% t;NHh^XnP   u4#ĞTuOY4 UGHui4u3M v{7oѯ?O﷖Ƽ_RFW I.k"E͍9\{kV85F`:"YW.e>[V  n6qd`h|VTbP ۢdL)zJoKR6z#cPGP-Sign-0.20/data/message0000644000175000000000000000172310613034124014041 0ustar eagleroot`Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Beware the Jujub bird, and shun The frumious Bandersnatch!' He took his vorpal sword in hand: Long time the manxome foe he sought-- So rested he by the Tumtum tree, And stood awhile in thought. And as in uffish thought he stood, The Jabberwock, with eyes of flame, Came whiffling through the tulgey wood, And burbled as it came! One, two! One, two! And through and through The vorpal blade went snicker-snack! He left it dead, and with its head He went galumphing back. `And has thou slain the Jabberwock? Come to my arms, my beamish boy! O frabjous day! Calloh! Callay!' He chortled in his joy. 'Twas brillig, and the slithy toves Did gyre and gimble in the wabe; All mimsy were the borogoves, And the mome raths outgrabe. Lewis Carroll "Jabberwocky" PGP-Sign-0.20/data/message.asc0000644000175000000000000000034410613034124014604 0ustar eagleroot-----BEGIN PGP SIGNATURE----- Version: GnuPG v0.9.2 (SunOS) Comment: For info see http://www.gnupg.org iD8DBQE2wP0g+YXjQAr8dHYRAvg6AKCkk8A0f4app+N/SdConKc65YtZtQCeMk9V e8D+5/bGyHtJr5uM2LYMDd8= =0SFF -----END PGP SIGNATURE----- PGP-Sign-0.20/data/secring.pgp0000644000175000000000000000075410613034124014637 0ustar eagleroot6ם"z..7 nSgc c >B{#$ޛ'Uk]drEH&ٜVw~ي1b ΢Τlp0}&HʮC^ڐ?Wf / ZUpUG H~?C#x MfIQv29&;icDՄա@!9t&݄U8gV<2ŲUbLThv|.2ο{!}>1L:xYy7.±0lʻ܎V7:I~*3h!?.TC'2$ 0w܌/ck;Ïr&xwZ~cZ%<+_?>ShjNP=;B0ؓo,f  a2%@Ap7 1>U ?ᥧxC^藮testingPGP-Sign-0.20/data/pubring.pkr0000644000175000000000000000613410613034124014657 0ustar eagleroot65-RD!lH# 'Giyv#r*=-pWFoH KǞ}=vXS)jp5Mb.ښ([ UglL@UԻ`)KW@՚4xg`Tp|ԇ:/$ aL\%`ѴTxIP%4JUt?/{ijG1[.8oQf?OwBv;e]-lþH=`L:]i;`rC~Y!SmctOo_ %e֪5h9K`EapB<UAw^^-xmR5R뽋*|g<:Qܰ #e,ˆrc[P<#' &dRuss Allbery W65  @ tvnM(ߛBzKaLYes{c( }j`C` 6iHsW;ՠ[J*ja-mA0 |+Z#YJR<(5au&q&RaӪě3SE|Q&fx%ߏ,1x7Jg.2q1={cvfy:0Q(*\6n> xCbY" X|GQ;@}v <ѯ5'E}VY>9?]:"fz<"FLXƏðF6i @ tvPn[ȉ 55b|3ӈzVG^@`6ם"z..7 nSgc c >B{#$ޛ'Uk]drEH&ٜVw~ي1b ΢Τlp0}&HʮC^ڐ?Wf / ZUpUG testingm.s/.;XV)v( &~?KٚX*-%m{&h- Qlr^\ p⬓8 {hAs5V9%R. Russell Allbery u35ݑ5V9D{ }-ɬIbzzZ%pPb|Jp]acelrҐnAME|`0R. Russell Allbery u3G5V9)>0G6%o7*^ԲuCMRwLRElBWvv DK``^Ť Vz$D2Rgbꁂy <`(R. Russell Allbery 1-1@=U23I1b5-r[d-1x)#,'.@~IY%2_i)v*aEߜ- ΂{7bP=R Y2CGT٩YJ} *;= $5: 1눰1~ϓ+<3.@0݀ރ N:⭁뻠:0yjJ@v_bfKehu_rUy-ٺiDn7R%Ib}HU<|]rjl.](u1wҖ5V9& !mw[{c7^7'*>.2= Bre3 axGz؈eF}n`&35D?@ĠSg`Ua h`1weʹ%]a )xŠƇ!Xv~p ad3Tˈe}VծS- j=!}6!m%|"*8?g'í:MqO)eA#14@ذEagle u1w5V9M9,w9FӜ(JqrUf2CS$o=PW-B؉К\<|c4BK4} ,ubj6S`6ƹ'C +&Lg~h* y80ٹnܯ LRfqi4aY#woAcķ9d՘]YϠ~|8RtSV-~MMLΉf% t;NHh^XnP   u4#ĞTuOY4 UGHui4u3M v{7oѯ?O﷖Ƽ_RFW I.k"E͍9\{kV85F`:"YW.e>[V ?6+.I@Gz5;u35ݑ5V9D{ }-ɬIbzzZ%pPb|Jp]acelrҐnAME|@0R. Russell Allbery u3G5V9)>0G6%o7*^ԲuCMRwLRElBWvv DK``^Ť Vz$D2Rgbꁂy <@(R. Russell Allbery 1-1@=U23I1b5-r[d-1x)#,'.@~IY%2_i)v*aEߜ- ΂{7bP=R Y2CGT٩YJ} *;= $5: 1눰1~ϓ+<3.@0݀ރ N:⭁뻠:0yjJ@v_bfKehu_rUy-ٺiDn7R%Ib}HU<|]rjl.](u1wҖ5V9& !mw[{c7^7'*>.2= Bre3 axGz؈eF}n`&35D?@ĠSg`Ua h@1weʹ%]a )xŠƇ!Xv~p ad3Tˈe}VծS- j=!}6!m%|"*8?g'í:MqO)eA#14@ذEagle u1w5V9M9,w9FӜ(JqrUf2CS$o=PW-B؉К\<|c4BK4} ,ubj6S@6ם"z..7 nSgc c >B{#$ޛ'Uk]drEH&ٜVw~ي1b ΢Τlp0}&HʮC^ڐ?Wf / ZUpUG testingPGP-Sign-0.20/data/pubring.gpg0000644000175000000000000000332610613034124014640 0ustar eagleroot6M\Vc-l;}ei%a{0O\[;COWO ]@~4 bi)*}ލN+ LN2!LPhg=MW4 4\kB*t2 leY/dϱGJܲ.N[a ul*⟝uQ\ Xd򿋱> ŸvX2>ixDj_1+Dad paoԍ$p8؄Z5;v˔FPoI&wl}{7fZ% t,? (Sm-wE ڹ]tA2jC+X%Fэm[!XJ[jfcF=i"'f?2YtestingW6  BI+ZtsܣT;VpX8oT4K ٥eI 6f!A!r˓{/F$  }]T¡Z3.&5ritu(qAuẗ%e4E,3 qټW65  @ tvnM(ߛBzKaLYes{c( }j`C 6iHsW;ՠ[J*ja-mA0 |+Z#YJR<(5au&q&RaӪě3SE|Q&fx%ߏ,1x7Jg.2q1={cvfy:0Q(*\6n> xCbY" X|GQ;@}v <ѯ5'E}VY>9?]:"fz<"FLXƏÈF6i @ tvPn[ȉ 55b|3ӈzVG^@PGP-Sign-0.20/data/message.asc.v40000644000175000000000000000035410613034124015135 0ustar eagleroot-----BEGIN PGP SIGNATURE----- Version: GnuPG v0.9.2 (SunOS) Comment: For info see http://www.gnupg.org iEYEARECAAYFAjbA/fsACgkQ+YXjQAr8dHYsMQCgpzOkRRopdW0nuiSNMB6Qx2Iw bw0AoMl82UxQEkh4uIcLSZMdY31Z8gtL =Dj7i -----END PGP SIGNATURE----- PGP-Sign-0.20/data/secring.gpg0000644000175000000000000000223310613034124014620 0ustar eagleroot6M\Vc-l;}ei%a{0O\[;COWO ]@~4 bi)*}ލN+ LN2!LPhg=MW4 4\kB*t2 leY/dϱGJܲ.N[a ul*⟝uQ\ Xd򿋱> ŸvX2>ixDj_1+Dad paoԍ$p8؄Z5;v˔FPoI&wl}{7fZ% t,? (Sm-wE ڹ]tA2jC+X%Fэm[!XJ[jfcF=i"'f?2Yx(r4WzrQaQz궙7{{:@q!&#:DSA_factor:z+Iξ6ŭ:A5&#:DSA_factor:q+9NQB6.!ՍN%&#:DSA_factor:PPy?شȉ芬p#$testingW6  BI+Ztu hF,vGɮFÈs)7ٲ 6f!A!r˓{/F$  }]T¡Z3.&5ritu(qAuẗ%e4E,3 qټ,bPGP-Sign-0.20/debian/0000755000175000000000000000000010614542010012777 5ustar eaglerootPGP-Sign-0.20/debian/copyright0000644000175000000000000000145010613034124014733 0ustar eaglerootDebian package by Russ Allbery 2004-08-04 It was downloaded from: Debian packaging copyright: All Debian packaging files are covered under the same copyright as the upstream source. Copyright: Copyright 1997, 1998, 1999, 2000, 2002, 2004 Russ Allbery . This program is free software; you may redistribute it and/or modify it under the same terms as Perl itself. Perl is distributed under either the Artistic License or the GNU General Public License. The full text of the GNU General Public License is available in Debian systems in /usr/share/common-licenses/GPL. The full text of the Artistic License is available on Debian systems in /usr/share/common-licenses/Artistic. PGP-Sign-0.20/debian/rules0000755000175000000000000000270010613034124014057 0ustar eagleroot#!/usr/bin/make -f # Rules for building libpgp-sign-perl. # # Based on: # # This debian/rules file is provided as a template for normal perl # packages. It was created by Marc Brockschmidt for # the Debian Perl Group (http://pkg-perl.alioth.debian.org/) but may # be used freely wherever it is useful. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 # If set to a true value then MakeMaker's prompt function will # always return the default without waiting for user input. export PERL_MM_USE_DEFAULT=1 PACKAGE = $(shell dh_listpackages) TMP = $(CURDIR)/debian/$(PACKAGE) PERL ?= /usr/bin/perl build: build-stamp build-stamp: dh_testdir $(PERL) Makefile.PL INSTALLDIRS=vendor PGP=/usr/bin/gpg $(MAKE) touch build-stamp clean: dh_testdir dh_testroot ifeq (Makefile,$(wildcard Makefile)) $(MAKE) distclean endif rm -f data/trustdb.gpg dh_clean build-stamp install-stamp install: install-stamp install-stamp: build-stamp dh_testdir dh_testroot dh_clean $(MAKE) test $(MAKE) install DESTDIR=$(TMP) PREFIX=/usr rmdir --ignore-fail-on-non-empty --parents $(TMP)/usr/lib/perl5 touch install-stamp binary-indep: build install dh_testdir dh_testroot dh_installdocs README TODO dh_installchangelogs ChangeLog dh_perl dh_link dh_strip dh_compress dh_fixperms dh_installdeb dh_gencontrol dh_md5sums dh_builddeb binary-arch: binary: binary-arch binary-indep .PHONY: build clean binary-arch binary-indep binary PGP-Sign-0.20/debian/compat0000644000175000000000000000000210613034124014176 0ustar eagleroot4 PGP-Sign-0.20/debian/control0000644000175000000000000000127610613034124014411 0ustar eaglerootSource: libpgp-sign-perl Section: perl Priority: optional Build-Depends: debhelper (>= 4.0.2) Build-Depends-Indep: perl (>= 5.8.0-7), gnupg Maintainer: Russ Allbery Standards-Version: 3.6.2 Package: libpgp-sign-perl Architecture: all Depends: ${perl:Depends}, gnupg Description: Perl module to create detached PGP signatures Creates and checks detached PGP signatures for textual data using GnuPG. Other PGP implementations are also supported with run-time configuration. Secret key passphrases are passed via a pipe, and no temporary files are required for signature generation (but are for signature verification). . Homepage: http://www.eyrie.org/~eagle/software/pgp-sign/ PGP-Sign-0.20/debian/changelog0000644000175000000000000000234310613034124014654 0ustar eaglerootlibpgp-sign-perl (0.19-4) unstable; urgency=low * Providing binary-arch in debian/rules is required by Policy even if there are no arch-dependent packages. Whoops. -- Russ Allbery Mon, 5 Dec 2005 15:09:47 -0800 libpgp-sign-perl (0.19-3) unstable; urgency=low * Run make test when building the package. * Simplify debian/rules. * Update copyright to my current format and add an explicit packaging copyright and license statement. * Update standards version to 3.6.2 (no changes required). * Update maintainer address. -- Russ Allbery Wed, 16 Nov 2005 21:05:52 -0800 libpgp-sign-perl (0.19-2) unstable; urgency=low * Uploaded to Debian. (Closes: #308429) * Add a watch file. * Use the recommend format for the Homepage link in the description. -- Russ Allbery Fri, 10 Jun 2005 15:43:39 -0700 libpgp-sign-perl (0.19-1) unstable; urgency=low * New upstream release. - Use --status-fd with GnuPG. Fixes pgp_verify in non-English locales. -- Russ Allbery Sun, 8 Aug 2004 02:57:42 -0700 libpgp-sign-perl (0.18-1) unstable; urgency=low * Initial Release. -- Russ Allbery Wed, 4 Aug 2004 22:26:31 -0700 PGP-Sign-0.20/VERSION.pm0000644000175000000000000000004610614452675013261 0ustar eaglerootpackage PGP::Sign; $VERSION = '0.20'; PGP-Sign-0.20/Sign.in0000644000175000000000000006647710613034124013032 0ustar eagleroot# PGP::Sign -- Create a PGP signature for data, securely. -*- perl -*- # $Id: Sign.in 158 2004-08-08 09:42:35Z eagle $ # # Copyright 1997, 1998, 1999, 2000, 2002, 2004 Russ Allbery # # This program is free software; you may redistribute it and/or modify it # under the same terms as Perl itself. # # THIS IS NOT A GENERAL PGP MODULE # # For a general PGP module that handles encryption and decryption, key ring # management, and all of the other wonderful things you want to do with PGP, # see the PGP module directory on CPAN. This module is designed to do one and # only one thing and do it fast, well, and securely -- create and check # detached signatures for some block of data. # # This above all: to thine own self be true, # And it must follow, as the night the day, # Thou canst not then be false to any man. # -- William Shakespeare, _Hamlet_ ############################################################################## # Modules and declarations ############################################################################## package PGP::Sign; require 5.003; use Exporter (); use Fcntl qw(F_SETFD O_WRONLY O_CREAT O_EXCL); use FileHandle (); use IPC::Open3 qw(open3); use strict; use vars qw(@ERROR @EXPORT @EXPORT_OK @ISA $MUNGE $PGPS $PGPV $PGPPATH $PGPSTYLE $TMPDIR $VERSION); @ISA = qw(Exporter); @EXPORT = qw(pgp_sign pgp_verify); @EXPORT_OK = qw(pgp_error); # The current PGP::Sign version number, which is not the same as the CVS # revision of this file. Picked up during build time. # @@ VERSION ############################################################################## # Global variables ############################################################################## # The text of any errors resulting from the last call to pgp_sign(). @ERROR = (); # Whether or not to perform some standard munging to make other signing and # checking routines happy. $MUNGE = 0; # The default path to PGP. PGPS is for signing, PGPV is for verifying (with # PGP v5 these are two different commands). This is picked up at install # time. # @@ PGPS # @@ PGPV # The path to the directory containing the key ring. If not set, PGP (v2, v5, # or v6) defaults to $ENV{PGPPATH} or $HOME/.pgp. GPG defaults to # $ENV{GNUPGHOME} or $HOME/.gnupg. Setting this will also be made to affect # GPG. $PGPPATH = ''; # What style of PGP invocation to use by default. Allowable values are PGP2, # PGP5, PGP6, and GPG. This is picked up at install time. # @@ PGPSTYLE # The directory in which temporary files should be created. $TMPDIR = $ENV{TMPDIR} || '/tmp'; ############################################################################## # Implementation ############################################################################## # This function actually sends the data to a file handle. It's necessary to # implement munging (stripping trailing spaces on a line). { my $spaces = ''; sub output { my ($fh, $string) = @_; if ($MUNGE) { $string = $spaces . $string; $string =~ s/ +(\n.)/$1/g; my $newline = ($string =~ s/\n$//); $string =~ s/( +)$//; if ($newline) { $string .= "\n" } else { $spaces = $1 } } else { $spaces = ''; } print $fh $string; } } # This is our generic "take this data and shove it" routine, used both for # signature generation and signature checking. The first argument is the file # handle to shove all the data into, and the remaining arguments are sources # of data. Scalars, references to arrays, references to FileHandle or # IO::Handle objects, file globs, references to code, and references to file # globs are all supported as ways to get the data, and at most one line at a # time is read (cutting down on memory usage). # # References to code are an interesting subcase. A code reference is executed # repeatedly, whatever it returns being passed to PGP using the ORS specified # if any, until it returns undef. sub write_data { my $fh = shift; # Deal with all of our possible sources of input, one at a time. We # really want perl 5.004 here, since we want UNIVERSAL::isa(). # Unfortunately, we can't rely on 5.004 yet. *But*, the main reason we # want isa() is to handle the various derived IO::Handle classes, and # 5.003 should only have FileHandle, so we can hack our way around that. # We can't do anything interesting or particularly "cool" with references # to references, so those we just print. (Perl allows circular # references, so we can't just dereference references to references until # we get something interesting.) Hashes are treated like arrays. my $source; for $source (@_) { if (ref $source eq 'ARRAY' or ref $source eq 'HASH') { for (@$source) { output ($fh, $_) } } elsif (ref $source eq 'GLOB' or ref \$source eq 'GLOB') { local $_; while (<$source>) { output ($fh, $_) } } elsif (ref $source eq 'SCALAR') { output ($fh, $$source); } elsif (ref $source eq 'CODE') { local $_; while (defined ($_ = &$source ())) { output ($fh, $_) } } elsif (ref $source eq 'REF') { output ($fh, $source); } elsif (ref $source) { if ($] > 5.003) { if (UNIVERSAL::isa ($source, 'IO::Handle')) { local $_; while (<$source>) { output ($fh, $_) } } else { output ($fh, $source); } } else { if (ref $source eq 'FileHandle') { local $_; while (<$source>) { output ($fh, $_) } } else { output ($fh, $source); } } } else { output ($fh, $source); } } } # Create a detached signature for the given data. The first argument should # be a key id and the second argument the PGP passphrase, and then all # remaining arguments are considered to be part of the data to be signed and # are handed off to write_data(). # # In a scalar context, the signature is returned as an ASCII-armored block # with embedded newlines. In array context, a list consisting of the # signature and the PGP version number is returned. Returns undef in the # event of an error, and the error text is then stored in @PGP::Sign::ERROR # and can be retrieved with pgp_error(). sub pgp_sign { my $keyid = shift; my $passphrase = shift; # Ignore SIGPIPE, since we're going to be talking to PGP. local $SIG{PIPE} = 'IGNORE'; # Figure out what command line we'll be using. PGP v6 and PGP v2 use # compatible syntaxes for what we're trying to do. PGP v5 would have, # except that the -s option isn't valid when you call pgps. *sigh* my @command; if ($PGPSTYLE eq 'PGP5') { @command = ($PGPS, '+batchmode', '-baft', '-u', $keyid); } elsif ($PGPSTYLE eq 'GPG') { @command = ($PGPS, '--detach-sign', '--armor', '--textmode', '--batch', '--force-v3-sigs', '-u', $keyid); } else { @command = ($PGPS, '+batchmode', '-sbaft', '-u', $keyid); } # We need to send the password to PGP, but we don't want to use either the # command line or an environment variable, since both may expose us to # snoopers on the system. So we create a pipe, stick the password in it, # and then pass the file descriptor to PGP. PGP wants to know about this # in an environment variable; GPG uses a command-line flag. 5.005_03 # started setting close-on-exec on file handles > $^F, so we need to clear # that here (but ignore errors on platforms where fcntl or F_SETFD doesn't # exist, if any). my $passfh = new FileHandle; my $writefh = new FileHandle; pipe ($passfh, $writefh); eval { fcntl ($passfh, F_SETFD, 0) }; print $writefh $passphrase; close $writefh; local $ENV{PGPPASSFD}; if ($PGPSTYLE eq 'GPG') { push (@command, '--passphrase-fd', $passfh->fileno); } else { $ENV{PGPPASSFD} = $passfh->fileno (); } # Fork off a pgp process that we're going to be feeding data to, and tell # it to just generate a signature using the given key id and pass phrase. # Set PGPPATH if desired. local $ENV{PGPPATH} = $PGPPATH if ($PGPPATH && $PGPSTYLE ne 'GPG'); if ($PGPPATH && $PGPSTYLE eq 'GPG') { push (@command, '--homedir', $PGPPATH); } my $pgp = new FileHandle; my $signature = new FileHandle; my $errors = new FileHandle; my $pid = eval { open3 ($pgp, $signature, $errors, @command) }; if ($@) { @ERROR = ($@, "Execution of $command[0] failed.\n"); return undef; } # Send the rest of the arguments off to write_data(). unshift (@_, $pgp); &write_data; # All done. Close the pipe to PGP, clean up, and see if we succeeded. If # not, save the error output and return undef. close $pgp; local $/ = "\n"; my @errors = <$errors>; my @signature = <$signature>; close $signature; close $errors; close $passfh; waitpid ($pid, 0); if ($? != 0) { @ERROR = (@errors, "$command[0] returned exit status $?\n"); return undef; } # Now, clean up the returned signature and return it, along with the # version number if desired. PGP v2 calls this a PGP MESSAGE, whereas PGP # v5 and v6 and GPG both (more correctly) call it a PGP SIGNATURE, so # accept either. while ((shift @signature) !~ /-----BEGIN PGP \S+-----\n/) { unless (@signature) { @ERROR = ("No signature from PGP (command not found?)\n"); return undef; } } my $version; while ($signature[0] ne "\n" && @signature) { $version = $1 if ((shift @signature) =~ /^Version:\s+(.*?)\s*$/); } shift @signature; pop @signature; $signature = join ('', @signature); chomp $signature; undef @ERROR; wantarray ? ($signature, $version) : $signature; } # Check a detatched 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 some number of data sources that write_data() can # handle and returns the key id of the signature, the empty string if the # signature didn't check, and undef in the event of an error. In the event of # some sort of an error, we stick the error in @ERROR. sub pgp_verify { my $signature = shift; my $version = shift; chomp $signature; # Ignore SIGPIPE, since we're going to be talking to PGP. local $SIG{PIPE} = 'IGNORE'; # 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) { @ERROR = ("Unable to open temp file $filename.asc: $!\n"); return 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 eq 'PGP5') { 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; my $datafile = new FileHandle "$filename", O_WRONLY|O_EXCL|O_CREAT; unless ($datafile) { unlink "$filename.asc"; @ERROR = ("Unable to open temp file $filename: $!\n"); return undef; } unshift (@_, $datafile); &write_data; close $datafile; # Figure out what command line we'll be using. my @command; if ($PGPSTYLE eq 'GPG') { @command = ($PGPV, '--batch', '--verify', '--quiet' ,'--status-fd=1', '--logger-fd=1'); } else { @command = ($PGPV, '+batchmode'); } # 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. local $ENV{PGPPATH} = $PGPPATH if ($PGPPATH && $PGPSTYLE ne 'GPG'); if ($PGPPATH && $PGPSTYLE eq 'GPG') { push (@command, '--homedir', $PGPPATH); } push (@command, "$filename.asc"); push (@command, $filename) unless $PGPSTYLE eq 'PGP5'; my $pgp = new FileHandle; my $output = new FileHandle; my $pid = eval { open3 ($pgp, $output, $output, @command) }; if ($@) { unlink ($filename, "$filename.asc"); @ERROR = ($@, "Execution of $command[0] failed.\n"); return undef; } close $pgp; # 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. # # Partly from pgpverify, by David Lawrence : # # MIT PGP 2.6.2 and PGP 6.5.2: # Good signature from user "Russ Allbery ". # ViaCrypt PGP 4.0: # Good signature from user: Russ Allbery # 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 " # GPG 1.0.1 (and 0.9.2): # gpg: Good signature from "Russ Allbery " # # 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; while (<$output>) { if ($PGPSTYLE eq 'GPG') { if (/\[GNUPG:\]\s+GOODSIG\s+\S+\s+(.*)/) { $signer = $1; last; } } else { if (/^Good signature from user(?::\s+(.*)|\s+\"(.*)\"\.)$/m) { $signer = $+; last; } elsif (/^Good signature made .* by key:\n.+\n\s+\"(.*)\"/m) { $signer = $1; last; } elsif (/^\S+: Good signature from \"(.*)\"/m) { $signer = $1; last; } elsif (/^(?:\S+: )?Bad signature /im) { last; } } } close $pgp; undef @ERROR; waitpid ($pid, 0); unlink ($filename, "$filename.asc"); umask $umask; $signer ? $signer : ''; } # Return the errors resulting from the last call to pgp_sign() or pgp_verify() # or the empty list if there are none. sub pgp_error { wantarray ? @ERROR : join ('', @ERROR); } ############################################################################## # Module return value and documentation ############################################################################## # Make sure the module returns true. 1; __DATA__ =head1 NAME PGP::Sign - Create detached PGP signatures for data, securely =head1 SYNOPSIS use PGP::Sign; ($signature, $version) = pgp_sign ($keyid, $passphrase, @data); $signer = pgp_verify ($signature, $version, @data); @errors = PGP::Sign::pgp_error; =head1 DESCRIPTION This module is designed to do one and only one thing securely and well; namely, generate and check detached PGP signatures for some arbitrary data. It doesn't do encryption, it doesn't manage keyrings, it doesn't verify signatures, it just signs things. This is ideal for applications like PGPMoose or control message generation that just need a fast signing mechanism. It supports versions 2.6, 5.0, and 6.5.2 of PGP, as well as GnuPG, and therefore supports any of the signature types understood by those programs provided they are installed. The interface is very simple; just call pgp_sign() with a key ID, a pass phrase, and some data, or call pgp_verify() with a signature (in the form generated by pgp_sign()), a version number (which can be undef if you don't want to give a version), and some data. The data can be specified in pretty much any form you can possibly consider data and a few you might not. Scalars and arrays are passed along to PGP; references to arrays are walked and passed one element at a time (to avoid making a copy of the array); file handles, globs, or references to globs are read a line at a time and passed to PGP; and references to code are even supported (see below). About the only thing that we don't handle are references to references (which are just printed to PGP, which probably isn't what you wanted) and hashes (which are treated like arrays, which doesn't make a lot of sense). If you give either function a reference to a sub, it will repeatedly call that sub, sending the results to PGP to be signed, until the sub returns undef. What this lets you do is pass the function an anonymous sub that walks your internal data and performs some manipulations on it a line at a time, thus allowing you to sign a slightly modified form of your data (with initial dashes escaped, for example) without having to use up memory to make an internal copy of it. In a scalar context, pgp_sign() returns the signature as an ASCII-armored block with embedded newlines (but no trailing newline). In a list context, it returns a two-element list consisting of the signature as above and the PGP version that signed it (if that information was present in the signature). Warning: It's expected that in the future this interface will change, and pgp_sign() will instead return a list consisting of the ASCII-armored block and all headers found in the armor. If you're using GnuPG, pgp_sign() will pass it the option B<--force-v3-sigs> so that it will generate PGP 5.0-compatible signatures. pgp_sign() will return undef in the event of any sort of error. pgp_verify() returns the signer of the message in the case of a good signature, the empty string in the case of a bad signature, and undef in the event of some error. It takes the same sort of data sources as pgp_sign(). pgp_error() (which isn't exported by default) returns the error encountered by the last pgp_sign() or pgp_verify(), or undef if there was no error. In a list context, a list of lines is returned; in a scalar context, a long string with embedded newlines is returned. Six global variables can be modified (note that these may eventually be partially or completely replaced with an interface via a PGP::Sign::config() call): =over 4 =item $PGP::Sign::PGPS The path to the program to use to generate signatures. This is set at the time of installation, but can be overridden. =item $PGP::Sign::PGPV The path to the program to use to verify signatures. This is set at the time of installation, but can be overridden. There are two separate variables since PGP 5.0 uses two separate program names for signing and verifying; for PGP 2.6, 6.5.2, or GnuPG, just set both this and $PGP::Sign::PGPS to the same value. =item $PGP::Sign::PGPPATH The path to a directory containing the PGP key rings that should be used. If this isn't set, all versions of PGP will use the value of the environment variable PGPPATH or F<$HOME/.pgp> (the default). GnuPG will use the value of the environment variable GNUPGHOME or F<$HOME/.gnupg>. Note that PGP when signing may want to write F (or F) in this directory if there isn't already a random seed there, so if you're encountering problems with signing, make sure the directory PGP is using is writeable by the user doing the signing. Note also that if you're using GnuPG and the Entropy Gathering Daemon (egd), the entropy socket or a link to it must be located in this directory. =item $PGP::Sign::PGPSTYLE What style of command line arguments and responses to expect from PGP. The only three valid values for this variable are "PGP2" for PGP 2.6 behavior, "PGP5" for PGP 5.0 behavior, "PGP6" for PGP 6.5 behavior, and "GPG" for GnuPG behavior. What command line arguments PGP::Sign uses when running PGP are entirely determined by this variable. It is set at the time of installation, but can be overridden. =item $PGP::Sign::TMPDIR The directory in which temporary files are created. Defaults to TMPDIR if set, and F if not. =item $PGP::Sign::MUNGE If this variable is set to a true value, PGP::Sign will automatically strip trailing spaces when signing or verifying signatures. This will make the resulting signatures and verification compatible with programs that generate attached signatures (since PGP ignores trailing spaces when generating or checking attached signatures). See the more extensive discussion of whitespace below. =back =head1 ENVIRONMENT =over 4 =item PGPPATH If $PGP::Sign::PGPPATH is set and $PGP::Sign::PGPSTYLE is something other than "GPG", PGP::Sign sets PGPPATH to tell PGP where to find its key rings. (GnuPG uses a command line argument instead.) =item TMPDIR The directory in which to create temporary files. Can be overridden by changing $PGP::Sign::TMPDIR. If not set, defaults F. =back In addition, all environment variables that PGP normally honors will be passed along to PGP and will likely have their expected effects. This includes PGPPATH, unless it is overridden (see above). =head1 DIAGNOSTICS Mostly the contents of @PGP::Sign::ERROR (returned by pgp_error()) are just the output of PGP. The exceptions are: =over 4 =item Execution of %s failed: %s We couldn't fork off a PGP process for some reason, given (at least as the system reported it) after the colon. =item No signature from PGP (command not found?) We tried to generate a signature but the output from the command we tried to run didn't contain anything that looked like a signature. One common explanation for this is that the path in $PGP::Sign::PGPS is invalid and that binary doesn't exist. =item %s returned exit status %d Some command that we ran, or tried to run, returned a non-zero exit status. %s will contain the exact binary name that PGP::Sign was attempting to run. =back =head1 BUGS PGP::Sign does not currently work with binary data, as it unconditionally forces text mode in PGP by using the C<-t> option. This is a high priority to fix, but I'd like to implement some sort of generic way of setting PGP options rather than just adding more entry points. There's no way of generating version four DSS signatures. This will be fixed by the same improvement that will fix the previous bug. PGP, all versions that I have available, behaves differently when generating attached signatures than when generating detached signatures. For attached signatures, trailing whitespace in lines of the data is not significant, but for detached signatures it is. This, combined with the fact that there's no way that I can see to get PGP to verify a detached signature without using files on disk, means that in order to maintain the intended default semantics of this module (manipulating detached signatures), I had to use temporary files in the implementation of pgp_verify(). PGP::Sign sets its umask before creating those temporary files and opens them with O_EXCL, but files may be left behind in the event that an application using pgp_verify() crashes unexpectedly. Setting $PGP::Sign::TMPDIR is recommended. Also, because of this incompatibility, you need to be aware of what the process checking the signatures you generate is expecting. If that process is going to turn your signature into an attached signature for verification (as pgpverify does for Usenet control messages), then you need to pre-munge your data to remove trailing whitespace at the ends of lines before feeding it to PGP. PGP::Sign will do that for you if you set $PGP::Sign::MUNGE to a true value. To add even more confusion to the mix, earlier versions of GnuPG followed an interpretation of RFC 2440 that specified text-mode signatures are performed against data with canonicalized line endings and with trailing whitespace removed (see section 5.2.1). There is no difference specified there between attached and detached signatures, and GnuPG treated them both the same. Versions of GnuPG at least after 1.0 appear to have changed to follow the PGP behavior instead. When verification of a signature fails, currently not very much information about what failed is available (since an invalid signature isn't considered an error in the pgp_error() sense). =head1 CAVEATS This module is fairly good at what it does, but it doesn't do very much. At one point, I had plans to provide more options and more configurability in the future, particularly the ability to handle binary data, that would probably mean API changes. I'm not sure at this point whether I'll get to that, or just replace this module with one that only uses GnuPG as I see no reason to use any other PGP implementation at this point and GnuPG has a much nicer programmatic interface. However, just in case, the interface to this module should not be considered stable yet; you may have to change your application when you upgrade to a newer version of this module. The README will list API changes. =head1 RESTRICTIONS PGP::Sign passes pass phrases to PGP via an open one-ended pipe, since this is the only secure method (both command line switches and environment variables can potentially be read by other users on the same machine using ps). This should be supported by any recent version of PGP; I have tested it against 2.6.2, 2.6.3i, 5.0, 6.5.2, GnuPG 0.9.2, and GnuPG 1.0.1. Implicit in this mechanism, though, is the requirement that the operating system on which you're running this module supports passing an open pipe to an exec()ed subprocess. This may cause portability problems to certain substandard operating systems. =head1 SEE ALSO pgp(1), pgps(1), pgpv(1), gpg(1) RFC 2440, L, which specifies the OpenPGP message format. The current version of this module is always available from its web site at L. =head1 AUTHOR Russ Allbery =head1 COPYRIGHT AND LICENSE Copyright 1997, 1998, 1999, 2000, 2002, 2004 Russ Allbery . This program is free software; you may redistribute it and/or modify it under the same terms as Perl itself. =head1 HISTORY Based heavily on work by Andrew Gierth and benefitting greatly from input, comments, suggestions, and help from him, this module came about in the process of implementing PGPMoose signatures and control message signatures for Usenet. PGPMoose is the idea of Greg Rose, and signcontrol and pgpverify are the idea of David Lawrence. Support for PGPPATH, the test suite, some bug fixes, and the impetus to get another version released came from Andrew Ford. Thank you. Original support for GnuPG from Todd Underwood and Monte Mitzelfelt. Code for using --status-fd based on code by Marco d'Itri. =cut PGP-Sign-0.20/MANIFEST0000644000175000000000000000063010613034124012706 0ustar eaglerootChangeLog data/message data/message.asc data/message.asc.v4 data/message.sig data/pubring.gpg data/pubring.pgp data/pubring.pkr data/secring.gpg data/secring.pgp data/secring.skr debian/changelog debian/compat debian/control debian/copyright debian/rules Makefile.PL makepm.PL MANIFEST This list of files META.yml Module meta-data (added by MakeMaker) README Sign.in t/basic.t t/locale.t TODO VERSION.pm PGP-Sign-0.20/TODO0000644000175000000000000000717710613034124012262 0ustar eagleroot PGP::Sign To-Do List Here's a list of things that have occurred to me that I'd like to see added to PGP::Sign at some point, in no particular order. As this is a module I can only work on in my free time, I won't get to implementing any of these things as quickly as I'd like. If you're interested in doing any of these, send me mail at rra@stanford.edu to let me know and then have at it! Patches gratefully accepted and will be noted in the README. Additions to this file are also welcome. * PGP::Sign currently hard-codes a bunch of flags to PGP to tell it to assume data is text. There should instead be a PGP::Sign::config() sub along the lines of Getopt::Long::config() where one can indicate what PGP options one wants to use. This would have the side effect of allowing PGP::Sign to work correctly with binary data. * The global variable interface to setting PGPSTYLE, PGPS, and PGPV should be replaced by that config mechanism as well. This means that configuration variables would have to take arguments, as in: PGP::Sign::config (style => 'PGP2'); so the interface to config should probably be hash-style. MUNGE should also be handled this way, and probably the other global variables as well while we're at it. * All of the information about a signature should be available, not just the key ID and whether or not it verified. It's a little tempting to make PGP::Sign return a queriable object here, but I'd rather stay away from the morass of turning this into OO.... * The second argument to pgp_verify() is utterly pointless, since no PGP implementation I'm aware of gives two hoots about the version header (nor should it). There *is*, however, need to supply PGP with user armor headers for the signature block, since I believe both Hash and Charset could change the operation of PGP. So pgp_verify() needs to be fixed so that you can pass it a hash of headers to add to the signature armor. * PGP::Sign should be extended to handle attached signatures as well, and to be able to hand back a signed document with an attached signature. This isn't even all that hard. * PGP::Sign currently does not deal correctly with tied arrays when processing input sources, due to using ref rather than UNIVERSAL::isa() to check the type of a source. This is tricky to fix without breaking Perl 5.003 compatibility, since 5.003 didn't have UNIVERSAL::isa(). I suppose one could check in the 5.004 branch where we look for IO::* stuff and have it be broken only for 5.003, or do a similar switch in several other places.... I don't think it works right with tied file handles right now either. * Information about why a signature verification failed isn't provided to the caller, and the additional parsable error tokens returned by GnuPG aren't taken advantage of. The caller should be able to get information about exactly why a signature verification failed (no public key found, bad signature, malformed data, etc.). And here's the really big one: * Despite all the disclaimers, there's really no reason why this couldn't be turned into a more general PGP module, at least to the extent of including support for encryption and decryption. Of course, the problem for me is that this then potentially puts it into export- controlled territories; the current implementation *only* does signing and verification and contains no hooks for encryption. I would be happy to work with someone else to tie this module into a larger framework, though, if someone wants to tackle the task of building a general Perl PGP module. PGP-Sign-0.20/t/0000755000175000000000000000000010614542010012020 5ustar eaglerootPGP-Sign-0.20/t/basic.t0000755000175000000000000001255010614506174013307 0ustar eagleroot# basic.t -- Basic tests for PGP::Sign functionality. -*- perl -*- # $Id: basic.t 173 2007-04-27 23:51:24Z eagle $ # Locate our test data directory for later use. my $data; for (qw(./data ../data)) { $data = $_ if -d $_ } unless ($data) { die "Cannot find PGP data directory\n" } $PGP::Sign::PGPPATH = $data; # Open and load our data file. This is the sample data that we'll be # signing and checking signatures against. open (DATA, "$data/message") or die "Cannot open $data/message: $!\n"; @data = ; close DATA; # The key ID and pass phrase to use for testing. my $keyid = 'testing'; my $passphrase = 'testing'; # Print out the count of tests we'll be running. BEGIN { $| = 1; print "1..14\n" } # 1 (ensure module can load) END { print "not ok 1\n" unless $loaded } use PGP::Sign; use FileHandle; $loaded = 1; print "ok 1\n"; # 2 (generate signature) my ($signature, $version) = pgp_sign ($keyid, $passphrase, @data); my @errors = PGP::Sign::pgp_error; print 'not ' if @errors; print "ok 2\n"; warn @errors if @errors; # 3 (check signature) my $signer = pgp_verify ($signature, $version, @data); @errors = PGP::Sign::pgp_error; print 'not ' if ($signer ne 'testing' || @errors); print "ok 3\n"; warn @errors if @errors; # 4 (check signature w/o version, which shouldn't matter) $signer = pgp_verify ($signature, undef, @data); @errors = PGP::Sign::pgp_error; print 'not ' if ($signer ne 'testing' || @errors); print "ok 4\n"; warn @errors if @errors; # 5 (check failed signature) $signer = pgp_verify ($signature, $version, @data, "xyzzy"); print 'not ' if ($signer ne '' || PGP::Sign::pgp_error); print "ok 5\n"; # 6 (whitespace munging) $PGP::Sign::MUNGE = 1; my @munged = @data; for (@munged) { s/\n/ \n/ } ($signature, $version) = pgp_sign ($keyid, $passphrase, @munged); $PGP::Sign::MUNGE = 0; print 'not ' if PGP::Sign::pgp_error; print "ok 6\n"; # 7 (check a signature of munged data against the munged version) $signer = pgp_verify ($signature, $version, @data); print 'not ' if ($signer ne 'testing' || PGP::Sign::pgp_error); print "ok 7\n"; # 8 (check signature of munged data against unmunged data with MUNGE) $PGP::Sign::MUNGE = 1; $signer = pgp_verify ($signature, $version, @munged); $PGP::Sign::MUNGE = 0; print 'not ' if ($signer ne 'testing' || PGP::Sign::pgp_error); print "ok 8\n"; # 9 (check signature of munged data against unmunged data w/o MUNGE) # Whether this signature verifies under GnuPG depends on the version of # GnuPG; GnuPG 1.0.2 and higher verify it, but GnuPG 1.0.1 doesn't. # Earlier versions do verify it. This is a disagreement over how to # handle trailing whitespace when verifying signatures. if ($PGP::Sign::PGPSTYLE eq 'GPG') { print "ok 9 # skip -- unreliable on GnuPG\n"; } else { $signer = pgp_verify ($signature, $version, @munged); print 'not ' if ($signer ne '' || PGP::Sign::pgp_error); print "ok 9\n"; } # 10 (take data from a code ref) my $munger = sub { local $_ = shift @munged; s/ +$// if defined; $_ }; $signature = pgp_sign ($keyid, $passphrase, $munger); print 'not ' if PGP::Sign::pgp_error; print "ok 10\n"; # 11 (check the resulting signature) $signer = pgp_verify ($signature, undef, @data); @errors = PGP::Sign::pgp_error; print 'not ' if ($signer ne 'testing' || @errors); print "ok 11\n"; warn @errors if @errors; # 12 (check an external PGP 2.6.2 signature, data from glob ref) if ($PGP::Sign::PGPSTYLE eq 'GPG') { print "ok 12 # skip -- GnuPG doesn't have IDEA\n"; } else { if (open (SIG, "$data/message.sig") && open (DATA, "$data/message")) { my @signature = ; close SIG; $signature = join ('', @signature[3..6]); $signer = pgp_verify ($signature, undef, \*DATA); close DATA; @errors = PGP::Sign::pgp_error; if ($signer ne 'R. Russell Allbery ' || PGP::Sign::pgp_error) { print "# Saw '$signer'\n"; print 'not '; } } else { print 'not '; } print "ok 12\n"; } # 13 (check an external version three DSA signature, data from array ref) if ($PGP::Sign::PGPSTYLE eq 'PGP2') { print "ok 13 # skip -- PGP 2 can't verify DSA signatures\n"; } else { if (open (SIG, "$data/message.asc")) { my @signature = ; close SIG; $signature = join ('', @signature[4..6]); $signer = pgp_verify ($signature, undef, \@data); @errors = PGP::Sign::pgp_error; if ($signer ne 'Russ Allbery ' || PGP::Sign::pgp_error) { print "# Saw '$signer'\n"; print 'not '; } } else { print 'not '; } print "ok 13\n"; } # 14 (check an external version four DSA signature, data from FileHandle) if ($PGP::Sign::PGPSTYLE ne 'GPG') { print "ok 14 # skip -- only GnuPG can verify version 4 signatures\n"; } else { if (open (SIG, "$data/message.asc.v4")) { my @signature = ; close SIG; my $fh = new FileHandle ("$data/message"); my $signer; if ($fh) { $signature = join ('', @signature[4..6]); $signer = pgp_verify ($signature, undef, $fh); @errors = PGP::Sign::pgp_error; } if ($signer ne 'Russ Allbery ' || PGP::Sign::pgp_error) { print "# Saw '$signer'\n"; print 'not '; } } else { print 'not '; } print "ok 14\n"; } PGP-Sign-0.20/t/locale.t0000755000175000000000000000704510614506174013470 0ustar eagleroot# locale.t -- Test for PGP::Sign in the presence of locale. -*- perl -*- # $Id: locale.t 173 2007-04-27 23:51:24Z eagle $ # Set the locale. I use French for testing; this won't be a proper test # unless the locale is available on the local system, so hopefully this will # be a common one. $ENV{LC_ALL} = 'fr_FR'; # Locate our test data directory for later use. my $data; for (qw(./data ../data)) { $data = $_ if -d $_ } unless ($data) { die "Cannot find PGP data directory\n" } $PGP::Sign::PGPPATH = $data; # Open and load our data file. This is the sample data that we'll be # signing and checking signatures against. open (DATA, "$data/message") or die "Cannot open $data/message: $!\n"; @data = ; close DATA; # The key ID and pass phrase to use for testing. my $keyid = 'testing'; my $passphrase = 'testing'; # Print out the count of tests we'll be running. BEGIN { $| = 1; print "1..7\n" } # 1 (ensure module can load) END { print "not ok 1\n" unless $loaded } use PGP::Sign; use FileHandle; $loaded = 1; print "ok 1\n"; # 2 (generate signature) my ($signature, $version) = pgp_sign ($keyid, $passphrase, @data); my @errors = PGP::Sign::pgp_error; print 'not ' if @errors; print "ok 2\n"; warn @errors if @errors; # 3 (check signature) my $signer = pgp_verify ($signature, $version, @data); @errors = PGP::Sign::pgp_error; print 'not ' if ($signer ne 'testing' || @errors); print "ok 3\n"; warn @errors if @errors; # 4 (check failed signature) $signer = pgp_verify ($signature, $version, @data, "xyzzy"); print 'not ' if ($signer ne '' || PGP::Sign::pgp_error); print "ok 4\n"; # 5 (check an external PGP 2.6.2 signature, data from glob ref) if ($PGP::Sign::PGPSTYLE eq 'GPG') { print "ok 5 # skip -- GnuPG doesn't have IDEA\n"; } else { if (open (SIG, "$data/message.sig") && open (DATA, "$data/message")) { my @signature = ; close SIG; $signature = join ('', @signature[3..6]); $signer = pgp_verify ($signature, undef, \*DATA); close DATA; @errors = PGP::Sign::pgp_error; if ($signer ne 'R. Russell Allbery ' || PGP::Sign::pgp_error) { print 'not '; } } else { print 'not '; } print "ok 5\n"; } # 6 (check an external version three DSA signature, data from array ref) if ($PGP::Sign::PGPSTYLE eq 'PGP2') { print "ok 6 # skip -- PGP 2 can't check DSA signatures\n"; } else { if (open (SIG, "$data/message.asc")) { my @signature = ; close SIG; $signature = join ('', @signature[4..6]); $signer = pgp_verify ($signature, undef, \@data); @errors = PGP::Sign::pgp_error; if ($signer ne 'Russ Allbery ' || PGP::Sign::pgp_error) { print 'not '; } } else { print 'not '; } print "ok 6\n"; } # 7 (check an external version four DSA signature, data from FileHandle) if ($PGP::Sign::PGPSTYLE ne 'GPG') { print "ok 7 # skip -- only GnuPG can verify version 4 signatures\n"; } else { if (open (SIG, "$data/message.asc.v4")) { my @signature = ; close SIG; my $fh = new FileHandle ("$data/message"); my $signer; if ($fh) { $signature = join ('', @signature[4..6]); $signer = pgp_verify ($signature, undef, $fh); @errors = PGP::Sign::pgp_error; } if ($signer ne 'Russ Allbery ' || PGP::Sign::pgp_error) { print 'not '; } } else { print 'not '; } print "ok 7\n"; } PGP-Sign-0.20/META.yml0000644000175000000000000000045210614542010013027 0ustar eagleroot# http://module-build.sourceforge.net/META-spec.html #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# name: PGP-Sign version: 0.20 version_from: VERSION.pm installdirs: site requires: distribution_type: module generated_by: ExtUtils::MakeMaker version 6.30_01 PGP-Sign-0.20/makepm.PL0000644000175000000000000001077110613035012013270 0ustar eagleroot# makepm.PL -- Builds PGP/Sign.pm from PGP/Sign.in. -*- perl -*- # $Id: makepm.PL 172 2007-04-23 04:46:02Z eagle $ # # The main reason why we have this script is to figure out where PGP is on # the system and code that and the PGP style to use into PGP::Sign before we # install the module. While we're at it, we also pull in our version number # from a separate file to give us some flexibility in release numbering. # Unbuffer output, since we'll be prompting. $| = 1; # First, grab the line to set the version number, since we'll need to # substitute that in to PGP/Sign.pm when we build it. It's the second line # of VERSION.pm. open (VERSION, 'VERSION.pm') or die "Cannot open VERSION.pm: $!\n"; ; my $version = ; close VERSION; # Search for PGP, prefering GPG, then PGP v6.5 or v2.6, then PGP v5.0. We # start by searching the user's PATH, and then check a few other standard # directories. We just look for the program used for signing, assuming the # program used for verification will be found in the same place. sub find_pgp { my @directories = map { s/^$/./; $_ } split (':', $ENV{PATH}); push (@directories, qw(/usr/local/bin /usr/bin /opt/bin)); my @programs = qw(gpg pgp pgp65 pgp6 pgps pgp2 pgp26 pgp263 pgp262); my $directory; for $directory (@directories) { next unless -d $directory; for (@programs) { my $program = "$directory/$_"; next unless -x $program; return $program; } } } # Used for heredocs to make them more readable. sub unquote { my ($string) = @_; $string =~ s/^: {0,7}//gm; $string } # We need to know PGPS (program used for signing), PGPV (program used for # verifying), and PGPSTYLE. First, check to see if a file named "paths" # exists; if so, this was given to Makefile.PL and we should just use those # values. Otherwise, we'll have to find it out for ourselves. if (-r './paths') { require './paths' } unless ($PGPV && $PGPS && $PGPSTYLE) { $PGPS = find_pgp; print unquote (<<'EOM'); : : PGP::Sign needs to know the path to PGP; this path will be encoded : in the installed module as the default path to PGP (it can be : overridden at runtime). Please enter the full path to the PGP : program you want to use to sign messages (if you are using version : 5.0 or 6.5, this should be the path to pgps) or just press Enter if : the guess is correct. : EOM $PGPS ||= '/usr/local/bin/pgp'; print "Program to sign data [$PGPS]: "; my $input = ; chomp $input; $PGPS = $input || $PGPS; if ($PGPS =~ m%pgps[^/]*$%) { ($PGPV = $PGPS) =~ s%pgps([^/]*)$%pgpv$1%; } else { $PGPV = $PGPS; } print "Program to verify signatures [$PGPV]: "; $input = ; chomp $input; $PGPV = $input || $PGPV; print unquote (<<'EOM'); : : PGP::Sign also needs to know what implementation of PGP you are : using. Acceptable values are "PGP2" for PGP 2.6 and workalikes : (this may also work for ViaCrypt PGP 4.0), "PGP5" for PGP 5.0 and : workalikes, "PGP6" for PGP 6.0 and workalikes, or "GPG" for GnuPG. : Please enter one of those possible values or just press Enter if : the guess is correct. : EOM { if ($PGPS =~ m%pgps[^/]*$%) { $PGPSTYLE = 'PGP5' } elsif ($PGPS =~ m%gpg[^/]*$%) { $PGPSTYLE = 'GPG' } else { my $version = `$PGPS 2>&1`; if ($version =~ /Pretty Good Privacy.* 6\./) { $PGPSTYLE = 'PGP6'; } else { $PGPSTYLE = 'PGP2'; } } print "PGP style [$PGPSTYLE]: "; my $input = ; chomp $input; $PGPSTYLE = uc ($input || $PGPSTYLE); unless ({PGP5 => 1, PGP6 => 1, GPG => 1, PGP2 => 1}->{$PGPSTYLE}) { print "\nUnknown PGP style '$PGPSTYLE'\n\n"; redo; } } print "\n"; } # Paranoia. for ($PGPS, $PGPV, $PGPSTYLE) { s/\\/\\\\/g; s/\'/\\\'/g } # Now, open our input file and create our output file, and then do the # necessary substitutions. open (IN, 'Sign.in') or die "Cannot open Sign.in: $!\n"; open (OUT, '> Sign.pm') or die "Cannot open Sign.pm: $!\n"; while () { if (/^\# @@ VERSION$/) { print OUT $version } elsif (/^\# @@ PGPS$/) { print OUT "\$PGPS = '$PGPS';\n" } elsif (/^\# @@ PGPV$/) { print OUT "\$PGPV = '$PGPV';\n" } elsif (/^\# @@ PGPSTYLE$/) { print OUT "\$PGPSTYLE = '$PGPSTYLE';\n" } else { print OUT } } close OUT; close IN; PGP-Sign-0.20/ChangeLog0000644000175000000000000002313610614506333013344 0ustar eagleroot2007-04-27 Russ Allbery * VERSION.pm: PGP::Sign 0.20 released. * t/basic.t: Add reasons for the skipped tests. * t/locale.t: Likewise. * t/pod.t: New check for POD formatting. 2007-04-22 Russ Allbery * makepm.PL: Unbuffer output since we're prompting the user. 2004-08-08 Russ Allbery * VERSION.pm: PGP::Sign 0.19 released. * Sign.in: Remove e-mail addresses from HISTORY since the documentation is automatically put on the web. * test.pl: Moved to... * t/basic.t: ...here. Updated the search for the data directory accordingly. Print more information when detached signatures fail to verify. * t/locale.t: New test. * Sign.in (pgp_verify): Replaced verification code for GnuPG with code that uses --status-fd, so that it will work independent of locale. Documented limitations in the error reporting and recommended setting TMPDIR. 2004-08-04 Russ Allbery * VERSION.pm: PGP::Sign 0.18 released. * debian/changelog: Add Debian packaging files. * debian/compat: Likewise. * debian/control: Likewise. * debian/copyright: Likewise. * debian/rules: Likewise. * Makefile.PL: Also remove trustdb.gpg; GnuPG generates it automatically and the copy we were distributing contained nothing of interest. * data/trustdb.gpg: Delete. 2002-06-28 Russ Allbery * VERSION.pm: PGP::Sign 0.17 released. * Sign.in: Update CAVEATS to be slightly less optimistic about the chances of a major overhaul. Add a URL for RFC 2440 and this module's web site. Add a COPYRIGHT AND LICENSE section. Update the markup in the documentation. 2000-10-08 Russ Allbery * test.pl: Skip test 9 completely under GnuPG, as the whitespace behavior changes from release to release; GnuPG 1.0.2 is back to the previous behavior of releases before GnuPG 1.0.1. * Makefile.PL: Added random_seed to @clean, created by GnuPG 1.0.2. 2000-02-12 Russ Allbery * VERSION.pm: PGP::Sign 0.16 released. * Makefile.PL: Clean up all the additional junk created in data by running the test suite with PGP 6.5. * makepm.PL: Also look for PGP 6.5, distinguish between PGP 2 and PGP 6 by checking its output when run without any arguments, and add the PGP6 PGPSTYLE. * Sign.in: Added a waitpid() in pgp_verify() to avoid leaving zombies behind. Updated comments and documentation for the new support for PGP 6.5.2 and for the change to GnuPG so that it does the same whitespace munging as PGP. 2000-02-06 Russ Allbery * test.pl: The signature in test 9 now expected to fail on all versions of PGP, as the release GnuPG was changed to follow PGP in its handling of whitespace. 1999-06-13 Russ Allbery * VERSION.pm: PGP::Sign 0.15 released. * Sign.in: Added a call to fcntl() to clear close-on-exec on the passphrase pipe in pgp_sign(), needed for Perl 5.005_03. Added a note to the documentation that PGP may want to write randseed.bin in its key ring directory. * Makefile.PL: Sign.in and Sign.pm moved to the root directory, updated ABSTRACT. * makepm.PL: Sign.in and Sign.pm moved to the root directory. 1999-02-10 Russ Allbery * VERSION.pm: PGP::Sign 0.14 released. * PGP/Sign.in: Use long options with GnuPG rather than -bat, add --force-v3-sigs so that generated signatures will be compatible with PGP 5.0, and added documentation of this. * makepm.PL: Search for gpg and pgps as well, set both PGPS and PGPV with prompts and guesses for each, prompt for and set PGPSTYLE, and pick up overrides to avoid interactivity from a file rather than from the command line. * Makefile.PL: Added support for PGPS, PGPV, and PGPSTYLE settings on the command line, changed to guess a few things if not specified and to pass values to makepm.PL via a separate file rather than the command line. Ugly hack to fix Makefile dependencies removed, since it's no longer necessary. 1999-02-09 Russ Allbery * test.pl: Changed the testing key ID to "testing", added special casing on PGPSTYLE for testing signatures of whitespace-munged data against unmunged data since GnuPG will still consider the signature valid, added two new tests for version 3 and version 4 DSS signatures, and had GnuPG skip the PGP 2.6.2 RSA signature check. * PGP/Sign.in: Added support for GnuPG and PGP 5.0. This involves a new PGPSTYLE global variable, support for separate programs for signing and verification, and lots of choosing between styles all over the code. The documentation has also been updated to reflect this support, including a long note about whitespace munging incompatibilities between different versions and warnings about potential future API changes for this module. Also added a SEE ALSO section and a thank you to the folks who send in GnuPG support originally. * data/message.asc.v4: New file. Version 4 DSS signature. * data/message.asc: New file. Version 3 DSS signature. * data/pubring.gpg: New file. GnuPG key ring for testing. * data/secring.gpg: New file. * data/trustdb.gpg: New file. * data/pubring.pkr: New file. PGP 5.0 key ring for testing. data/secring.pkr: New file. * data/message.sig: Renamed from message.asc; this is the PGP 2.6.2 RSA signature. * data/pubring.pgp: Change key ID of test key to testing, since GPG requires at least five characters in the key ID. data/secring.pgp: Likewise. 1998-12-04 Russ Allbery * VERSION.pm: PGP::Sign 0.13 released. * Makefile.PL: Add two ugly hacks, one to let someone set the path to PGP on the command line of "perl Makefile.PL," and the second to strip the resulting extra dependency from the processPL section. Pass the path to PGP to makepm.PL on the command line if it's given. * makepm.PL: Add support for accepting the path to PGP on the command line (and not prompting in that case). 1998-12-02 Russ Allbery * VERSION.pm: PGP::Sign 0.12 released. * makepm.PL: The path to PGP that the user inputs should override any other path to PGP that we find. 1998-11-27 Russ Allbery * VERSION.pm: PGP::Sign 0.11 released. * Makefile.PL: Added a MAN3PODS directive to prevent MakeMaker from generating a PGP::PGP::Sign man page, changed the formatting of the 5.005-only section. 1998-11-26 Russ Allbery * Makefile.PL: Added ABSTRACT and AUTHOR for Perl versions 5.005 and higher. This is for the PPD to go with a binary distribution, and for Perl Resource Kits. * VERSION.pm: PGP::Sign 0.10 released. * PGP/Sign.in: Modified to be PGP/Sign.in instead of Sign.pm, added special markers for the path to PGP and the version number, added support for $PGPPATH, fixed a bug in finding the PGP version number of a signature, cleaned up and reformatted the documentation, added a note about PGP environment variables, added bugs concerning our lack of support for PGP v5 and GPG, added a thank you to Andrew Ford in the history section of the documentation. * Makefile.PL: Run makepm.PL to generate PGP/Sign.pm, tell MakeMaker where the actual module is, and get our version number from VERSION.pm now. * makepm.PL: New file. Now generate PGP/Sign.pm automatically from this file, which finds and prompts for the path to PGP and grabs the version from VERSION.pm. * VERSION.pm: New file. We now pull our release version number from here rather than the CVS revision of Sign.in. * test.pl: New file. Added a reasonably good test suite that works with public and private key rings included with the distribution. Based on work by Andrew Ford. * data/message: New file. * data/message.asc: New file. * data/pubring.pgp: New file. * data/secring.pgp: New file. 1998-07-05 Russ Allbery * Sign.pm: PGP::Sign 0.9 released. * Sign.pm: Fixed the way I was dealing with open3() file handles and $?. One needs to keep the PID and do an explicit waitpid(), or the status you get may be something random. Also cleaned things up a little and explicitly set $/ in case our calling program had it set to something odd. 1997-08-18 Russ Allbery * Sign.pm: PGP::Sign 0.8 released. * Sign.pm (pgp_verify): Added a umask 077 (and restoration of umask on completion) since we're creating temporary files. (pgp_sign): Added a check to see if we got a signature at all. 1997-08-15 Russ Allbery * Sign.pm: PGP::Sign 0.7 released. * Sign.pm (pgp_verify): Changed to use O_EXCL when opening /tmp files to avoid symlink attacks. * Sign.pm: PGP::Sign 0.6 released. * Sign.pm: Added output() to munge trailing spaces if $MUNGE is set, modified write_data() to send everything through output() rather than printing it directly, added documentation of the new behavior to the PODs. 1997-07-29 Russ Allbery * Sign.pm: Removed $ORS, which was a hack that we don't need any more. That work should be done by the client, and the client is capable of it. Added a pgp_error() function (not exported by default) to retrieve the error message, since that's a cleaner user interface. Changed the signature verification code to verify detached signatures, which means we now use temporary files. Added a $TMPDIR global variable to specify the directory in which to create temporary files. Changed the documentation to include notes about all of this. 1997-07-27 Russ Allbery * Sign.pm: Broke write_data() off into a separate function, added pgp_verify() and tested it, changed the documentation to mention it as well. Fixed a few minor bugs, made to use @ERROR correctly, added documentation. PGP-Sign-0.20/README0000644000175000000000000002633310614541715012457 0ustar eagleroot PGP::Sign version 0.20 (Create and verify detached PGP signatures for data) Copyright 1997, 1998, 1999, 2000, 2002, 2004, 2007 Russ Allbery . This program is free software; you may redistribute it and/or modify it under the same terms as Perl itself. INTRODUCTION One important thing to clear up right away: This is not a general PGP module. For wonderful general PGP modules that will encrypt, decrypt, manage key rings, slice, dice, fold, spindle, and mutilate your data, see the PGP by-module directory at your local CPAN mirror; hopefully there will be one there. This module sprung out of a need to do one thing and one thing only, do it securely, and do it well. This module creates and checks detached signatures for data. That's it. If you want to do anything else that PGP lets you do, look elsewhere. Currently this module only works with text data. Support for binary data is high on the list of features I want to add. The original purpose of this module was to factor out common code in a News::Article class written by Andrew Gierth that did PGPMoose signatures and signed control messages. It should now be possible to reimplement PGPMoose, signcontrol, and pgpverify using this module, and the second and parts of the first have already been done. So much for the "one thing only" part. For the "do it securely" part, this module uses a pipe to pass the secret key password to PGP, rather than a command line flag or an environment variable as seen in other modules. Both of those are subject to snooping by other users; this approach isn't. For the "do it well" part, the interface to this module takes every form of data known to man. Scalars and arrays are no problem, of course, but if you give it a reference to an array, it'll walk the array to avoid making a copy of a potentially large data structure. You can also give it an open file (in the form of a glob, a reference to a glob, a FileHandle object, an IO::Handle object, or anything derived from either) and it'll walk that too. Or you can give it a reference to a scalar if you really want to and it's cool with that. Or, if you want to get really exciting, you can give it a reference to a sub and it'll call the sub repeatedly to get more data until the sub returns undef. Perfect for walking some complex data structure you don't want to make an internal copy of. And if there's any other interesting data structure you want to throw at it, tell me about it, and the next version will probably support that too. This module supports a wide variety of different versions of PGP, from PGP 2.6.2 to PGP 5.0 to PGP 6.5 to the new (and very nice) GnuPG. Different implementations of PGP are capable (and not capable) of creating and checking various types of signatures; obviously, what this module can do is limited by what versions of PGP you have installed. See the documentation for all the gory details, which really aren't that gory. At least yet. REQUIREMENTS This module requires a version of PGP that supports PGPPASSFD or some other mechanism for handing the passphrase over in a pipe. 2.6.2, 2.6.3i, 5.0, 6.5, and GnuPG all do. I can't personally vouch for any other version, but I believe ViaCrypt PGP 4.0 may also work (since it's largely based on 2.6.2). This module also requires an operating system that's capable of coping with pipes, forking, and passing file descriptors through an exec(). If your operating system can't, that's considered by this module author to be a bug in your operating system and not in this module. I've personally tested or received reports of clean tests of this module with the following versions of PGP: PGP 2.6.2 (US version) PGP 2.6.2i PGP 5.0 (US Linux freeware version) PGP 6.5.2 (US Solaris freeware version) GnuPG 0.9.2 (Linux and Solaris) GnuPG 1.0.1 (Solaris) GnuPG 1.0.6 (Solaris) GnuPG 1.2.1 (Linux) GnuPG 1.2.2 (FreeBSD and OpenBSD) GnuPG 1.2.4 (Linux) GnuPG 1.4.6 (Linux) If you successfully use this module with another significant version of PGP not listed above, please let me know. This module requires no other modules besides IPC::Open3 and FileHandle, both of which are part of Perl core and have been for some time. It should work with Perl 5.003 or later, although I personally have only tested it with Perl 5.004_04, 5.005_03, 5.6.1, 5.8.0, 5.8.4, and 5.8.8. INSTALLATION Follow the standard installation procedure for Perl modules, which is to type the following commands: perl Makefile.PL make make test make install You'll probably need to do the last as root unless you're installing in your own private modules directory. In order for make test to succeed if you're using GnuPG and egd (the entropy daemon), you may have to make a symlink from data/entropy to the entropy socket in your ~/.gnupg directory. When you run make, you will be prompted for the path to the program to create signatures and the program to verify signatures. PGP::Sign will try to guess at what you may want to use, preferring GnuPG and then PGP 5.0. For GnuPG, PGP 2.6, or PGP 6.5, both paths should point to the same program; for PGP 5.0, pgps is the program that generates signatures and pgpv is the program that verifies them. Don't set the signing program and the verifying program to mutually incompatible things, or you'll get strange results. You will also be prompted for what PGP style to default to, since each PGP implementation works slightly differently. This has to be one of the following: "PGP2" for PGP 2.6 workalikes, "PGP5" for PGP 5.0 and workalikes, "PGP6" for PGP 6.5 and workalikes, or "GPG" for GnuPG. Again, PGP::Sign will try to guess from the name of the binaries you chose (and distinguish between PGP2 and PGP6 based on the output of the program when run without any arguments). If you have multiple versions of PGP installed on your system, you still have to pick one to be the default. You'll be able to switch between PGP programs and PGP styles at runtime; see the PGP::Sign documentation for details. If you want to avoid the prompt for the path to PGP, you can, instead of the first line, type: perl Makefile.PL PGP=/path/to/pgp and then /path/to/pgp will be used as the path to PGP (both signing and verification) and you won't be prompted. When invoked this way, Makefile.PL will attempt to figure out what PGP style you're using from the name of the binaries. You can set it specifically with something like: perl Makefile.PL PGP=/usr/local/bin/gpg PGPSTYLE=GPG if you need to. If the signing program and verifying program are different, set PGPS and PGPV instead of just PGP. For example: perl Makefile.PL PGPS=/usr/local/bin/pgps PGPV=/usr/local/bin/pgpv If you want to install PGP::Sign in somewhere other than the default installation location, you can set PREFIX or LIB on the Makefile.PL command line. See the ExtUtils::MakeMaker documentation for more details. TESTING There is a small test suite that uses the files in data to make sure that signing and checking of signatures work. This test suite uses the key rings and data in the data subdirectory of the distribution, and should work correctly under any of the supported versions of PGP. To run the test suite, type: make test after running make. Regardless of your PGP style, at least one test will be skipped, since PGP::Sign knows how to test RSA signatures (PGP 2.6, PGP 5.0, and PGP 6.5), DSS version three signatures (PGP 5.0, PGP 6.5, and GnuPG), and DSS version four signatures (GnuPG only), and no one PGP implementation can handle all three (unless your GnuPG installation includes RSA support). For some reason, the test suite fails the first time it's run with PGP 6.5 (at least on Solaris), giving error messages about not having enough random bits, and then succeeds the second time. I consider this to be a bug in PGP 6.5, as no other version of PGP has this problem. Note that different PGP implementations return different things and therefore the test suite looks for different things depending on what your PGP style is set to. See the PGP::Sign documentation for an extended discussion of issues related to trailing whitespace, and see the comments in test.pl for information on exactly what's being tested. More tests are welcome, particularly if you find a bug or if they test some major functionality of this module not currently covered. THANKS To Andrew Gierth for the inspiration and motivation to write this and the reminder that PGPPASSFD existed, for being one of the two people who caught the mistake I made with $? and open3(), and for pointing out a missing waitpid() in pgp_verify() that was causing zombies. To Jon Ribbens for pointing out that $? isn't guaranteed to contain the exit status of something called from open3() unless you do a waitpid() for it first. To Andrew Ford for adding PGPPATH support and adding a test suite and code in Makefile.PL to search for an installed version of PGP. To Todd Underwood for the impetus to get this module working under GnuPG and PGP 5.0, and to he and Monte Mitzelfelt for the initial GnuPG implementation that I based mine on. To Lupe Christoph for pointing out that Perl 5.005_03 sets close-on-exec on file handles created by pipe, requiring an fcntl() call in PGP::Sign to unset that. To J. Porter Clark for information about the socket needed for GnuPG with egd support. To Marco d'Itri for example code on how to use the GnuPG --status-fd support, so that parsing of the human-readable output of GnuPG isn't needed, and to Autrijus Tang for reminding me that I'd not yet pulled that code over from pgpverify. To David Lawrence and Greg Rose for signcontrol and PGPMoose respectively, the motivating applications. To Phil Zimmermann, because Phil should be listed in the thank you list for anything related to PGP, given that he wrote it and went through legal hell to make sure we still had it available. To Werner Koch for GnuPG, which is much nicer than any other PGP implementation I've worked with and is free to boot, and for pointing me at the right sections of RFC 2440 to explain the OpenPGP standard on whitespace munging in text signatures. CONTACTING ME AND CONTRIBUTIONS Send any comments, bug reports, feature requests, flames, thank yous, offers of vast quantities of money, lutefisk, and large green Martian dogs named Ralf to rra@stanford.edu. :) Please allow at least a month for me to respond to mail regarding this module. I get at *least* 1,000 mail messages a day, and I'm afraid this module is something that I only get a chance to work on once every few months. I do intend to continue to maintain it, however, and I will get back to you eventually. Contributions are welcome! I will not have enough time to add everything I want to add to this module, but I tend to be sparked into bursts of creativity and programming energy when sent new ideas or patches, even partial ones. If you're interested in contributing, please read TODO first. Enjoy! PGP-Sign-0.20/Makefile.PL0000644000175000000000000000634110613034124013534 0ustar eagleroot# Makefile.PL for PGP::Sign module -*- perl -*- # $Id: Makefile.PL 145 2004-08-05 05:27:39Z eagle $ use ExtUtils::MakeMaker; # The build process for PGP::Sign normally will attempt to find programs to # use for signature generation and verification and will set PGPSTYLE based # on what programs are found. We want to allow people to override that # earlier and without requiring interaction, though, so we allow four # additional command line options. We have to pull them out of @ARGV before # handing things over to WriteMakefile(), since otherwise MakeMaker will # complain about them. # # PGP sets both PGPS and PGPV to the same value; PGPS and PGPV can also be # set seperately for separate signing and verification programs. my ($pgps, $pgpv, $pgpstyle); @ARGV = map { if (/^PGP=(.*)/) { $pgps = $pgpv = $1; () } elsif (/^PGPS=(.*)/) { $pgps = $1; () } elsif (/^PGPV=(.*)/) { $pgpv = $1; () } elsif (/^PGPSTYLE=(.*)/) { $pgpstyle = $1; () } else { $_ } } @ARGV; if ($pgps && !$pgpv) { die "Must set PGPV if PGPS is set\n"; } elsif ($pgpv && !$pgps) { die "Must set PGPS if PGPV is set\n"; } # If either PGP or PGPS and PGPV are set, and PGPSTYLE isn't, we try to # figure out PGPSTYLE from the program names. We just base this on the name # of the executable used for signing, which should be reasonably reliable. # If this check fails, people can always set it themselves. Note that this # incorrectly detects PGP v6 as PGP v2; this is based on my assumption that # PGP v2 is still more commonly installed. if ($pgps && !$pgpstyle) { if ($pgps =~ m%pgps[^/]*$%) { $pgpstyle = 'PGP5' } elsif ($pgps =~ m%gpg[^/]*$%) { $pgpstyle = 'GPG' } else { $pgpstyle = 'PGP2' } } # Paranoia. for ($pgps, $pgpv, $pgpstyle) { s/\\/\\\\/g; s/\'/\\\'/g } # If any of these are set, write out the results to paths for makepm.PL to # pick up. if ($pgps) { open (PATHS, '> paths') or die "Can't create file 'paths': $!\n"; print PATHS "# Automatically generated PGP::Sign configuration\n"; print PATHS "\$PGPS = '$pgps';\n"; print PATHS "\$PGPV = '$pgpv';\n"; print PATHS "\$PGPSTYLE = '$pgpstyle';\n"; close PATHS; } # Files that should be removed on make clean, generated by running make test # with various versions of PGP. my @clean = map { 'data/' . $_ } qw(PGPMacBinaryMappings.txt PGPgroup.pgr PGPsdkPreferences pgp.cfg random_seed randseed.bin randseed.rnd pubring-bak-1.pkr secring-bak-1.skr trustdb.gpg); # Now actually build the Makefile. WriteMakefile ( NAME => 'PGP::Sign', DISTNAME => 'PGP-Sign', ($] >= 5.005 ? (ABSTRACT => 'Create and verify PGP/GnuPG signatures, securely', AUTHOR => 'Russ Allbery (rra@stanford.edu)') : ()), PL_FILES => { 'makepm.PL' => 'Sign.pm' }, PM => { 'Sign.pm' => '$(INST_LIBDIR)/Sign.pm' }, VERSION_FROM => 'VERSION.pm', clean => { FILES => "@clean" }, dist => { COMPRESS => 'gzip', SUFFIX => 'gz' }, realclean => { FILES => 'Sign.pm paths' } );