Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

CGI + Perl issue 1

Status
Not open for further replies.

FlyingHorseman

Technical User
Oct 16, 2008
10
US
Background: I have a Solaris 10 machine, on which I have iPlanet 6 web server and ColdFusion 8, along with Perl 5.8.4. I just migrated from Solaris 8 and Perl 5.8.0, with all the other components the same. I had scripts that were running before. And to compund problems some of the directory structure is different.
Flow: I call a cfm script which reads all files in a directory and checks whether they have been added in an Oracle database. If so, there is a red X next to it. Regardless each file is a link which invokes a cgi script with the file-name being passed to it.
But, I keep getting the following error:
Server Error.
This server has encountered an internal error which prevents it from fulfilling your request. The most likely cause is a misconfiguration. Please ask the administrator to look for messages in the server's error log.
I look in the error log and this is the entry:
[05/Aug/2009:12:17:00] failure (25252): for host 10.x.y.zz trying to GET /cgi-bin/premierIsac.cgi, cgi_scan_headers reports: the CGI program /apps/infosec/cgi-bin/premierIsac.cgi did not produce a valid header (name without value: got line "use of uninitialized value in pattern match (m//) at /apps/infosec/cgi-bin/premierisac.cgi line 12, <infile> line 119.")
~ x ~
Code of the cgi file upto lines 13.
#!/usr/local/bin/perl -w
####### Original author: An intern from ages ago

use CGI qw:)standard); #needed for the 'param' function below
$file_parameter = param("file"); # Assign the value of the passed parameter to $file

open(INFILE, "/export/home/testuser/Notices/FS_ISAC/$file_parameter") or die ("Couldn't open temp_notices for reading: $!");

$file = <INFILE>;

while ($file !~ /(.+)\s+from\s+the\s+Financial\s+Services\s+ISAC/i) {
$file = <INFILE>;
}

I am at a complete loss here. I thought the scripts were not executing inthe cgi-bin directory, but, I put a Hello.pl and it executes fine, though it is called from the browser directly and there is no hand-off.

Any ideas/suggestions welcome.
 
I have an idea, but it's a very unusual thing to happen.

I'm guessing that at line 12 (is that the $file !~ regexp line?), $file is an undefined value. This causes a Perl warning to be issued. Usually this isn't a problem though, because Perl warnings are sent to STDERR, and not STDOUT, and most CGI-invoking web servers log STDERR to an error log and only use STDOUT when figuring out what to send to the web browser.

But it looks like your Solaris is picking up things in STDERR as output for your browser. CGI scripts should begin printing to STDOUT by printing an HTTP header, e.g. "Content-Type: text/plain". Judging by the error log it looks like the Perl warning happens before the CGI prints a header, and the server thinks the warning is for the browser, thus causing the error.

Try this in a test CGI script:

Code:
#!/usr/bin/perl -w

print "Content-Type: text/html\n\n";

print "Hello world!\n";
warn "Goodbye world!\n";

If you see "Hello world! Goodbye world!" in your web browser, it means your server is sending you the STDERR that your script prints (warn goes to STDERR), which will verify if I'm right.

It's a really weird and unusual issue anyway.

Cuvou.com | My personal homepage
Code:
perl -e '$|=$i=1;print" oo\n<|>\n_|_";x:sleep$|;print"\b",$i++%2?"/":"_";goto x;'
 
Another thing you can do is drop -w from the shebang line and use the warnings pragma and no warnings as needed:

Code:
#!/usr/local/bin/perl
[red]use warnings;[/red]
####### Original author: An intern from ages ago

use CGI qw(:standard); #needed for the 'param' function below
$file_parameter = param("file");  # Assign the value of the passed parameter to $file

open(INFILE, "/export/home/testuser/Notices/FS_ISAC/$file_parameter") or die ("Couldn't open temp_notices for reading: $!");

$file = <INFILE>;
[red]{
   no warnings;[/red]# no warnings will be issued in this block of code
while ($file !~ /(.+)\s+from\s+the\s+Financial\s+Services\s+ISAC/i) {    
    $file = <INFILE>;
}
[red]}[/red]

I would check the value of $file as the code runs to give you an idea of what the problem might be. Could be a blank line coming from the file or undef when eof is reached. To avoid that you could rewrite the code:

