eoPh has asked for the wisdom of the Perl Monks concerning the following question:

First off, I'm fairly new to perl, so please don't crucify me for bad coding practice, etc. My problem is as such: I've got a script that takes in data from an html form, dumps a feild to a file, and executes gpg to encrypt it. I can dump to file, but it doesn't seem that the encryption is working... It works if I run the script locally on the machine (even as the nobody user, which apache uses to run the script), but not as the CGI. Any ideas?
#!/usr/bin/perl $gpgpath = "/usr/bin/gpg"; $gpguser = "xxxxxxxx\@xxxxxxxxx.com"; print "Content-Type: text/html\n"; print "<html>\n<body>\n"; $stdin = <STDIN>; $stdin =~ s/\+/ /g; %form = split(/=|&/, $stdin); $filenum = int(rand 50) + 1; open(OUTMESSAGE, ">tmpMessages/$filenum"); while (($name, $value) = each %form) { $value =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg; $form{"$name"} = $value; } print OUTMESSAGE $form{'body'}; close OUTMESSAGE; $gpgcommand = "$gpgpath --batch --always-trust --eatr -a -r $gpguser - +o tmpMessages/$filenum.enc -e"; print $gpgcommand; print `$gpgcommand`; print "</body>\n</html>\n";
when executed, the $gpgcommand is printed out, and works if I cut-and-paste the command into a terminal, but not through the perl script. Is this maybe an apache configuration issue?

Replies are listed 'Best First'.
(ichi) Re: CGI won't execute GPG properly...
by ichimunki (Priest) on Jun 06, 2002 at 18:02 UTC
    I am required to mention that you might consider programming Perl with #!/usr/bin/perl -w, use strict, and (in this case) use CGI. These may make your life easier in the future.

    But to your immediate question, why don't you try writing a quick command-line-only version of this? Example:
    #!/usr/bin/perl -w use strict; my $gpgpath = "/usr/bin/gpg"; my $gpguser = "xxxxxxxx\@xxxxxxxxx.com"; my $filenum = 'set_to_test_path'; $gpgcommand = "$gpgpath --batch --always-trust --eatr -a -r $gpguser - +o tmpMessages/$filenum.enc -e"; print $gpgcommand, "\n"; my $gpgresults = `$gpgcommand`; print $gpgresults, "\n";
    That way Apache isn't interfering. You can also test your CGI scripts from a command line (so that Apache configuration is not the issue), by running this with perl script.pl. You will have to enter any form information by hand key=value and press return, then this will dump output to STDOUT. Either of these methods will allow you to see the warnings (provided you add -w to your shebang line), which may be very informative. Don't forget to execute these using the same login that the Apache process will have.
      thanks, the strict and -w are probably a good idea :] (like I said, I'm new to perl)

      after making the minor modifications, I realized that the user executing the script was 'apache', not 'nobody', but even being that user doesn't seem to help. Executing the script on the command line works fine, but still a no-go through a browser

      thanks for the help, though
Re: CGI won't execute GPG properly...
by cLive ;-) (Prior) on Jun 06, 2002 at 21:36 UTC

    When you run it in the shell, the HOME dir is yours. When you run it through the server, it probably isn't.

    If you insist on doing it manually, you should add the homedir to the gpg command:

    $gpgcommand = "$gpgpath --batch --homedir=/path/to/your/homedir --alwa +ys-trust --eatr -a -r $gpguser -o tmpMessages/$filenum.enc -e"

    Or you may be able to get away with just setting the $ENV{GNUPGHOME} variable - sorry, I can't remember :)

    But, are there any reasons you're not using the GnuPG and CGI modules?

    #!/usr/bin/perl -w use strict; use CGI; use GnuPG; my $gnupg = new GnuPG(homedir => '/path/to/home/dir', gnupg_path => '/rath/to/gpg'); # yadda yadda # and then encrypt someting like this (grabbed from docs, amend to sui +t...) $gpg->encrypt( plaintext => "file.txt", output => "file.gpg", armor => 1, sign => 1, passphrase => $secret);

    .02

    cLive ;-)

    --
    seek(JOB,$$LA,0);

Re: CGI won't execute GPG properly...
by Aristotle (Chancellor) on Jun 06, 2002 at 19:26 UTC

    In what way does it "not work"? Are there any error messages in any logs? That is where any output on STDERR would end up in. Do you get a 500 server error? If not, what do you see? Have you looked into the HTML source to check exactly what the script produces? Have you checked the values of $? (child process error) and $! (OS function error) to see if GPG tried to signal an error to its caller?

    I'm sure there's a few more places to look which I forget in this off the top of my head listing, but that should suffice to begin with. :-)

    Finally, you might want to add use CGI::Carp qw(fatalsToBrowser warningsToBrowsers); during development. (But remove the fatalsToBrowser warningsToBrowsers parameters once the script is publically accessible - it is none of your visitors' business why your script broke, if it did.) See Ovid's CGI course for a good beginner's resource on CGI programming.

    Makeshifts last the longest.