diff --git a/CHANGED b/CHANGED
index e0a425ff1..be4795706 100644
--- a/CHANGED
+++ b/CHANGED
@@ -1,5 +1,6 @@
# 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.
+ - changed: allowed.pm/fhem.pl: SecurityCheck cleanup, Forum #81509
- new: 88_xs1Bridge: New modul to read xs1 EZcontrol
- change: 93_DbRep: V7.0.0, changelog:
- faster exec if no time attribut/aggregation is set
diff --git a/FHEM/01_FHEMWEB.pm b/FHEM/01_FHEMWEB.pm
index 9a5520f06..1dd0e0c6c 100644
--- a/FHEM/01_FHEMWEB.pm
+++ b/FHEM/01_FHEMWEB.pm
@@ -132,7 +132,7 @@ FHEMWEB_Initialize($)
$hash->{AttrFn} = "FW_Attr";
$hash->{DefFn} = "FW_Define";
$hash->{UndefFn} = "FW_Undef";
- $hash->{NotifyFn}= ($init_done ? "FW_Notify" : "FW_SecurityCheck");
+ $hash->{NotifyFn}= "FW_Notify";
$hash->{AsyncOutputFn} = "FW_AsyncOutput";
$hash->{ActivateInformFn} = "FW_ActivateInform";
no warnings 'qw';
@@ -226,37 +226,6 @@ FHEMWEB_Initialize($)
}
}
-#####################################
-sub
-FW_SecurityCheck($$)
-{
- my ($ntfy, $dev) = @_;
- return if($dev->{NAME} ne "global" ||
- !grep(m/^INITIALIZED$/, @{$dev->{CHANGED}}));
- my $motd = AttrVal("global", "motd", "");
- if($motd =~ "^SecurityCheck") {
- my @list1 = devspec2array("TYPE=FHEMWEB");
- my @list2 = devspec2array("TYPE=allowed");
- my @list3;
- for my $l (@list1) { # This is a hack, as hardcoded to basicAuth
- next if(!$defs{$l});
- my $fnd = 0;
- for my $a (@list2) {
- next if(!$defs{$a});
- my $vf = AttrVal($a, "validFor","");
- $fnd = 1 if($vf && ($vf =~ m/\b$l\b/) && AttrVal($a, "basicAuth",""));
- }
- push @list3, $l if(!$fnd);
- }
- $motd .= (join(",", sort @list3).
- " has no associated allowed device with basicAuth.\n")
- if(@list3);
- $attr{global}{motd} = $motd;
- }
- $modules{FHEMWEB}{NotifyFn}= "FW_Notify";
- return;
-}
-
#####################################
sub
FW_Define($$)
@@ -1070,8 +1039,7 @@ FW_answerCall($)
} else {
my $motd = AttrVal("global","motd","none");
if($motd ne "none") {
- $motd =~ s/\n/
/g;
- FW_addContent(">$motd
$motd
{".httpAuthHeader"};
return 0 if(!$basicAuth);
+ return 2 if(!$param);
my $FW_httpheader = $param;
my $secret = $FW_httpheader->{Authorization};
@@ -173,6 +175,7 @@ allowed_Authenticate($$$$)
my $pw = AttrVal($aName, "password", undef);
if(!$pw) {
$pw = AttrVal($aName, "globalpassword", undef);
+ return 2 if($pw && !defined($param));
$pw = undef if($pw && $cl->{NAME} =~ m/_127.0.0.1_/);
}
return 0 if(!$pw);
@@ -244,8 +247,10 @@ allowed_Attr(@)
} else {
delete($hash->{$attrName});
}
- readingsSingleUpdate($hash, "state", "validFor:".join(",",@param), 1)
- if($attrName eq "validFor");
+ if($attrName eq "validFor") {
+ readingsSingleUpdate($hash, "state", "validFor:".join(",",@param), 1);
+ InternalTimer(1, "SecurityCheck", 0) if($init_done);
+ }
} elsif(($attrName eq "basicAuth" ||
$attrName eq "password" || $attrName eq "globalpassword") &&
@@ -253,6 +258,7 @@ allowed_Attr(@)
foreach my $d (devspec2array("TYPE=(FHEMWEB|telnet)")) {
delete $defs{$d}{Authenticated} if($defs{$d});
}
+ InternalTimer(1, "SecurityCheck", 0) if($init_done);
}
return undef;
@@ -266,11 +272,16 @@ allowed_fhemwebFn($$$$)
my $hash = $defs{$d};
my $vf = $defs{$d}{validFor} ? $defs{$d}{validFor} : "";
- my @arr = map { "" }
+ my (@F_arr, @t_arr);
+ my @arr = map {
+ push(@F_arr, $_) if($defs{$_}{TYPE} eq "FHEMWEB");
+ push(@t_arr, $_) if($defs{$_}{TYPE} eq "telnet");
+ ""
+ }
grep { !$defs{$_}{SNAME} }
devspec2array("TYPE=(FHEMWEB|telnet)");
- return " $d validFor ".
+ my $r = " $d validFor
EOF
+
+ $r .= "For ".join(",",@F_arr).
+ ": \"set $d basicAuth <username> <password>\"
"
+ if(@F_arr);
+ $r .= "For ".join(",",@t_arr).
+ ": \"set $d password <password>\" or".
+ " \"set $d globalpassword <password>\"
"
+ if(@t_arr);
+ return $r;
}
1;
diff --git a/FHEM/98_telnet.pm b/FHEM/98_telnet.pm
index bab883691..8e6b38a42 100644
--- a/FHEM/98_telnet.pm
+++ b/FHEM/98_telnet.pm
@@ -20,7 +20,6 @@ telnet_Initialize($)
$hash->{AsyncOutputFn} = "telnet_Output";
$hash->{UndefFn} = "telnet_Undef";
$hash->{AttrFn} = "telnet_Attr";
- $hash->{NotifyFn}= "telnet_SecurityCheck";
$hash->{AttrList} = "globalpassword password prompt allowedCommands ".
"allowfrom SSL connectTimeout connectInterval ".
"encoding:utf8,latin1 sslVersion";
@@ -57,39 +56,6 @@ CommandTelnetEncoding($$)
return $ret;
}
-#####################################
-sub
-telnet_SecurityCheck($$)
-{
- my ($ntfy, $dev) = @_;
- return if($dev->{NAME} ne "global" ||
- !grep(m/^INITIALIZED$/, @{$dev->{CHANGED}}));
- my $motd = AttrVal("global", "motd", "");
- if($motd =~ "^SecurityCheck") {
- my @list1 = devspec2array("TYPE=telnet");
- my @list2 = devspec2array("TYPE=allowed");
- my @list3;
- for my $l (@list1) { # This is a hack, as hardcoded to basicAuth
- next if(!$defs{$l} || $defs{$l}{TEMPORARY}); # Blocking.pm /Forum #47022
- my $fnd = 0;
- for my $a (@list2) {
- next if(!$defs{$a});
- my $vf = AttrVal($a, "validFor","");
- $fnd = 1 if(($vf && $vf =~ m/\b$l\b/) &&
- (AttrVal($a, "password","") ||
- AttrVal($a, "globalpassword","")));
- }
- push @list3, $l if(!$fnd);
- }
- $motd .= (join(",", sort @list3).
- " has no associated allowed device with password/globalpassword.\n")
- if(@list3);
- $attr{global}{motd} = $motd;
- }
- delete $modules{telnet}{NotifyFn};
- return;
-}
-
##########################
sub
telnet_ClientConnect($)
diff --git a/fhem.pl b/fhem.pl
index 1f3eac668..da3ab7223 100755
--- a/fhem.pl
+++ b/fhem.pl
@@ -94,6 +94,7 @@ sub RefreshAuthList();
sub RemoveInternalTimer($;$);
sub ReplaceEventMap($$$);
sub ResolveDateWildcards($@);
+sub SecurityCheck();
sub SemicolonEscape($);
sub SignalHandling();
sub TimeNow();
@@ -574,10 +575,6 @@ if($pfn) {
close(PID);
}
-my $sc_text = "SecurityCheck:";
-$attr{global}{motd} = "$sc_text\n\n"
- if(!$attr{global}{motd} || $attr{global}{motd} =~ m/^$sc_text/);
-
$init_done = 1;
$lastDefChange = 1;
@@ -593,25 +590,11 @@ foreach my $d (keys %defs) {
}
}
+SecurityCheck();
+
$fhem_started = time;
DoTrigger("global", "INITIALIZED", 1);
-$attr{global}{motd} .= "Running with root privileges."
- if($^O !~ m/Win/ && $<==0 && $attr{global}{motd} =~ m/^$sc_text/);
-$attr{global}{motd} .=
- "\nRestart FHEM for a new check if the problem is fixed,\n".
- "or set the global attribute motd to none to supress this message.\n"
- if($attr{global}{motd} =~ m/^$sc_text\n\n./);
-my $motd = $attr{global}{motd};
-if($motd eq "$sc_text\n\n") {
- delete($attr{global}{motd});
-} else {
- if($motd ne "none") {
- $motd =~ s/\n/ /g;
- Log 2, $motd;
- }
-}
-
my $osuser = "os:$^O user:".(getlogin || getpwuid($<) || "unknown");
Log 0, "Featurelevel: $featurelevel";
Log 0, "Server started with ".int(keys %defs).
@@ -5364,4 +5347,40 @@ restoreDir_saveFile($$)
}
}
+sub
+SecurityCheck()
+{
+ return if(AttrVal("global", "motd", "") eq "none");
+ my @fnd;
+ foreach my $sdev (devspec2array("TYPE=(telnet|FHEMWEB)")) {
+ next if(!$defs{$sdev} || $defs{$sdev}{TEMPORARY});
+ my $hash = { SNAME=>$sdev, TYPE=>$defs{$sdev}{TYPE} };
+ push(@fnd, " $sdev is not password protected")
+ if(!Authenticate($hash, undef));
+ }
+ if(@fnd) {
+ push @fnd, "";
+ my @l = devspec2array("TYPE=allowed");
+ if(@l) {
+ push @fnd, "Protect this FHEM installation by ".
+ "configuring the allowed device $l[0]";
+ } else {
+ push @fnd, "Protect this FHEM installation by ".
+ "defining an allowed device with define allowed allowed";
+ }
+ }
+
+ if($^O !~ m/Win/ && $<==0) {
+ push(@fnd, "Running with root privileges is discouraged.")
+ }
+
+ if(@fnd) {
+ unshift(@fnd, "SecurityCheck:");
+ push(@fnd, "You can disable this message with attr global motd none");
+ $attr{global}{motd} = join("\n", @fnd);
+ } elsif($attr{global}{motd} =~ m/^SecurityCheck/) {
+ delete $attr{global}{motd};
+ }
+}
+
1;
diff --git a/www/pgm2/fhemweb.js b/www/pgm2/fhemweb.js
index f76ac1c0b..5daf49e3d 100644
--- a/www/pgm2/fhemweb.js
+++ b/www/pgm2/fhemweb.js
@@ -248,6 +248,26 @@ FW_jqueryReadyFn()
$(this).data('delayTimer', wait);
});
+ $("pre.motd").each(function(){ // add links for passwort setting
+ var txt = $(this).text();
+ txt = txt.replace(/(configuring|define|attr) .*/g, function(x) {
+ return ""+x+"";
+ });
+ $(this).html(txt);
+ $(this).find("a").click(function(){
+ var txt = $(this).text();
+ var ma = txt.match(/configuring.*device (.*)/);
+ if(ma)
+ location.href = FW_root+"?detail="+ma[1];
+ FW_cmd(FW_root+"?cmd="+encodeURIComponent(txt)+"&XHR=1",
+ function(data){
+ if(txt.indexOf("attr") == 0) $("pre.motd").html("");
+ if(txt.indexOf("define") == 0)
+ location.href = FW_root+"?detail=allowed";
+ });
+ });
+ });
+
FW_smallScreenCommands();
FW_inlineModify();
FW_rawDef();