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

I need to PGP encrypt a parameter from the querystring. The command to run on my system is:
/usr/bin/gpg -ea --always-trust -r user\@domain.com
, but the answer (if anyone has one!) should be the same for any command.

I want to set the output of this command to another variable, like this:
$encStr = `echo $plainStr | /usr/bin/gpg -ea --always-trust -r ken\@ra +ndys.com`;
This works great from the command line, but when I run it via the web, I get nothing. Any ideas? The entire thing is below...
#!/usr/bin/perl use CGI("param"); print "Content-Type: text/html\n\n"; print "<html>\n<body>\n"; $plainStr = param("plainStr"); $encStr = `echo $plainStr | /usr/bin/gpg -ea --always-trust -r user\@d +omain.com`; print "Encrypted String = $encStr"; print "\n</body>\n</html>";
THANKS!!!

Replies are listed 'Best First'.
Re: Get output from an external program
by BazB (Priest) on Jan 18, 2002 at 02:52 UTC

    Have a look at Use strict warnings and diagnostics or die and perlman:perlsec.
    Read up on taint mode.
    Read Ovid's CGI tutorial - there is a link on his homenode.

    I know that you're trying to do this by calling gpg directly, but you might also want to have a look at CPAN, there is a GnuPG::Interface module. The docs appear quite good.
    (Update: There is also the Crypt::PGP5 module if your final target system only has PGP available. Even more impressive is the Crypt::OpenPGP module that arhuman recently mentioned).

    There are a number of small errors in your code - have another look at perldoc CGI.
    Also, if you're going to use CGI, you're as well using more/all of it's functionality.

    Start with:

    #!/usr/bin/perl -wT #use warnings and use taint mode. use strict; use CGI qw/:standard/; use GnuPG::Interface; my $q = new->CGI; my $tainted_plain_str = $q->param('plainStr'); my $plain_str = # insert code to untaint $tainted_plain_str print $q->header; print $q->start_html('A webpage'); # Do your stuff with GnuPG::Interface. # Print out your encrypted string. print $q->end_html;

    Note, I've not been doing this all that long, so check the code I've posted - it's untested.

    If you're sufficiently concerned about you data that you're going to be encrypting it with something like GPG, then you should be paranoid when it comes to coding this script (if you absolutely have to do things this way).
    There are plenty nodes about security: Think beyond Taint and warnings, Stay aware of security and (OT) Security Rant are all good starters. Use Super Search to look for nodes relating to CGI, PGP/GPG and the like.

    Hope it helps.

    BazB.

    Update: Added more nodes and a suggestion that sometimes paranoia can be a Good Thing(tm).

Re: Get output from an external program
by metadoktor (Hermit) on Jan 18, 2002 at 05:34 UTC
    BazB has listed some good advice (you should also make sure that you regex your input!!! someone could easily crack your script by passing it special chars) but to answer your specific question about not being able to run the command you may have a problem with permissions. CGI programs tend to run as nobody or as www (if an admin sets things up that way). Check to see if your pgp program has permissions which are accessible to your CGI script. Also you may want to ensure that your echo command is fully qualified as /usr/bin/echo. As another measure to test your program, you may want to simply run the gpg command with a string of your own thus excluding the echo command to make things as simple as possible.

    metadoktor

    "The doktor is in."

Re: Get output from an external program
by dmmiller2k (Chaplain) on Jan 18, 2002 at 08:46 UTC

    Both BazB and metadoktor give good advice.

    I had another thought. This may not be your problem but here it is anyway. When you capture the output of a command using backticks, only STDOUT is captured, not STDERR. In a CGI program, STDERR goes into the web server's errorlog. You can capture both STDOUT and STDERR (intermingled) in the same stream by appending '2>&1' to the command.

    $encStr = `echo $plainStr | /usr/bin/gpg -ea --always-trust -r user\@d +omain.com 2>&1`;

    dmm

    If you GIVE a man a fish you feed him for a day
    But,
    TEACH him to fish and you feed him for a lifetime
Re: Get output from an external program
by jholtzman (Initiate) on Jan 23, 2002 at 14:51 UTC
    Thanks BazB and metadoktor for your advice. As you can probably tell, I am no perl monk... I'd rather live my life in Java-land, but not all web servers are build alike (no choice for this project - it's got to be perl)! Can I install perl modules, specifically GPG::Interface, as a normal (non-root) user? I tried just dumping the .pm files in my cgi-bin, but that didn't work... Thanks again, JMH