Solved

formmail.pl with file attachment

Posted on 2001-07-15
10
318 Views
Last Modified: 2007-12-19
Can anyone help with modifications to formmail.pl so that I can use a "file" (browse) type field to the web form.

The "user's" selected file would then be sent as an email attachment along with the other data contained in the form.

Thanks

Greg
0
Comment
Question by:gfergus
  • 5
  • 4
10 Comments
 
LVL 6

Expert Comment

by:christopher sagayam
ID: 6284291
?
0
 
LVL 8

Expert Comment

by:bebonham
ID: 6284610
I think he is talking about formmail.pl from matt's script archive.

A lot of people use this script...

but it doesn't use the cgi module, and I don't have an non cgi upload script handy, but could dig one up I guess.

0
 
LVL 8

Expert Comment

by:bebonham
ID: 6284616
and then there's the matter of a non perl module mailer that can attach a file

I've seen one again, in this ta (maneshr)...but I don't think he even got all the bugs out, best to use MIME::Lite.

so...it is either a ton of code, or he uses modules...

formail.pl itself is too big because it doesn't use cgi.

might as well just start from scratch and make one script that does it all.


but on the other hand, you could always tack on the cgi and mime modules into the formail.pl
0
 

Author Comment

by:gfergus
ID: 6287362
Thanks for your comments.

I'm getting the idea that there may not be a script similar to Matt's Script Archive 'formail.pl' that can handle file attachments. Is this the case?

Please tell me about the 'non perl module' mailer that can attach a file. That may be what I'm after.

Keep in mind the script/module has to run on a UNIX box.

Also, is it a difficult task to edit formmail.pl to use MIME for attachments?

Also, where can I find out about MIME:Lite?

Thanks
0
 
LVL 8

Expert Comment

by:bebonham
ID: 6288081


matt's formmail.pl is a really cool script, because it should run on any computer with perl, because it uses NO modules...


this attacher is not totally non module


it uses the CGI module to upload the file and doesn't use MIME at all...


the mainthing this shows is that you can send an attachment via email without MIME:Lite

also, the uploading can be done without CGI, but I haven't found that script yet...



keep in mind, all of these things can be done in 10-15 lines IF you use CGI and MIME:Lite.


but first, run this attached script and HTML page

COURTESY OF MANESHR


=========attach_cv_details.html
<TITLE>Email your Resume</TITLE>

<form ENCTYPE="multipart/form-data" method=post action="/cgi-bin/attach_cv_details.pl">
<table border=1 cellspacing=3 cellpadding=4>

<TD><B>Name</B></TD>
<TD><input type=text name=name></TD>
<TR>

<TD><B>Age</B></TD>
<TD><input type=text name=age size=4></TD>
<TR>

<TD><B>Address</B></TD>
<TD><input type=text name=address size=30></TD>
<TR>

<TD><B>Your CV <I>(in MS-Word format)</I></B></TD>
<TD><input type=file name=cv></TD>
<TR>

<TD align=center colspan=2><input type=submit value="Send it!!"></TD>
</TABLE>
</form>

=========attach_cv_details.pl
#!/usr/local/bin/perl

$|++;


use CGI;

$query=new CGI;

##  Read HTML form variables into PERL variables
$name=$query->param('name');
$age=$query->param('age');
$address=$query->param('address');

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

##  Location of the uploaded file
$dir_to_store="/tmp";

##  The sender of this form and the receiver of this email.
##  The sender can be the user himself/herself.
##  In that case you will have to add an extra element to the HTML form.
my($from,$to) = ("user_sending_cv\@resume.com","sender\@server.com");

##  Compose the text message.
$message= qq{A CV has been submitted from the web.
Here are the details.

Name: $name
Age: $age
Address: $address

Also find below the attached CV.

};

$boundary="Message-Boundary-19990614";

die('Sender name not found') if (! $from);

##  Now that the file has been uploaded to the server...
##  ...send it out as an email attachment.
$mailprog ="/usr/lib/sendmail";
open(MAIL, "| $mailprog -t ");
print MAIL "To: $to\n";
print MAIL "From: $from\n";
print MAIL "Subject: CV submitted from the Web!\n";
print MAIL "MIME-Version: 1.0\n";
print MAIL "Content-type: Multipart/1;\n";
print MAIL "\tboundary=$boundary\n";
print MAIL "\n";
print MAIL "\n";
print MAIL "--$boundary\n";

##  Print out any message sent with the email
if ($message){
 print MAIL "Content-type: text/plain; charset=US-ASCII\n";
 print MAIL "Content-description: Mail message body\n";
 print MAIL "Content-transfer-encoding: 7BIT\n";
 print MAIL "\n";
 print MAIL $message."\n";
 print MAIL "--$boundary\n";
}

