tags:

views:

314

answers:

3

I'm having a bugger of a time with a CGI wrapper for PHP. I know very little about CGI and PHP as CGI.

Here's what I know about the system:

  • Solaris 10 on a 386
  • Suhosin
  • PHP normally running as CGI, with cgiwrap (http://cgiwrap.sourceforge.net/). I am not able to find an example wrapper.cgi on the server to look at.
  • Shared hosting (virtual host), so I don't have access to Apache config. But the admins are not helpful. Switching hosts is not an option.
  • Options directive cannot be overridden in .htaccess (ExecCGI, for example).

.htaccess:

AddHandler php-handler .php  
Action php-handler "/bin/test.cgi"

~/public_html/bin/test.cgi:

#!/usr/bin/sh

# Without these 2 lines, I get an Internal Server Error
echo "Content-type: text/html"
echo ""

exec "/path/to/php-cgi" 'foo.php';

/bin/foo.php:

<?php 
echo "this is foo.php!";

Output of http://mysite.com/bin/test.cgi:

X-Powered-By: PHP/5.2.11 Content-type: text/html echo "Content-type: text/html" echo "" exec "/path/to//php-cgi" 'foo.php';

Output of http:/ /mysite.com/anypage.php:

X-Powered-By: PHP/5.2.11 Content-type: text/html echo "Content-type: text/html" echo "" exec "/path/to//php-cgi" 'foo.php';

The things I note are:

  • PHP is being executed, as noted by the X-Powered-By ... header.
  • The source of /bin/test.cgi is output in the results.
  • No matter what I put as the second argument of exec, it isn't passed to the php binary. I've tried '-i' to get phpinfo, '-v' to get the version...
  • When I execute test.cgi via the shell, I get the expected results (the argument is passed to php, and it is reflected in the output).

Any ideas about how to get this to work?

UPDATE

  • It appears that the reason the source of the test.cgi was appearing was due to errors. Anytime fatal error occurred, either within the cgi itself or with the command being executed by exec, it would cause the source of the cgi to appear.
  • Within test.cgi, I can get the proper output with exec "/path/to/php-cgi" -h (I get the same thing as I would from CLI).
+1  A: 

Why not just put the php-cgi file in the bin folder directly, and put that as your handler as opposed to test.cgi calling it.

blockhead
I'll try it. The wrapper method is one I've seen a lot, so it's the only one I'm familiar with (though the wrapper is usually named something other than 'test.cgi').
When I do this, I get an error in the log: "File does not exist: /full/path/to/public_html/bin/php-cgi/bin/foo.php". It's tacking the path of the script onto the path defined as the handler and trying to use that new value as the handler. (Note that I'm doing this in a subdirectory to preserve the actual website for now.)
I mean copy the php-cgi file into your cgi executable directly. The place where test.cgi is located.
blockhead
That's what I did. php-cgi was in the same directory: public_html/bin. But the error msg included the full filesystem path from server root.
what does your .htaccess file look like now?
blockhead
I've changed it too many times... This now appears to be a CGI problem - looking like it was errors in the code causing the source of the code to be output to the browser. I could get a basic output using the original configuration, but when I try to invoke PHP from within the script, it dies in most instances (I can get correct results if I just use the '-h' option for PHP, but other options don't work). Now I'm attempting to debug from the CGI end.
+1  A: 

Can't really tell but here are some thoughts:

  • Don't output anything before you exec the php script as php itself handles the response header.

  • To call the script try exec "/path/to/php-cgi \"/path/to/script/foo.php\""

Hope I could help.

EDIT

You might wanna have a look at this post of Stuart Herbert. Particulary the part where he writes:

#!/bin/bash

/usr/bin/php-cgi "$@"

This script simply executes our central copy of the PHP CGI executable, passing through whatever parameters Apache has called the bash script with.

aefxx
Thanks. I should have mentioned that I tried that and got a 500 error (Internal server error).
Tried without the headers, that is.
For the second (calling the script with the entire command in quotes), apparently exec considers the entire first argument as a program name. I get this error (in the log): /path/to/php-cgi -nf "foo.php": not found. (-nf are apparently necessary options for php-cgi).
A: 

A couple of thoughts:

  1. I'm pretty sure that suhosin isn't going to do you much good here. Not that it'll harm anything. But, in this case, PHP scripts are going to execute under very unprivileged users (one hopes). The systems access control tools will keep the script sandboxed.

  2. It's my understanding that you can use the following configuration directives (amusing that your php-cgi binary is located at /usr/bin/php-cgi you can just access and run PHP scripts as CGIs in the conventional way.

    ScriptAlias /local-bin /usr/bin
    AddHandler application/x-httpd-php5 php
    Action application/x-httpd-php5 /local-bin/php-cgi

    Stick that in the config. Upload a php file. Hit the php file from your browser, and it should all work.

tychoish
Thanks - it's a shared hosting environment, so I don't have access to the apache config and can't do anything about the presence of suhosin.I tried your suggestion, without the ScriptAlias directive, using a local copy of php-cgi, and using "/bin/php-cgi" in the Action directive. I get an error in the log: "File does not exist: /full/path/to/public_html/bin/php-cgi/bin/foo.php". It's tacking the path of the script onto the path defined as the handler and trying to use that new value as the handler. (Note that I'm doing this in a subdirectory to preserve the actual website for now.)
Try taking out the script alias stuff, and simply so that it looks like: `AddHandler application/x-httpd-php5 php``Action application/x-httpd-php5 /usr/bin/php`Alias would be nice, but if you can't even hack your system to make it work, the chances of someone being able to break in through you is pretty low. Directories shouldn't matter. How much access to the file system outside of your public_html folder do you have?
tychoish
I have a ~ directory above public_html. In case it matters, it's a networked file system, so ~ isn't on the same machine. On the actual webserver, I can't login directly (I can only get to the files via a symlink at ~/public_html). Trying `AddHandler application/x-httpd-php5 php` `Action application/x-httpd-php5 /usr/bin/php`, I get a 404 error. Nothing in the error log, though.