From 34e7ed6567700dcd9fcdedbc4aceb6031c70cd43 Mon Sep 17 00:00:00 2001 From: nasseeder1 Date: Wed, 2 Jan 2019 21:56:15 +0000 Subject: [PATCH] 49_SSCam: V8.3.1, change usage of older SMTP versions when Email shipping is used git-svn-id: https://svn.fhem.de/fhem/trunk@18122 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 2 + fhem/FHEM/49_SSCam.pm | 124 +++++++++++++++++++++++++++++++++--------- 2 files changed, 100 insertions(+), 26 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index 260cbe210..ada4256f5 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,7 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it. + - change: 49_SSCam: V8.3.1, change usage of older SMTP versions when Email + shipping is used - feature: 73_AutoShuttersControl: add support blockingAfterManual at Brightness, Bugfixes - feature: 49_SSCam: integrated Email shipping of snapshots, save recordings diff --git a/fhem/FHEM/49_SSCam.pm b/fhem/FHEM/49_SSCam.pm index c1856b9b6..3e6245012 100644 --- a/fhem/FHEM/49_SSCam.pm +++ b/fhem/FHEM/49_SSCam.pm @@ -47,6 +47,7 @@ use Encode; # Versions History intern our %SSCam_vNotesIntern = ( + "8.3.1" => "02.01.2019 fix SMTP usage for older Net::SMTP, new attribute \"smtpSSLPort\"", "8.3.0" => "02.01.2019 CAMLASTRECID replaced by Reading CamLastRecId, \"SYNO.SurveillanceStation.Recording\" added, ". "new get command \"saveRecording\"", "8.2.0" => "02.01.2019 store SMTP credentials with \"smtpcredentials\", SMTP Email integrated ", @@ -362,6 +363,7 @@ sub SSCam_Initialize($) { "smtpFrom ". "smtpHost ". "smtpPort ". + "smtpSSLPort ". "smtpTo ". "smtpNoUseSSL:1,0 ". "snapEmailTxt ". @@ -776,7 +778,7 @@ sub SSCam_Set($@) { } elsif ($opt eq "snap" && SSCam_IsModelCam($hash)) { if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";} - $hash->{HELPER}{SNAPBYSTRMDEV} = 1 if ($prop =~ /STRM/); # $prop wird mitgegeben durch Snap by SSCamSTRM-Device + $hash->{HELPER}{SNAPBYSTRMDEV} = 1 if ($prop && $prop =~ /STRM/); # $prop wird mitgegeben durch Snap by SSCamSTRM-Device if (AttrVal($name, "snapEmailTxt", "")) { # Snap soll nach Erstellung per Email versendet werden @@ -7112,6 +7114,13 @@ sub SSCam_prepareSendEmail ($$;$) { $lsnaptime = ReadingsVal($name,"LastSnapTime",""); $sdat = $data; } + + my $sslfrominit = 0; + my $smtpsslport = 465; + if(AttrVal($name,"smtpSSLPort",0)) { + $sslfrominit = 1; + $smtpsslport = AttrVal($name,"smtpSSLPort",0); + } $ret = SSCam_sendEmail($hash, {'subject' => $smtpmsg{subject}, 'part1txt' => $smtpmsg{body}, @@ -7122,6 +7131,8 @@ sub SSCam_prepareSendEmail ($$;$) { 'lsnaptime' => $lsnaptime, 'opmode' => $OpMode, 'smtpnousessl' => $nousessl, + 'sslfrominit' => $sslfrominit, + 'smtpsslport' => $smtpsslport, } ); return $ret; @@ -7142,19 +7153,34 @@ sub SSCam_sendEmail ($$) { my $m1 = "Net::SMTP"; my $m2 = "MIME::Lite"; + my $m3 = "Net::SMTP::SSL"; + my $sslfb = 0; # Flag für Verwendung altes Net::SMTP::SSL - my ($vm1,$vm2); - eval { require Net::SMTP; # libnet-3.06 has SSL included, so we need to check the version + my ($vm1,$vm2,$vm3); + eval { require Net::SMTP; Net::SMTP->import; $vm1 = $Net::SMTP::VERSION; + + # Version von Net::SMTP prüfen, wenn < 3.00 dann Net::SMTP::SSL verwenden + # (libnet-3.06 hat SSL inkludiert) + my $sv = $vm1; + $sv =~ s/[^0-9.].*$//; + if($sv < 3.00) { + require Net::SMTP::SSL; + Net::SMTP::SSL->import; + $vm3 = $Net::SMTP::SSL::VERSION; + $sslfb = 1; + } + require MIME::Lite; MIME::Lite->import; $vm2 = $MIME::Lite::VERSION; }; - if(!$vm1 || !$vm2) { + if(!$vm1 || !$vm2 || ($sslfb && !$vm3)) { my $nl = !$vm2?$m2." ":""; - $nl .= !$vm1?$m1:""; + $nl .= !$vm1?$m1." ":""; + $nl .= ($sslfb && !$vm3)?$m3:""; $ret = "required module for sending Email couldn't be loaded. You have to install: $nl"; Log3($name, 1, "$name - $ret"); @@ -7165,8 +7191,9 @@ sub SSCam_sendEmail ($$) { return $ret; } - Log3($name, 4, "$name - sendEmail version of \"$m1\" is \"$vm1\""); - Log3($name, 4, "$name - sendEmail version of \"$m2\" is \"$vm2\""); + Log3($name, 4, "$name - version of loaded module \"$m1\" is \"$vm1\""); + Log3($name, 4, "$name - version of \"$m1\" is too old. Use SSL-fallback module \"$m3\" with version \"$vm3\"") if($sslfb && $vm3); + Log3($name, 4, "$name - version of loaded module \"$m2\" is \"$vm2\""); my %SSCam_mailparams = ( 'smtpFrom' => {'attr'=>'smtpFrom', 'default'=>'', 'required'=>1, 'set'=>1}, @@ -7178,6 +7205,7 @@ sub SSCam_sendEmail ($$) { 'part2type' => { 'default'=>'', 'required'=>0, 'set'=>1}, 'smtphost' => {'attr'=>'smtpHost', 'default'=>'', 'required'=>1, 'set'=>0}, 'smtpport' => {'attr'=>'smtpPort', 'default'=>'25', 'required'=>1, 'set'=>0}, + 'smtpsslport' => {'attr'=>'smtpSSLPort', 'default'=>'', 'required'=>0, 'set'=>1}, # SSL-Port, verwendet bei direktem SSL-Aufbau 'smtpnousessl' => {'attr'=>'smtpNoUseSSL','default'=>'0', 'required'=>0, 'set'=>1}, 'smtpdebug' => {'attr'=>'smtpDebug', 'default'=>'0', 'required'=>0, 'set'=>0}, 'sdat' => { 'default'=>'', 'required'=>0, 'set'=>1}, # Daten base64 codiert, wenn gesetzt muss 'part2' auf 'image/jpeg' gesetzt werden @@ -7185,6 +7213,8 @@ sub SSCam_sendEmail ($$) { 'fname' => { 'default'=>'image.jpg', 'required'=>0, 'set'=>1}, # Filename für "image" oder "sdat" 'lsnaptime' => { 'default'=>'', 'required'=>0, 'set'=>1}, # Zeitstempel des letzten Schnappschusses 'opmode' => { 'default'=>'', 'required'=>1, 'set'=>1}, # OpMode muss gesetzt sein + 'sslfb' => { 'default'=>$sslfb, 'required'=>0, 'set'=>1}, # Flag für Verwendung altes Net::SMTP::SSL + 'sslfrominit' => { 'default'=>'', 'required'=>0, 'set'=>1}, # SSL soll sofort ! aufgebaut werden ); my %params = (); @@ -7233,7 +7263,8 @@ sub SSCam_sendEmailblocking($) { my $part2type = $paref->{part2type}; my $smtphost = $paref->{smtphost}; my $smtpport = $paref->{smtpport}; - my $smtpnousessl = $paref->{smtpnousessl}; # SSL Verschlüsselung soll genutzt werden + my $smtpsslport = $paref->{smtpsslport}; + my $smtpnousessl = $paref->{smtpnousessl}; # SSL Verschlüsselung soll NICHT genutzt werden my $subject = $paref->{subject}; my $to = $paref->{smtpTo}; my $msgtext = $paref->{msgtext}; @@ -7243,10 +7274,12 @@ sub SSCam_sendEmailblocking($) { my $fname = $paref->{fname}; # Filename von "image" my $lsnaptime = $paref->{lsnaptime}; # Zeit des letzten Schnappschusses wenn gesetzt my $opmode = $paref->{opmode}; # aktueller Operation Mode + my $sslfb = $paref->{sslfb}; # Flag für Verwendung altes Net::SMTP::SSL + my $sslfrominit = $paref->{sslfrominit}; # SSL soll sofort ! aufgebaut werden my $hash = $defs{$name}; my $sslver = ""; - my ($err,$fh); + my ($err,$fh,$smtp); # Credentials abrufen my ($success, $username, $password) = SSCam_getcredentials($hash,0,"smtp"); @@ -7310,29 +7343,50 @@ sub SSCam_sendEmailblocking($) { $mailmsg->attr('content-type.charset' => 'UTF-8'); - # login to SMTP Host - my $smtp = Net::SMTP->new(Host => $smtphost, Port => $smtpport, SSL => 0, Debug => $smtpdebug); + ##### SMTP-Connection ##### + # login to SMTP Host + if($sslfb) { + # Verwendung altes Net::SMTP::SSL <= 3.00 -> immer direkter SSL-Aufbau, Attribut "smtpNoUseSSL" wird ignoriert + Log3($name, 3, "$name - Attribute \"smtpNoUseSSL\" will be ignored due to usage of Net::SMTP::SSL") if(AttrVal($name,"smtpNoUseSSL",0)); + $smtp = Net::SMTP::SSL->new(Host => $smtphost, Port => $smtpsslport, Debug => $smtpdebug); + } else { + # Verwendung neues Net::SMTP::SSL > 3.00 + if($sslfrominit) { + # sofortiger SSL connect + $smtp = Net::SMTP->new(Host => $smtphost, Port => $smtpsslport, SSL => 1, Debug => $smtpdebug); + } else { + # erst unverschlüsselt, danach switch zu encrypted + $smtp = Net::SMTP->new(Host => $smtphost, Port => $smtpport, SSL => 0, Debug => $smtpdebug); + } + } + if(!$smtp) { $err = "SMTP Error: Can't connect to host $smtphost"; Log3($name, 2, "$name - $err"); - $err = encode_base64($err,""); + $err = encode_base64($err,""); return "$name|$err|''"; } - - if($smtp->can_ssl() && !$smtpnousessl) { - unless( $smtp->starttls ( SSL_verify_mode => 0, - SSL_version => "TLSv1_2:!TLSv1_1:!SSLv3:!SSLv23:!SSLv2", - ) ) { - $err = "SMTP Error while switch to SSL: ".$smtp->message(); - Log3($name, 2, "$name - $err"); - $err = encode_base64($err,""); - return "$name|$err|''"; - } - $sslver = $smtp->get_sslversion(); - Log3($name, 3, "$name - SMTP-Host $smtphost connection switched to SSL version: $sslver"); + if(!$sslfb && !$sslfrominit) { + # Aufbau unverschlüsselt -> switch zu verschlüsselt wenn nicht untersagt + if($smtp->can_ssl() && !$smtpnousessl) { + unless( $smtp->starttls ( SSL_verify_mode => 0, + SSL_version => "TLSv1_2:!TLSv1_1:!SSLv3:!SSLv23:!SSLv2", + ) ) { + $err = "SMTP Error while switch to SSL: ".$smtp->message(); + Log3($name, 2, "$name - $err"); + $err = encode_base64($err,""); + return "$name|$err|''"; + } + + $sslver = $smtp->get_sslversion(); + Log3($name, 3, "$name - SMTP-Host $smtphost switched to encrypted connection with SSL version: $sslver"); + } else { + Log3($name, 3, "$name - SMTP-Host $smtphost use unencrypted connection !"); + } } else { - Log3($name, 3, "$name - don't use SSL connection to SMTP-Host $smtphost !"); + $sslver = $smtp->get_sslversion(); + Log3($name, 3, "$name - SMTP-Host $smtphost use immediately encrypted connection with SSL version: $sslver"); } unless( $smtp->auth($username, $password) ) { @@ -8288,7 +8342,8 @@ attr <name> genericStrmHtmlTag <video $HTMLATTR controls autoplay> There are more attributes must be set or can be used optionally.
At first the Credentials for access the Email outgoing server must be set by command "set <name> smtpcredentials <user> <password>". The connection establishment to the server is initially done unencrypted and switches to an encrypted connection if SSL - encryption is available. In that case the transmission of User/Password takes place encrypted too. + encryption is available. In that case the transmission of User/Password takes place encrypted too. + If attribute "smtpSSLPort" is defined, the established connection to the Email server will be encrypted immediately. Attributes which are optional are marked:

