CGI Skript - Kontakt

1

1965

Hallo,
ich habe mal eine Frage:

Wir benutzen auf einer unserer Seiten ein CGI Script welches der Kunde als Kontaktformular nutzt.

Jetzt möchte ich eine kleine Zusatzfunktion einbauen - dem User soll es möglich gemacht werden eine Datei von 1 MB (Dateiformat egal) mitzusenden und es soll als Anhang an die Mail mitversendet werden.

Da ich eigentlich sehr zufrieden mit diesem Skript bin möchte ich es nur erweiteren.

Was muss ich tun?
Ich bin kein Profi was das angeht - aber ich hoffe es gibt hier jemanden der mir das gut erklären kann.

Datei mailform.cgi
Code:
#!/usr/bin/perl

use CGI::Carp qw(fatalsToBrowser);
require "mailsetup.pl";
&formparser;

foreach ("/usr/sbin/sendmail","/usr/lib/sendmail","/usr/bin/sendmail","/usr/share/sendmail","/var/qmail/bin/sendmail","/usr/bin/sendmail.restart","/etc/sendmail.cf","/etc/sendmail.cw","/usr/man/man8/sendmail.8","/var/qmail/bin/qmail-inject"){
if(-e $_ && -X _){
$mailprogamm = $_;
last;
}
} 
###################################################
# alle Formfelder
$name_v = &maildatensaver($FORM{'name_v'});
$name_n = &maildatensaver($FORM{'name_n'});
$verein_company = &maildatensaver($FORM{'verein_company'});
$email = &maildatensaver($FORM{'email'});
$vorwahl = &maildatensaver($FORM{'vorwahl'});
$nummer = &maildatensaver($FORM{'nummer'});
$quelle = &maildatensaver($FORM{'quelle'});
$Newsletter = &maildatensaver($FORM{'Newsletter'});
$Mitteilung = &maildatensaver($FORM{'Mitteilung'});
$absende_id = &maildatensaver($FORM{'absende_id'});

###################################################

# Fehlerbehandlung Anfang
$fehlermeldung = "" ;
$fehler_gefunden = "" ;

#--------CHECK fuer: Vorname-----------------------------
$errormeldung = "<li>Das Feld \"Vorname\" wurde nicht oder nicht mit korrekten Daten ausgefüllt.\n" ;
if ($name_v eq '') {
$fehlermeldung = $fehlermeldung.$errormeldung ;
$fehler_gefunden = 1 ; }

#-------------------------------------
#--------CHECK fuer: E-Mail Adresse-----------------------------
$errormeldung = "<li>Das Feld \"E-Mail Adresse\" muss eine g&uuml;ltige E-Mail Adresse beinhalten.\n";
if ($email !~ /^([a-zA-Z0-9][a-zA-Z_0-9-\.]*)(\@)([a-zA-Z0-9][a-zA-Z_0-9-\.]*[a-zA-Z0-9])(\.)([a-zA-Z0-9]*)$/) {
$fehlermeldung = $fehlermeldung.$errormeldung ;
$fehler_gefunden = 1 ; }
#-------------------------------------
#--------CHECK fuer: Telefonnummer-----------------------------
$errormeldung = "<li>Das Feld \"Telefonnummer\" darf nur Zahlen von 0 - 9 beinhalten.\n" ;
if ($vorwahl =~ /[^0-9]/) {
$fehlermeldung = $fehlermeldung.$errormeldung ;
$fehler_gefunden = 1 ; }

#-------------------------------------
#--------CHECK fuer: Nummer-----------------------------
$errormeldung = "<li>Das Feld \"Nummer\" darf nur Zahlen von 0 - 9 beinhalten.\n" ;
if ($nummer =~ /[^0-9]/) {
$fehlermeldung = $fehlermeldung.$errormeldung ;
$fehler_gefunden = 1 ; }

#-------------------------------------
#--------CHECK fuer: Ihre Anfrage-----------------------------
$errormeldung = "<li>Das Feld \"Ihre Anfrage\" wurde nicht oder nicht mit korrekten Daten ausgefüllt.\n" ;
if ($Mitteilung eq '') {
$fehlermeldung = $fehlermeldung.$errormeldung ;
$fehler_gefunden = 1 ; }

#-------------------------------------


if ($fehler_gefunden) {
&fehlerausgabe;
exit;
}
# Fehlerbehandlung Ende
###################################################
&floodcheck;
&datumsroutine;
&mailsenden;
&bestaetigung;
sub mailsenden {

# Mail senden
my $mailbodykontakt = <<MBT;
Anfrage von XXXX

Rabattangebot
Anfrage vom: $datumlang\n

Persönliche Daten: 
Vorname: $name_v 
Name: $name_n
von Verein/Firma: $verein_company 

Kontakt
E-Mail Adresse: $email
Telefonnummer: $vorwahl

////////////////////////////////////////////////

Kennt XXXX durch:
$quelle

$Newsletter

//////////////////////////////////////////////

Rabattangebotsanfrage für:
$Mitteilung


Anfrage umgehend bearbeiten!

MBT

if (!$email) { 
$email = $empfaengermail;
}

if (!$betreff) { 
$betreff = "Angebotsanfrage | 2010-$absende_id";
}

open (MAIL, "|$mailprogamm -t") || die $!;
print MAIL "To: $empfaengermail ($empfaenger)\n";
print MAIL "From: $email \n";
print MAIL "Subject: $betreff\n\n";
print MAIL $mailbodykontakt;
print MAIL "\n\n";
print MAIL "Gesendet am: $datumlang\n";
close(MAIL);
}


###################################################
sub bestaetigung {
print "Content-type: text/html\n\n";

$meta = qq~<meta http-equiv="refresh" content="$forwardtime; URL=$forwardurl">~;
$titeltext = "Nachricht erfolgreich versendet";
$statustext = qq~<div align="center"><b>Vielen Dank f&uuml;r Ihre Nachricht.</b><br>
  <br>
  <span class="font14">Wir haben Ihre Anfrage unter der Nummer: 2010-$absende_id gespeichert!  </span><br />
  <br />
Sie werden in $forwardtime Sekunden zurück zur Hauptseite geleitet.
<br />
Klicken Sie bitte den nachfolgenden Link um zurück zu gelangen<br>
<br>
</div>
<div align="center">Hier gehts <a href="javascript:history.go(-1)">zurück</a></div>
<br><br>
~;
print &tparser("header.html");
print &tparser("mailstatus.html");
print &tparser("footer.html");
exit;
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Fehlerausgabe
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
sub fehlerausgabe {
print "Content-type: text/html\n\n";

$meta = '';
$titeltext = "Fehler festgestellt!";
$statustext = qq~<b>Beim ausfüllen haben Sie folgendes vergessen:</b>
<ol>
$fehlermeldung
</ol><br><br>

<div align="center">Bitte gehen Sie « <a href="javascript:history.go(-1)">zurück</a></div>
~;
print &tparser("header.html");
print &tparser("mailstatus.html");
print &tparser("footer.html");
exit;
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Formdatenparser
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
sub formparser {
read(STDIN, $input, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $input);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$name =~ tr/+/ /;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Templateroutine
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
sub tparser {
my $templatedatei = shift;
my $OUTPUT;
local($/);

open (FILE, "<$templatedatei") or die "Kann Template $templatedatei nicht oeffnen $!\n";
$OUTPUT = <FILE>;
close(FILE);
# Skalarwerte ersetzen
$OUTPUT =~ s/<__\$([\w\-]+)__>/${$1}/g;
# Hashwerte ersetzen
$OUTPUT =~ s/<__\%([\w\-]+)\{([\w\-]+)\}__>/${$1}{$2}/g;
# Arraywerte ersetzen
$OUTPUT =~ s/<__\$([\w\-]+)\[([\w\-]+)\]__>/${$1}[$2]/g;
# Werte ersetzen in der Form $lang{user}
$OUTPUT =~ s/<__\$([\w\-]+)\{([\w\-]+)\}__>/${$1}{$2}/g;
# Werte ersetzen in der Form $input{'action'} oder $lang{'hallo du'}
$OUTPUT =~ s/<__\$([\w\-]+)\{'([\w\- ]+)\'}__>/${$1}{$2}/g;
return $OUTPUT;
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Datumsroutine
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
sub datumsroutine {

@tagekurz = ('So','Mo','Di','Mi','Do','Fr','Sa');
@monatekurz = ('Jan.','Feb.','März','Apr.','Mai.','Jun.','Jul.','Aug.','Sept.','Okt.','Nov.','Dez.');
@tage = ('Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag');
@monate = ('Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember');
($sec, $min, $stunde, $mtag, $mon, $jahr, $tag, $nr_tag, $isdst) = localtime(time);
$monat = $mon+1;
if($monat < 10) { $monat = "0$monat"; }
if($stunde < 10) { $stunde = "0$stunde"; }
if ($min < 10) { $min = "0$min"; }
if ($sec < 10) { $sec = "0$sec"; }
$jahr = 1900 + $jahr;

# Ausgabe z.B. Sonntag, 14. Juli , 2002 um 17:39:43 Uhr 
$datumlang = " $tage[$tag], $mtag. $monate[$mon]  $jahr um $stunde:$min:$sec Uhr";
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Floodsperre
# - - - - - - - - - - - - - - - - - - - - - - - - - - #
sub floodcheck {
$wartezeit = "1.0";
$sperrlistenlaenge = 15;
my $IP_Nummer = $ENV{'REMOTE_ADDR'};
my $aktionszeit = time();

open(ZEITLIMIT, "floodsperre.dat");
@letzte_eintraege = <ZEITLIMIT>;
close(ZEITLIMIT);
foreach (@letzte_eintraege) {
if (/^$IP_Nummer/){
($junk,$letzte_aktionszeit) = split(/\|!!\|/,$_);
chomp($letzte_aktionszeit);
last;
}
} # ende foreach
$wartezeit *= $noflood; # zeit in sek bis neu gepostet werden darf
$floodfehler = 0;
if ( int(($aktionszeit - $letzte_aktionszeit) < $wartezeit)){

$floodfehler = 1;

# Fehlerpruefung
$fehlermeldung = "" ;
$fehler_gefunden = "" ;
# -----------------------------------------------------------------------
$errormeldung = "<li>Sie müssen $wartezeit Sekunden warten bis Sie wieder eine E-Mail absenden k&ouml;nnen.\n" ;
if ($floodfehler) {
$fehlermeldung = $fehlermeldung.$errormeldung ;
$fehler_gefunden = 1 ; }
# -----------------------------------------------------------------------
if ($fehler_gefunden) {
&fehlerausgabe;}
exit;
}
else {
if (unshift(@letzte_eintraege, "$IP_Nummer|!!|$aktionszeit\n") > $sperrlistenlaenge){
$#letzte_eintraege = $sperrlistenlaenge;
}

open(ZEITLIMIT, ">floodsperre.dat");
print ZEITLIMIT @letzte_eintraege;
close(ZEITLIMIT);
}
return 1;
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Maildaten vorbereiten
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
sub maildatensaver {
$_[0] =~ s/^\s+//;
$_[0] =~ s/\s+$//;
$_[0] =~ s/`//g;
$_[0] =~ s/\r//g;
$_[0] =~ s/\|//g;
$_[0] =~ s/\n/\n/ig;
return($_[0]);
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

Vielen Dank für eure Hilfe!
 
Ich würde Dir dringend raten, auf die Subroutine "formparse" zu verzichten und stattdessen die Vars()-Methode aus CGI (http://search.cpan.org/dist/CGI.pm) zu nehmen. CGI ist im Perl-Standard schon mit drin. So wie Du es machst sind Sicherheitslöcher drin.

CGI.pm bietet auch entsprechende Methoden für den Dateiupload an.

Hier findest Du eine Beschreibung, wie man Attachments mit sendmail verschickt: http://wiki.perl-community.de/Wissensbasis/SendmailAttachments

Und so wie Du Dateien öffnest, ist es auch nicht ganz optimal, siehe auch http://reneeb-perlblog.blogspot.com/2009/09/verschiedenes-zu-open.html
 
Zurück