The idead behind this perl script is to allow file transfert from someone without a suitable mail user agent, just a simple browser. File attachment for the dummies. From a web page with a form and a file field, the file is uploaded to the server that deals with it to make it a mime attachment.
For this script, we will only use perl modules included in the standard distribution.
#!/usr/bin/perl # All by HAbeTT # Up2me use CGI; use MIME::Base64;
CGI helps us retrieve data from the html form and MIME::Base64 will be used to encode the attachment file. At first, we start to build the html output page.
print <<frag; Content-type: text/html <html> <head> </head> <body> frag
Then we retrieve the cgi data and output an error message if the form doesn't contain the expected fields and data.
$query = new CGI;
unless ($query->param('fichier')) {
print "<font color=\"#ff0000\">Error, file not specified.<p>";
print "</body></html>";
exit(0);
}
Now we retrieve the name of the uploaded file and then the data it contains.
$file = $query->param('fichier');
$data = "";
while ($size = read($file,$daa,1024)) {
$data.=$daa;
}
The data is now base64 encoded as mail protocols require and the file name is processed to exclude path information that we don't need :
$encodata = encode_base64($data); $file =~ s/\\/\//g; $file = substr($file, rindex($file, "/")+1);
In theory, a fixed boundary can be set to tear appart the different segments of the message, but we will include a random boundary generator to avoid any trouble wiht badly written mail user agents. The boundary must a 7 bits ascii string. Dashes (-) are recomended as this character cannot appear in base 64 encoded data.
$bound = int(rand(1000))."--".int(rand(1000))."--".int(rand(1000));
Now we open a pipe to sendmail (check it is located at the same place on your server). We use the t switch so that the From: and the To: are set only one time, inside the message (plus security bonus).
open (SENDMAIL, "|/usr/lib/sendmail -t"); print SENDMAIL <<End; From: robot\@habett.org To: habett\@habett.org Subject: Transport of the $file file X-Mailer: Up2Me by HAbeTT MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="$bound" MIME format mail and base64 data $bound Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit $file is attached $bound Content-Type: text/plain; name="$file" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="$file" $encodata $bound ok End
To make things easier, we have defined the attachment to have a Content-Type: text/plain on 8 bits that should suit any data but should have been more precise. We could have included a deduction of the right Content-Type from the extension of the name of the uploaded file.
We just have to conclude the html control page.
print <<frag; message sent with the file <b>$file</b> attached. <p> thanks </body> </html> frag exit(0);