@@ -8824,6 +8880,13 @@ attr <name> genericStrmHtmlTag <video $HTMLATTR controls autoplay>
+ +
  • smtpSSLPort <Port>
    + Optional setting of SSL port of outgoing email server (default: 465). If set, the established connection to the Email + server will be encrypted immediately. +
  • +
    +
  • smtpTo <name>@<domain>[, <name>@<domain>][, <name>@<domain>]...
    Receiving address for emal shipping. Several receiving addresses are separated by ",". @@ -9824,6 +9887,7 @@ attr <name> genericStrmHtmlTag <video $HTMLATTR controls autoplay> Die Credentials für den Zugang zum Email-Server müssen mit dem Befehl "set <name> smtpcredentials <user> <password>" gesetzt werden. Der Verbindungsaufbau zum Postausgangsserver erfolgt initial unverschüsselt und wechselt zu einer verschlüsselten Verbindung wenn SSL zur Verfügung steht. In diesem Fall erfolgt auch die Übermittlung von User/Password verschlüsselt. + Ist das Attribut "smtpSSLPort" definiert, erfolgt der Verbindungsaufbau zum Email-Server sofort verschlüsselt. Optionale Attribute sind gekennzeichnet:

    @@ -10382,6 +10447,13 @@ attr <name> genericStrmHtmlTag <video $HTMLATTR controls autoplay>

  • + +
  • smtpSSLPort <Port>
    + Optionale Angabe SSL Port des Postausgangsservers (default: 465). Ist dieses Attribut gesetzt, erfolgt die Verbindung zum + Email-Server sofort verschlüsselt. +
  • +
    +
  • smtpTo <name>@<domain>[, <name>@<domain>][, <name>@<domain>]...
    Empfängeradresse(n) für den Email-Versand. Mehrere Adressen müssen durch "," getrennt werden.