From d70bb6273b7aaf9a20e5652f0430de2c7765629a Mon Sep 17 00:00:00 2001
From: rudolfkoenig <>
Date: Wed, 30 Dec 2015 09:11:46 +0000
Subject: [PATCH] fhem.pl: Slight authorize/authenticate mods (Forum #46380)
git-svn-id: https://svn.fhem.de/fhem/trunk@10305 2b470e98-0d58-463d-a4d8-8e2adae1ed80
---
fhem/FHEM/96_allowed.pm | 23 ++++++++++++++++++-----
fhem/FHEM/98_JsonList2.pm | 4 ++--
fhem/FHEM/98_XmlList.pm | 9 +++------
fhem/fhem.pl | 10 +++++++---
4 files changed, 30 insertions(+), 16 deletions(-)
diff --git a/fhem/FHEM/96_allowed.pm b/fhem/FHEM/96_allowed.pm
index fc7b907f1..bb35f84a4 100755
--- a/fhem/FHEM/96_allowed.pm
+++ b/fhem/FHEM/96_allowed.pm
@@ -59,12 +59,13 @@ allowed_Authorize($$$$)
if($type eq "cmd") {
return 0 if(!$me->{allowedCommands});
- return ($me->{allowedCommands} =~ m/\b$arg\b/) ? 1 : 2;
+ # Return 0: allow stacking with other instances, see Forum#46380
+ return ($me->{allowedCommands} =~ m/\b$arg\b/) ? 0 : 2;
}
if($type eq "devicename") {
return 0 if(!$me->{allowedDevices});
- return ($me->{allowedDevices} =~ m/\b$arg\b/) ? 1 : 2;
+ return ($me->{allowedDevices} =~ m/\b$arg\b/) ? 0 : 2;
}
return 0;
@@ -182,7 +183,12 @@ allowed_Attr(@)
define <name> allowed <deviceList>
Authorize execution of commands and modification of devices based on the
- frontend used.
+ frontend used and/or authenticate users.
+
+ If there are multiple instances defined, which are valid for a given
+ frontend device, then all authorizations must succeed. For authentication
+ it is sufficient when one of the instances succeeds.
+
Note: this module should work as intended, but no guarantee
can be given that there is no way to circumvent it.
Examples:
@@ -316,10 +322,17 @@ allowed_Attr(@)
Authorisiert das Ausführen von Kommandos oder das Ändern von
Geräten abhängig vom verwendeten Frontend.
+ Falls man mehrere allowed Instanzen definiert hat, die für dasselbe
+ Frontend verantwortlich sind, dann müssen alle Authorisierungen
+ genehmigt sein, um das Befehl ausführen zu können. Auf der
+ anderen Seite reicht es, wenn einer der Authentifizierungen positiv
+ entschieden wird. Die Prüfungen werden in alphabetischer Reihenfolge
+ der Instanznamen ausgeführt.
+
Achtung: das Modul sollte wie hier beschrieben funktionieren,
allerdings können wir keine Garantie geben, daß man sie nicht
- überlisten, und Schaden anrichten kann.
-
+ überlisten, und Schaden anrichten kann.
+
Beispiele:
define allowedWEB allowed
diff --git a/fhem/FHEM/98_JsonList2.pm b/fhem/FHEM/98_JsonList2.pm
index b6968cab6..c9b1f9353 100644
--- a/fhem/FHEM/98_JsonList2.pm
+++ b/fhem/FHEM/98_JsonList2.pm
@@ -81,10 +81,10 @@ CommandJsonList2($$)
if($param) {
my @arg = split(" ", $param);
$attr = $arg[1];
- @d = devspec2array($arg[0]);
+ @d = devspec2array($arg[0],$cl);
} else {
- @d = keys %defs;
+ @d = devspec2array(".*", $cl); # Needed for Authorization
$param="";
}
diff --git a/fhem/FHEM/98_XmlList.pm b/fhem/FHEM/98_XmlList.pm
index a1d98d45e..0d7babf94 100644
--- a/fhem/FHEM/98_XmlList.pm
+++ b/fhem/FHEM/98_XmlList.pm
@@ -47,17 +47,14 @@ CommandXmlList($$)
my $lt = "";
my %filter;
- if($param) {
- my @arr = devspec2array($param);
- map { $filter{$_} = 1 } @arr;
- }
- delete($modules{""}) if(defined($modules{""})); # ???
+ my @arr = devspec2array($param ? $param : ".*", $cl); # for Authorize
+ map { $filter{$_} = 1 } @arr;
for my $d (sort { my $x = $modules{$defs{$a}{TYPE}}{ORDER}.$defs{$a}{TYPE} cmp
$modules{$defs{$b}{TYPE}}{ORDER}.$defs{$b}{TYPE};
$x = ($a cmp $b) if($x == 0); $x; } keys %defs) {
- next if(IsIgnored($d) || (%filter && !$filter{$d}));
+ next if(IsIgnored($d) || !$filter{$d});
my $p = $defs{$d};
my $t = $p->{TYPE};
if($t ne $lt) {
diff --git a/fhem/fhem.pl b/fhem/fhem.pl
index f83a3ff7a..9e5aa836f 100755
--- a/fhem/fhem.pl
+++ b/fhem/fhem.pl
@@ -2115,7 +2115,7 @@ CommandList($$)
for my $d (sort { my $x=$modules{$defs{$a}{TYPE}}{ORDER}.$defs{$a}{TYPE} cmp
$modules{$defs{$b}{TYPE}}{ORDER}.$defs{$b}{TYPE};
$x=($a cmp $b) if($x == 0); $x; } keys %defs) {
- next if(IsIgnored($d));
+ next if(IsIgnored($d) || ($cl && !Authorized($cl,"devicename",$d)));
my $t = $defs{$d}{TYPE};
$str .= "\n$t:\n" if($t ne $lt);
$str .= sprintf(" %-20s (%s)\n", $d, $defs{$d}{STATE});
@@ -4537,6 +4537,7 @@ Each($$;$) # can be used e.g. in at, Forum #40022
##################
# Return 1 if Authorized, else 0
+# Note: AuthorizeFn's returning 1 are not stackable.
sub
Authorized($$$)
{
@@ -4555,6 +4556,7 @@ Authorized($$$)
##################
# Return 0 if not needed, 1 if authenticated, 2 if authentication failed
+# Loop until one Authenticate is ok
sub
Authenticate($$)
{
@@ -4563,11 +4565,13 @@ Authenticate($$)
return 1 if(!$init_done || !$cl || !$cl->{SNAME}); # Safeguarding
RefreshAuthList() if($auth_refresh);
+ my $needed = 0;
foreach my $a (@authenticate) {
my $r = CallFn($a, "AuthenticateFn", $defs{$a}, $cl, $arg);
- return $r if($r);
+ $needed = $r if($r);
+ return $r if($r == 1);
}
- return 0;
+ return $needed;
}
sub