CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
Image upload script

 



jjvoice
Novice

Dec 4, 2007, 11:14 AM

Post #1 of 9 (1700 views)
Image upload script Can't Post

Hello,

I wrote a perl upload script to allow users to upload images to the server. It worked great for a long time. However, my hosting service just moved me to a new platform and it no longer works. I get a permission denied error writing to the tempfile. They tell me I have to define a path the the tempfile in my own directory because I am not allowed to write to the system temfile anymore. I know of no way to do this, and I actually thought this was totally transparent to my script and defined by CGI.pm. Does anyone know how to define the path to a tempfile in my own directory, rather than using the system tempfile during the upload? Thanks!


rmelnyk@us.ibm.com


KevinR
Veteran


Dec 4, 2007, 11:32 AM

Post #2 of 9 (1698 views)
Re: [jjvoice] Image upload script [In reply to] Can't Post

I believe it's covered in the CGI modules documentation.
-------------------------------------------------


jjvoice
Novice

Dec 4, 2007, 12:19 PM

Post #3 of 9 (1694 views)
Re: [KevinR] Image upload script [In reply to] Can't Post


In Reply To
I believe it's covered in the CGI modules documentation.



Kevin,



Thanks for the help. I checked there and they do have some info on temp files, but based on what I see there, I can not figure out what to put in my script to get it to use a temp file in my directory structure. I've tried a million things and can not get it to work. Can you give me a clue as to how to proceed? Thanks.



Bob


KevinR
Veteran


Dec 4, 2007, 9:43 PM

Post #4 of 9 (1691 views)
Re: [jjvoice] Image upload script [In reply to] Can't Post

This is quotedfrom the CGI module:

# -private_tempfiles

CGI.pm can process uploaded file. Ordinarily it spools the uploaded file to a temporary directory, then deletes the file when done. However, this opens the risk of eavesdropping as described in the file upload section. Another CGI script author could peek at this data during the upload, even if it is confidential information. On Unix systems, the -private_tempfiles pragma will cause the temporary file to be unlinked as soon as it is opened and before any data is written into it, reducing, but not eliminating the risk of eavesdropping (there is still a potential race condition). To make life harder for the attacker, the program chooses tempfile names by calculating a 32 bit checksum of the incoming HTTP headers.

To ensure that the temporary file cannot be read by other CGI scripts, use suEXEC or a CGI wrapper program to run your script. The temporary file is created with mode 0600 (neither world nor group readable).

The temporary directory is selected using the following algorithm:

1. if the current user (e.g. "nobody") has a directory named
"tmp" in its home directory, use that (Unix systems only).

2. if the environment variable TMPDIR exists, use the location
indicated.

3. Otherwise try the locations /usr/tmp, /var/tmp, C:\temp,
/tmp, /temp, ::Temporary Items, and \WWW_ROOT.

Each of these locations is checked that it is a directory and is writable. If not, the algorithm tries the next choice.

<end quote>

Try adding a folder named tmp to your home dir per rule number 1. If that does not work, try defining the ENV variable per rule number 2:

$ENV{TMPDIR} = 'path/to/a/folder';
-------------------------------------------------


jjvoice
Novice

Dec 5, 2007, 4:13 AM

Post #5 of 9 (1686 views)
Re: [KevinR] Image upload script [In reply to] Can't Post

Kevin,



Thanks, yeah, I found that too. I tried both of those suggestions and still I get the same error - error opening tempfile, permission denied. It is still trying to use the system tempfile which the system will not allow me to write to. I think I'm gunna have to get in touch with someone from the hosting service who knows what they changed and how I can fix it. Thanks for all your help.



Bob


jjvoice
Novice

Dec 5, 2007, 4:17 AM

Post #6 of 9 (1685 views)
Re: [jjvoice] Image upload script [In reply to] Can't Post

Kevin,



Just a long shot...here is my script. Do you see anything here that would be forcing the script to use the system tmp dir instead of what I specify in the $ENV variable? Thanks again.

#!/usr/bin/perl -w
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
if 0;

$ENV{TMPDIR} = "/home/users/web/b2420/ipw.summitwebpages/public_html/melnykchat/tmp";

use CGI;

$query = new CGI;

$passwd = $query->param("passwd");

@upfiles = ("upfile1","upfile2","upfile3","upfile4","upfile5","upfile6","upfile7","upfile8","upfile9","upfile10,upfile11","upfile12","upfile13","upfile14","upfile15","upfile16","upfile17","upfile18","upfile19","upfile20");

if ($passwd eq "xxxx") {

for ($i=0; $i<20; $i++) {
$filename = $query->param($upfiles[$i]);
$filename =~ s/.*[\/\\](.*)/$1/;
$upload_filehandle = $query->upload($upfiles[$i]);
$upload_dir = "/home/users/web/b2420/ipw.summitwebpages/public_html/melnykchat/images";
open (UPLOADFILE,">$upload_dir/$filename");
binmode UPLOADFILE;
while ( <$upload_filehandle> ) {
print UPLOADFILE;}
close (UPLOADFILE);
}


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


print "<P>Your image has been uploaded!</P> \n";
print "<a href=\"..\/image_upload.html\">Back to upload page</a>\n";}

else {
print "Content-type: text/html\n\n";
print "<P>Bad password!</P> \n";
print "<a href=\"..\/image_upload.html\">Back to upload page</a>\n";}


KevinR
Veteran


Dec 5, 2007, 11:14 AM

Post #7 of 9 (1681 views)
Re: [jjvoice] Image upload script [In reply to] Can't Post

make sure your tmp directory has read/write permissions set (if applicable). I see a potential problem here:


Code
 open (UPLOADFILE,">$upload_dir/$filename"); 
binmode UPLOADFILE;
while ( <$upload_filehandle> ) {
print UPLOADFILE;}
close (UPLOADFILE);
}


the close() function should be move outside the "while" loop:


Code
open (UPLOADFILE,">$upload_dir/$filename"); 
binmode UPLOADFILE;
while ( <$upload_filehandle> ) {
print UPLOADFILE;}
}
close (UPLOADFILE);


You also do not need to do this:

@upfiles = ("upfile1","upfile2","upfile3","upfile4","upfile5","upfile6","upfile7","upfile8","upfile9","upfile10,upfile11","upfile12","upfile13","upfile14","upfile15","upfile16","upfile17","upfile18","upfile19","upfile20");

you can name all the upload fields the same and the CGI module will parse the input correctly in list context:


Code
my @files_to_upload = $query->param('upload'); 
foreach my $files (@files_to_upload) {
do something
}


but you can do it the way you are currently if you want to.
-------------------------------------------------


jjvoice
Novice

Dec 5, 2007, 11:37 AM

Post #8 of 9 (1677 views)
Re: [KevinR] Image upload script [In reply to] Can't Post

Kevin,

Thanks. Yes, the permissions are set. And the close is already outside the while loop. That last bracket closed the for loop from above. The only thing in the while loop is the print UPLOADFILE; And thank for the coding tip on the @upfile array - a bit cleaner the way you did it.



Bob


KevinR
Veteran


Dec 5, 2007, 12:15 PM

Post #9 of 9 (1676 views)
Re: [jjvoice] Image upload script [In reply to] Can't Post

oops, I missed that closing bracket:

while ( <$upload_filehandle> ) {
print UPLOADFILE;}<---- Blush

Your host may have to solve the problem if nobody else can think of something to try. Usually a 'tmp' directory in your web root should work, I don't know why yours is not.
-------------------------------------------------

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives