Hi,
kurz formuliert: Warum erhalte ich ein "Passwort falsch", wenn ich SendMail(Curl) aus einer Notify heraus triggere?
SendMail
state:message:[\s\S]* {
my $emailTo = 'xxx';
my $emailFrom = 'yyy';
my $emailServer = 'smtp.zzz.de';
#erzeuge Datumsangabe konform zu RFC-5322:
my @emailDateArray = split(' ', strftime("%w %d %m %Y %H:%M:%S %z", localtime));
$emailDateArray[0] = (qw[Sun Mon Tue Wed Thu Fri Sat])[$emailDateArray[0]] . ',';
$emailDateArray[2] = (qw[Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec])[$emailDateArray[2]-1];
my $emailDate = join(' ', @emailDateArray);
# Passwort aus getKeyValue abrufen
my ($err, $emailPass) = getKeyValue("${name}_password");
if ($err || !defined $emailPass) {
return "Error retrieving password: $err";
}
my $message = ReadingsVal($name, 'message', '???');
my $subject = "$name: FHEM Nachricht";
# Betreff extrahieren und aus der Nachricht entfernen
if ($message =~ s/(?:Subject|Betreff)=["'](.*?)["']//) {
$subject = $1;
}
# Empfänger extrahieren und aus der Nachricht entfernen
if ($message =~ s/(?:To|An)=["'](.*?)["']//) {
$emailTo = $1;
}
#Dateianhänge bestimmen
my @attachments;
while ($message =~ s/(?:Attachment|Anhang)=["'](.*?)["']//) {
my $file = $1;
return ">>$file<< not found, not sending email" unless (-e $file);
push (@attachments, $file);
}
#der curl Befehl wird hier aufgebaut:
my $cmd = "curl -m 19 --noproxy '*' --no-progress-meter --ssl-reqd smtps://$emailServer:465 ";
$cmd .= "--user '$emailFrom:$emailPass' --mail-from '$emailFrom' --mail-rcpt '$emailTo' ";
$cmd .= "--write-out 'Email sent with status %{http_code}' ";
$cmd .= "-H 'Subject: $subject' ";
$cmd .= "-H 'From: $emailFrom' ";
$cmd .= "-H 'Date: $emailDate' ";
#multipart/alternative für Text und HTML EMail Body
$cmd .= "-F '=(;type=multipart/alternative' ";
# Leerzeichen und <br> bzw <br \> am Anfang entfernen:
$message =~ s/^(\s|<br(?:[ \/]+)>)+//;
# Leerzeichen und <br> bzw <br \> am Ende entfernen:
$message =~ s/(\s|<br(?:[ \/]+)>)+$//;
#Plaintext E-Mail Inhalt an cURL:
$cmd .= "-F \"=$message;type=text/plain; charset=UTF-8\" ";
#ersetze \n bzw. \r\n durch ein HTML-tag <br />:
$message =~ s/\r?\n/<br \/>/g;
#HTML E-Mail Inhalt an cURL:
$cmd .= "-F '= <body>$message</body>;type=text/html; charset=UTF-8' ";
$cmd .= "-F '=)' ";
#jetzt alle Attachments (0..N) anhängen:
foreach my $file (@attachments) {
$cmd .= "-F '=@".$file.";encoder=base64' ";
}
#stderr auch mit in den output sammeln:
$cmd .= " 2>&1";
#Blockierender Aufruf von cURL in dieser Funktion via BlockingCall:
if (!defined &sendMailfunc1) {
*sendMailfunc1 = sub ($) {
my ($param) = @_;
my $result;
$result = qx/$param/;
$result = MIME::Base64::encode_base64($result);
$result =~ s/\n//g;
return $result;
}
}
#Rückgabe über diese Funktion,
#anzeigen in dem reading dieses UserReadings:
if (!defined &sendMailfunc2) {
*sendMailfunc2 = sub ($) {
my ($result) = @_;
my $hash = $defs{$name};
$result = MIME::Base64::decode_base64($result);
readingsSingleUpdate($hash, $reading, $result, 1);
}
}
#funktion falls BlockingCall abgebrochen wird:
if (!defined &sendMailfunc3) {
*sendMailfunc3 = sub ($) {
my ($result) = @_;
my $hash = $defs{$name};
readingsSingleUpdate($hash, $reading, $result, 1);
}
}
BlockingCall("sendMailfunc1", $cmd, "sendMailfunc2", 20, "sendMailfunc3", "Error: timeout");
return "started cURL command...";
},
state:password:.* {
# Passwort speichern
my $ret = setKeyValue("${name}_password", ReadingsVal($name, 'password', undef)) // "password stored";
#password wieder aus der Variablen rausnehmen, soll nicht sichtbar bleiben:
#
# Hinweis: das Password taucht beim Setzen hierüber im Event-Log auf!
# Alternativ: { setKeyValue("sendMail_password", "geheimesPasswort") }
readingsBulkUpdate($hash, "password", "****");
return "$ret";
}
Ausschnitt aus 99_myUtils.pm
sub
backup_mail()
{
fhem("set sendMail message Betreff='RaspiBackup' Sicherung durchgeführt!");
}
Ausschnitt Notify
mqtt_listener:.* {
my $nachricht=ReadingsVal("mqtt_listener","state","unbekannt");
...
if(substr($nachricht,0,18) eq "RaspiBackup Fertig")
{
#fhem("set sendMail message Betreff='RaspiBackup' Sicherung durchgeführt!");
backup_mail();
}
Rückmeldung (Funktion ok) bei Verwendung "backup_mail()"
Email sent with status 250
Rückmeldung (Fehler) bei Verwendung "fhem set"
curl: (67) Login denied Email sent with status 535
Ein direktes Eingeben des "fhem set" Befehls in FHEM funktioniert natürlich.
Der Effekt tritt nur aus der Notify heraus auf.
Danke
Kharim
Vorschlag: Du baust einfach mal eine Debug Ausgabe ein, die $cmd ins Logfile schreibt. Damit kannst Du dann in den unterschiedlichen Situationen beim Aufruf (direkter Funktionsaufruf vs. Aufruf aus notify) sehen, was $cmd tatsächlich enthält.
$cmd .= " 2>&1";
Debug $cmd;
#Blockierender Aufruf von cURL in dieser Funktion via BlockingCall:
Mein Bauchgefühl läßt mich ein escaping-Problem bei irgendeinem speziellen Zeichen vermuten. Das könnte beispielsweise der Doppelpunkt zwischen user und password sein - aber es ist nur ein Gefühl.