diff --git a/FHEM/01_FHEMWEB.pm b/FHEM/01_FHEMWEB.pm index c972e1a23..40e8ee614 100755 --- a/FHEM/01_FHEMWEB.pm +++ b/FHEM/01_FHEMWEB.pm @@ -118,6 +118,7 @@ FHEMWEB_Initialize($) CORS:0,1 HTTPS:1,0 SVGcache:1,0 + allowedCommands allowfrom basicAuth basicAuthMsg @@ -1491,6 +1492,8 @@ FW_style($$) my ($cmd, $msg) = @_; my @a = split(" ", $cmd); + return if( AttrVal($FW_wname,"allowedCommands","") !~ m/\b$a[0]\b/); + my $start = "
"; my $end = "
"; @@ -1769,9 +1772,11 @@ FW_fC($@) my ($cmd, $unique) = @_; my $ret; if($unique) { - $ret = AnalyzeCommand($FW_chash, $cmd); + $ret = AnalyzeCommand($FW_chash, $cmd, + AttrVal($FW_wname,"allowedCommands",undef)); } else { - $ret = AnalyzeCommandChain($FW_chash, $cmd); + $ret = AnalyzeCommandChain($FW_chash, $cmd, + AttrVal($FW_wname,"allowedCommands",undef)); } return $ret; } @@ -2565,6 +2570,24 @@ FW_ActivateInform()
+ +
  • allowedCommands
    + A comma separated list of commands allowed from this FHEMWEB + instance.
    If set to an empty list , (i.e. comma only) + then this FHEMWEB instance will be read-only.
    If set to + get,set, then this FHEMWEB instance will only allow + regular usage of the frontend by clicking the icons/buttons/sliders but + not changing any configuration.
    + + + This attribute intended to be used together with hiddenroom/hiddengroup +
    + + Note:allowedCommands should work as intended, but no guarantee + can be given that there is no way to circumvent it. If a command is + allowed it can be issued by URL manipulation also for devices that are + hidden.

  • +
  • allowfrom

  • @@ -2614,7 +2637,7 @@ FW_ActivateInform() Comma separated list of rooms to "hide", i.e. not to show. Special values are input, detail and save, in which case the input areas, link to the detailed views or save button is hidden (although each aspect - still can be addressed through url manipulation).
    + still can be addressed through URL manipulation).
    The list can also contain values from the additional "Howto/Wiki/FAQ" block. diff --git a/fhem.pl b/fhem.pl index 46662632d..b78548cbc 100755 --- a/fhem.pl +++ b/fhem.pl @@ -40,8 +40,8 @@ use Time::HiRes qw(gettimeofday); # Forward declarations # sub AddDuplicate($$); -sub AnalyzeCommand($$); -sub AnalyzeCommandChain($$); +sub AnalyzeCommand($$;$); +sub AnalyzeCommandChain($$;$); sub AnalyzeInput($); sub AnalyzePerlCommand($$); sub AssignIoPort($;$); @@ -728,9 +728,9 @@ CommandIOWrite($$) ##################################### # i.e. split a line by ; (escape ;;), and execute each sub -AnalyzeCommandChain($$) +AnalyzeCommandChain($$;$) { - my ($c, $cmd) = @_; + my ($c, $cmd, $allowed) = @_; my @ret; if($cmd =~ m/^[ \t]*(#.*)?$/) { # Save comments @@ -753,7 +753,7 @@ AnalyzeCommandChain($$) my $subcmd; while(defined($subcmd = shift @cmdList)) { $subcmd =~ s/SeMiCoLoN/;/g; - my $lret = AnalyzeCommand($c, $subcmd); + my $lret = AnalyzeCommand($c, $subcmd, $allowed); push(@ret, $lret) if(defined($lret)); } @cmdList = @saveCmdList; @@ -803,9 +803,9 @@ AnalyzePerlCommand($$) } sub -AnalyzeCommand($$) +AnalyzeCommand($$;$) { - my ($cl, $cmd) = @_; + my ($cl, $cmd, $allowed) = @_; $cmd =~ s/^(\n|[ \t])*//;# Strip space or \n at the begginning $cmd =~ s/[ \t]*$//; @@ -814,10 +814,12 @@ AnalyzeCommand($$) return undef if(!$cmd); if($cmd =~ m/^{.*}$/s) { # Perl code + return( "Forbidden command $cmd." ) if( $allowed && $allowed !~ m/\bperl\b/ ); return AnalyzePerlCommand($cl, $cmd); } if($cmd =~ m/^"(.*)"$/s) { # Shell code in bg, to be able to call us from it + return( "Forbidden command $cmd." ) if( $allowed && $allowed !~ m/\bshell\b/ ); if($evalSpecials) { map { $ENV{substr($_,1)} = $evalSpecials->{$_}; } keys %{$evalSpecials}; } @@ -849,6 +851,8 @@ AnalyzeCommand($$) $fn = $cmds{$fn}{ReplacedBy} if(defined($cmds{$fn}) && defined($cmds{$fn}{ReplacedBy})); + return( "Forbidden command $fn." ) if( $allowed && $allowed !~ m/\b$fn\b/ ); + ############# # autoload commands. if(!defined($cmds{$fn}) || !defined($cmds{$fn}{Fn})) {