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

I'm having issues in a CGI::Application app i've written (where the bulk of code is in a .pm file, and an instance script uses it). in the application, i grab a username and password from a cookie, then run an external command (a C program) to authenticate the user/pass, like so:
sub do_auth_check { # get self object and CGI query object my $self = shift; my $q = $self->query(); # get user info from cookies my($uname,$pwd) = ( $q->cookie('username'), $q->cookie('password') ) +; warn($uname.':'.$pwd); # DEBUG use only # build command my $com = 'env QUERY_STRING=username='.$uname.'\;password='.$pwd.' / +usr/bin/custom_auth_tool'; warn('running command "'.$com.'"'); # DEBUG use only # run command through a pipe open(WEBOS,"$com|"); $com = join('', <WEBOS>); close(WEBOS); # remove newlines (should also take care of tainting, IIRC) $com =~ s/\x0D?\x0A//g; warn('ran command "'.$com.'"'); # DEBUG use only return $com; }
authentication doesnt work, however, and in the error log, i get this:
evan:password at AppTest.pm line 554. running command "env QUERY_STRING=username=evan\;password=password /us +r/bin/custom_auth_tool" at AppTest.pm line 561. ran command: "" at AppTest.pm line 566.
so, the command seems to output a blank string, which i would normally attribute to permissions, but if I run the following script:
#!perl use strict; use CGI; my $q = new CGI; my $uname = $q->cookie('username'); my $pwd = $q->cookie('password'); my $com = 'env QUERY_STRING=username='.$uname.'\;password='.$pwd.' /us +r/bin/custom_auth_tool'; print "Content-Type: text/plain\n\n", "Command:\n$com\n\n"; open(WEBOS,"$com|"); $com = join('', <WEBOS>); close(WEBOS); print "Result:\n$com\n\n";
this works, and i get the following:
Command: env QUERY_STRING=username=evan\;password=password /usr/bin/custom_auth +_tool Result: user evan authenticated
i thought perhaps it was because the test script above had executable permissions, whereas AppTest.pm (where the do_auth sub is) didnt, it was just being used by an instance script. so, i chmodded AppTest.pm, but to no avail...i'm stumped, can anyone see anything i've missed?

EDIT: escaped semicolons in the commands per Fletch's suggestion. the original problem still persists...thanks for the suggestion though!

__________
Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.
- Terry Pratchett

Replies are listed 'Best First'.
Re: blank string returned from piped command
by Fletch (Bishop) on Jul 31, 2006 at 16:42 UTC

    The ; character separates commands in most shells. What you've done is open a pipe from a shell which first runs env, then runs your custom_auth_tool with only password set. You need to either quote or backwhack the semicolon, or set the relevant keys in %ENV before opening your pipe.

    local $ENV{ QUERY_STRING } = "username=$uname;password=$pwd"; open( WEBOS, "/usr/bin/custom_auth_tool |" ) or die "Can't open pipe to authtool: $!\n"; ## ...
Re: blank string returned from piped command
by samtregar (Abbot) on Jul 31, 2006 at 17:49 UTC
    Try checking the return value on the open() and close() - even if it doesn't solve this problem it's a good habit to get in. You could be getting a useful error and not know it! Example:

    open(WEBOS,"$com|") or die "Couldn't open '$com|': $!"; $com = join('', <WEBOS>); close(WEBOS) or die "Couldn't close '$com|': $!";

    -sam

Re: blank string returned from piped command
by Ieronim (Friar) on Jul 31, 2006 at 17:50 UTC
    Bad style. Replace
    open(WEBOS,"$com|"); $com = join('', <WEBOS>); close(WEBOS);
    with
    open(WEBOS,"$com|") or die "Cannot run $cmd : $!" ; $com = join('', <WEBOS>); close(WEBOS) or die "$cmd closed with bad status: $! $?";
    Does anything change?

         s;;Just-me-not-h-Ni-m-P-Ni-lm-I-ar-O-Ni;;tr?IerONim-?HAcker ?d;print
Re: blank string returned from piped command
by kwaping (Priest) on Jul 31, 2006 at 17:05 UTC
    You might need to uri_escape() your username and password using URI::Escape before inserting them into your QUERY_STRING. However, the resulting characters might cause issues for your shell. I'm not sure what to do about that second part.

    ---
    It's all fine and dandy until someone has to look at the code.
      the program i'm calling is url-escape aware, so it will work whether the string is escaped or not. and if i expected the username or password to contain anything unexpected, i could quote them:
      my $com = 'env QUERY_STRING=username="'.$uname.'"\;password="'.$pwd.'" + /usr/bin/custom_auth_tool';

      __________
      Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.
      - Terry Pratchett

Re: blank string returned from piped command
by EvanK (Chaplain) on Jul 31, 2006 at 18:13 UTC
    that did something...modified per samtregar and Ieronim's suggestions:
    # run command through a pipe open(WEBOS,"$com|") or warn("cant open pipe to command: $!"); $com = join('', <WEBOS>); close(WEBOS) or warn("cant close pipe to command: $! $?");
    and it seems to be throwing an error on the close(), though it doesnt say why. scratch that last comment, $? is returning the value 11

    UPDATE: the C program i'm calling seems to be failing when do_auth calls it from within a module. when do_auth calls it from within a pl script, however, it works fine. this gives me the impression that the permissions are varying when I call a sub in the instance script from when i call a sub in a module used in said instance script. in the meantime, i'm just going to drop the CGI::Application framework right now and rewrite it all as one big script.

    thanks for the help, everyone! i appreciate it, as always!

    __________
    Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.
    - Terry Pratchett