##  Process the uploaded CV/Resume file.
$uploaded_file=$query->param('cv');
$tmp_uploaded_file=$query->param('cv');
$tmp_uploaded_file=~ s/\\/\//g;
@tmp_uploaded_file=split(/\//,$tmp_uploaded_file);

$filename = $dir_to_store."/".$tmp_uploaded_file[$#tmp_uploaded_file];

##  Allow upload of ONLY those files that have the extension .doc
if (!($tmp_uploaded_file[$#tmp_uploaded_file] =~ /\.doc$/i )){
 print "<Font color=red>Invalid file type!!</FONT>\n";
 exit;
}

##  The file type is valid (extension is valid!!).
open(MYFILE,"> $filename") || die $!;
binmode MYFILE;
while($bytesread=read($uploaded_file,$data,1024)){
 $size+=$bytesread;
 $body.=$data;
 print MYFILE $data;
}
close(MYFILE);
close($uploaded_file);

##  Print the header for that attachment.
print MAIL "Content-type: application/octet-stream; name=\"$filename\"; type=Unk
nown\n";
print MAIL "Content-transfer-encoding: BASE64\n";
print MAIL "Content-disposition: attachment\n";
print MAIL "\n";

##  Open the actual file and read its contents.
undef $/;
open(F, $filename) || die("Cannot read $filename: $!\n");
binmode F;
#$body = encode_base64(<F>);  ##  Use base64 for encoding the contents
$body = my_encode_base64(<F>);  ##  Use base64 for encoding the contents
close F;
$/="\n";

##  Send out the contents!!
print MAIL $body;
print MAIL "\n";
print MAIL "--$boundary\n";


print "<P><B>Your resume has been E-mailed as an attachment.!!</B><br>\n";
##  Indicate end of all attachments.
print MAIL "--$boundary--\n";
close(MAIL);

sub my_encode_base64 ($;$){
 my $res = "";
 my $eol = $_[1];
 $eol = "\n" unless defined $eol;
 pos($_[0]) = 0;                          # ensure start at the beginning
 while ($_[0] =~ /(.{1,45})/gs) {
   $res .= substr(pack('u', $1), 1);
   chop($res);
 }
 $res =~ tr|` -_|AA-Za-z0-9+/|;               # `# help emacs
 # fix padding at the end
 my $padding = (3 - length($_[0]) % 3) % 3;
 $res =~ s/.{$padding}$/'=' x $padding/e if $padding;
 # break encoded string into lines of no more than 76 characters each
 if (length $eol) {
   $res =~ s/(.{1,76})/$1$eol/g;
 }
$res;
}




if that works well enough for you, I can combine it with a non-module upload script and it might work with formmail.pl



if not,

then you can do something like

use CGI ':standard';
use MIME::Lite;

foreach(param())
{
$values{$_}=param($_);
}

###assumed attachment field is called filef

$fh=param('filef');

open OUT, "attachfile.dat"  
####filename & path is in $fh, you will need to get just the filename (not in this example)
while(read($fh,buffer,1024)
{
print OUTF $buffer;
}

close OUT;


foreach(keys %values)
{
$msg.=$_ . "\t=\t" . $values{$_} . "\n";
}


my $mail = MIME::Lite->new(
From=>'you@you.com',
To=>'target@target.com',
Subject=>'mail',
Type=>'multipart/mixed') or warn "creation prob $!";
attach $mail(Type=>'TEXT',Data=>$msg) or warn "can't attach msg $!";
attach $mail(Type=>'BINARY',
Path=>'path/filename.ext',Filename=>'filename.ext') or warn "can't put file $!";
$mail->send() or warn "can't send $!";




That is just an example, and needs a little fleshing out.

but you can see how much shorter that is.


Bob
0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 

Author Comment

by:gfergus
ID: 6288811
Thanks Bob

It looks great. I'll set it up tonight and see how it goes.

I'll let you know ASAP.

Greg
0
 

Author Comment

by:gfergus
ID: 6291189
Hi Bob

Had some problem with the html/script. The html worked ok but the broswer reported 'Internal server error 500' and displayed the path to the perl script in the address bar. There was no email sent and I could not find the 'uploaded' file on the server. I checked the existing formmail.pl script/html and it works with email OK (but does not include a function to upload files).

I have the necessary permission to edit then upload the scripts but I am limited to ftp access. The cgi scripts are contained in a directory called '/cgi' and the html lives in a directory called '/web'. There was no directory called '/tmp' and I was not permmited to create one in '/' but I could create '/web/tmp'. I used 'web/tmp' as the location for the uploaded file.

Maybe I need to find or setup a directory (such as /tmp) that has the correct permissions to allow writing a new file? I found a directory '/files' , maybe I could use '/files' for the upload directory...

I only have ftp access to the UNIX server. However I probably could request a simple change to a system, directory or file permission/security setting.

Please desribe the code I can use to debug the perl script. For example, a piece of code that would write out the current variables and display them in a html page, returned to the original html request.

By what process does the user's file get uploaded to the UNIX server? Is it a function of the html form field of type 'file' or is it required that the perl script read in the user's file-path from the form-field type 'file' and then conduct a simple ftp function to upload the file?
Is there a system setting or process block that restricts uploading of a file to the UNIX web server?
Could you write a simple script\html  to confirm that the upload function is available?

It seems to me I am asking a lot from you. If you can help I am willing to help you in return with an increase in points awarded or whatever you may suggest, thanks.

Greg
0
 

Author Comment

by:gfergus
ID: 6291204
Also to help me understand what's happening, a couple more questions....

In the script, what is the function of:
    $boundary="Message-Boundary-19990614";
and what is the significance of the number 19990614 ?

Where in the script, is the file uploaded?

In the HTML, what is the function of:
     ENCTYPE="multipart/form-data"
in the form header and how does it work?

Thanks

Greg
0
 
LVL 8

Accepted Solution

by:
bebonham earned 100 total points
ID: 6302826
  $boundary="Message-Boundary-19990614";


maneshr's script writes mime..


this is a MIME content seperator.

the file would be uploaded to the current working directory.


the ENCTYPE tells the browser to send a file, and not just the filename...it is a requirement for uploading and the FILE input type.


Bob
0
 

Author Comment

by:gfergus
ID: 6625788
Thanks for all your help!
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
Email validation in proper way is  very important validation required in any web pages. This code is self explainable except that Regular Expression which I used for pattern matching. I originally published as a thread on my website : http://www…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now