Code:
while (my $file = <INFILE>) {
    if ($file =~ /(.+)\s+from\s+the\s+Financial\s+Services\s+ISAC/i) {
         #I assume you want to process $1 here
     }
}

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Thanks Kirsle for responding.
I tried your suggestion and when I ran the file from the browser I got the same error in my browser window as before:
Server Error
This server has encountered an internal error which prevents it from fulfilling your request. The most likely cause is a misconfiguration. Please ask the administrator to look for messages in the server's error log.
~ x ~
In my error log I got the following:
[05/Aug/2009:14:15:42] failure (25252): for host 10.x.y.zz trying to GET /cgi-bin/Hello.pl, cgi_scan_headers reports: the CGI program /apps/infosec/cgi-bin/Hello.pl did not produce a valid header (name without value: got line "goodbye world!")
~ x ~
I hope it helps further.
 
Thanks KevinADC for joining in trying to unravel this.
First I tried removing the -w flag and substituting with use warnings. But, that didn't turn out so well as the process just hung interminably.

So, I reverted back and tried rewriting the code as suggested.
I unfortunately still get the same Server Error message in the browser window and get the following in my error log:
[05/Aug/2009:14:47:49] failure (25252): for host 10.x.y.zz trying to GET /cgi-bin/premierIsac.cgi, cgi_scan_headers reports: the CGI program /apps/infosec/cgi-bin/premierIsac.cgi did not produce a valid header (name without value: got line "use of uninitialized value in pattern match (m//) at /apps/infosec/cgi-bin/premierisac.cgi line 23, <infile> line 119.")

The funny thing was that it used to work on my old server. So, could it be a permissioning problem?
Anyway, this is the whole premierIsac.cgi code with the suggested modification:-
Code:
#!/usr/local/bin/perl -w
####### Original author: An intern from ages ago

use CGI qw(:standard); #needed for the 'param' function below
$file_parameter = param("file");  # Assign the value of the passed parameter to $file

open(INFILE, "/export/home/testuser/Notices/FS_ISAC/$file_parameter") or die ("Couldn't open temp_notices for reading: $!");

$file = <INFILE>;

#while ($file !~ /(.+)\s+from\s+the\s+Financial\s+Services\s+ISAC/i) {
#       $file = <INFILE>;
while (my $file = <INFILE>) {
        if ($file =~ /(.+)\s+from\s+the\s+Financial\s+Services\s+ISAC/i) {
        $module = $1;
}
}
#if ($file =~ /(.+)\s+from\s+the\s+Financial\s+Services\s+ISAC/i) {
#       $module = $1;
#}

until (($file =~ /^Advisory\s+ID\:?/i) || ($file =~ /Tracking\s+ID/i)) {
   $file = <INFILE>;
}
if ($file =~ /ID:?\s+(\S+)/i) {
   $id = $1;
}
elsif ($file =~ /ID:?\s+$/i) {
   $file = <INFILE>;
   while ($file eq "") {
      $file = <INFILE>;
      next;
   }
   $id = $file;
   $id =~ s/\s+//g;
}

until ($file =~ /^Date.*:/i) {
   $file = <INFILE>;
}
if ($file =~ /Date.*:?\s+(\d\d?\/\d\d?\/\d\d\d\d)/i) {
   $report_dt = $1;
}
elsif ($file =~ /Date.*:?\s+$/i) {
   $file = <INFILE>;
   while ($file eq "") {
      $file = <INFILE>;
      next;
   }
   $report_dt = $file;
   $report_dt =~ s/\s+//g;
}
$report_dt =~ /(\d\d?\/\d\d?\/\d\d\d\d)\S+/;
$report_dt = $1;


while ($file !~ /Title:?\s+(\S+.+)/i) {
   $file = <INFILE>;
}
if ($file =~ /Title:?\s+(\S+.+)/i) {
   $title = $1;
}
elsif ($file =~ /Title:?\s+$/i) {
   $file = <INFILE>;
   while ($file eq "") {
      $file = <INFILE>;
      next;
   }
   $title = $file;
   $title =~ s/^\s+//;
   $title =~ s/\"+//g;
}

$severityFound =0;
$severity = " ";
while ($file = <INFILE>) {
	
	if (($severityFound == 0) && ($file =~ /^\s*Severity:?\s+(.+)/i)) {
		$severityFound = 1;
   		$severity = $1;
	}
	elsif (($severityFound == 0) && ($file =~ /^\s*Severity:?\s+$/i)) {
		$severityFound = 1;
   		$file = <INFILE>;
   		while ($file eq "") {
      			$file = <INFILE>;
   		}
   		$severity = $file;
   		$severity =~ s/\s+//g;
	}
		
}

close(INFILE);


open(OUTF,">/apps/infosec/Notices/Fsisac_premier/temp_notices") or die ("Couldn't open temp_notices for writing: $!");
print OUTF (" $id\n $report_dt\n $title\n $severity\n $module\n");
close(OUTF); 

##### Print top of HTML output #####
	##### Print HTML output #####
#####	
	print <<STUFF;
	Content-type: text/html		

	<HTML> 
	<HEAD><TITLE>Populate Vulnerability Database</TITLE></HEAD>
		<script language="javascript">		
		function redirect () {
			location.href="/Notices/Fsisac_premier/populate_premier.cfm"
		}
		// -->
		</script>
	<BODY onLoad="redirect()"> <BR><H1><FONT COLOR="red"><I><B> Loading - Please wait. </B></I></FONT></H1><BR></BODY>
	</HTML>
			
STUFF
 
It's interesting that your error log shows it got the line "Goodbye world", considering that would've been the 4th line printed (and a warning at that).

Code:
Content-Type: text/html

Hello world!
Goodbye world!

It seems that your server simply doesn't like Perl's warnings *at all*

Try setting the "no warnings" pragma at the top of your file. If that doesn't work, try this hack at the top too (and by "top" I obviously don't mean over the #! line, but below it somewhere, before your code actually "does" anything):

Code:
$SIG{__WARN__} = sub {};

The signal there captures all warnings and sends them to a sub that does nothing at all... hopefully it means the server won't pick up anything from STDERR and croak again.

Was everything working before you changed your Perl version? Is /usr/bin/perl still pointing at the correct Perl? I dunno about Solaris, but in Linux if you install a different version of Perl than what it comes with, folks generally install it to /usr/local/bin/perl, because the /usr/bin/perl was provided by the vendor's package manager and too many other packages rely on that version of Perl... so they keep their custom Perl separate from the original.

Cuvou.com | My personal homepage
Code:
perl -e '$|=$i=1;print" oo\n<|>\n_|_";x:sleep$|;print"\b",$i++%2?"/":"_";goto x;'
 
Can you get any perl script to run?

When your code does this:

Code:
while (my $file = <INFILE>) {
        if ($file =~ /(.+)\s+from\s+the\s+Financial\s+Services\s+ISAC/i) {
        $module = $1;
}
}

It reads the whole file line by line and would only assign the last match found to $1 (if any).

The rest of your code that tries to read from the same filehandle <INFILE> should just return undef since you have never moved the file-pointer back to the beginning of the file (or where ever it needs to be)..



------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Thanks Kirsle and KevinADC for your comments. Unfortunately, I have ben asked to work on some other stuff and may not get around to this problem until much later. I shall try and squeeze in something, somehow.

I shall keep you guys posted.
 
I figured it out, finally yesterday, but, due to Patch Tuesday was swamped. I am finally up for some air and thought I would update you guys on the situation and also probably help somebody in the future.

The problem was iPlanet and CGI. What needed to be done was establish(?) the CGIStub. I did it when I first installed the web server way back in 2002, but, then an intern was the main person updating the server on a day-to-day basis and I was used as a resource when he or they came across something difficult. As such, it was not in their documentation and I had completely forgotten about it plus it isn't in the manuals for iPlanet 6. I don't know if they are in the newer manuals.

I came across it in a Sun forum posting which referred to the steps for Using CGI, and I mistakenly assumed they were referring to the couple of check boxes in the iPlanet Administration GUI that need to be enabled. I read the rest of the post and a tip about ^m characters helped me the first time I FTPed a file over. Only yesterday I went to the URL referenced, which is and have paid the price (in terms of sheer frustration). I did the first 8 steps and skipped the optional step 9. And voila!!! My original scripts without any modification worked!!

I did run into one other problem, but, that was resolved by increasing the timeout value for the ColdFusion server from 60 seconds to 120 seconds. I needed to do this as the database still resides on the old server and is not local to the web server. It doesn't timeout with this increased setting.

Even though you guys didn't provide the solution, I appreciate the effort all the same and it is a wonderful community that is out here on these forums. Thanks a lot.
 
Cool, thanks for the update and glad you got it working.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top