2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-10 09:16:53 +00:00

96_allowed.pm: multi-allowed changes (Forum #92423)

git-svn-id: https://svn.fhem.de/fhem/trunk@17613 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2018-10-24 15:37:39 +00:00
parent 152f62c95d
commit 5a6ee78379
3 changed files with 59 additions and 25 deletions

View File

@ -1,5 +1,6 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # 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. # Do not insert empty lines here, update check depends on it.
- feature: allowed: multi-allowed changes (Forum #92423)
- feature: 93_DbRep: V8.4.0, reduceLog from DbLog integrated into DbRep, - feature: 93_DbRep: V8.4.0, reduceLog from DbLog integrated into DbRep,
sqlCmd/dbValue with textField-long as default, both sqlCmd/dbValue with textField-long as default, both
attributes timeOlderThan / timeDiffToNow can be set, attributes timeOlderThan / timeDiffToNow can be set,

View File

@ -8,7 +8,7 @@ use vars qw(@FW_httpheader); # HTTP header, line by line
use MIME::Base64; use MIME::Base64;
my $allowed_haveSha; my $allowed_haveSha;
sub allowed_CheckBasicAuth($$$$@); sub allowed_CheckBasicAuth($$$$);
##################################### #####################################
sub sub
@ -26,10 +26,11 @@ allowed_Initialize($)
allowedCommands allowedCommands
allowedDevices allowedDevices
allowedDevicesRegexp allowedDevicesRegexp
allowedIfAuthenticatedByMe:1,0
basicAuth basicAuth
basicAuthExpiry basicAuthExpiry
basicAuthMsg basicAuthMsg
disable:0,1 disable:1,0
globalpassword globalpassword
password password
validFor validFor
@ -90,6 +91,9 @@ allowed_Authorize($$$$)
} else { } else {
return 0 if(!$me->{validFor} || $me->{validFor} !~ m/\b$cl->{NAME}\b/); return 0 if(!$me->{validFor} || $me->{validFor} !~ m/\b$cl->{NAME}\b/);
} }
return 0 if(AttrVal($me->{NAME}, "allowedIfAuthenticatedByMe", 0) &&
(!$cl->{AuthenticatedBy} ||
$cl->{AuthenticatedBy} ne $me->{NAME}));
if($type eq "cmd") { if($type eq "cmd") {
return 0 if(!$me->{allowedCommands}); return 0 if(!$me->{allowedCommands});
@ -121,6 +125,13 @@ allowed_Authenticate($$$$)
{ {
my ($me, $cl, $param) = @_; my ($me, $cl, $param) = @_;
my $doReturn = sub($$){
my ($r,$a) = @_;
$cl->{AuthenticatedBy} = $me->{NAME} if($r == 1);
$cl->{AuthenticationDeniedBy} = $me->{NAME} if($r == 2 && $a);
return $r;
};
return 0 if($me->{disabled}); return 0 if($me->{disabled});
return 0 if(!$me->{validFor} || $me->{validFor} !~ m/\b$cl->{SNAME}\b/); return 0 if(!$me->{validFor} || $me->{validFor} !~ m/\b$cl->{SNAME}\b/);
my $aName = $me->{NAME}; my $aName = $me->{NAME};
@ -145,7 +156,7 @@ allowed_Authenticate($$$$)
} }
} }
my $pwok = (allowed_CheckBasicAuth($me, $cl, $secret, $basicAuth, 0) == 1); my $pwok = (allowed_CheckBasicAuth($me, $cl, $secret, $basicAuth) == 1);
# Add Cookie header ONLY if authentication with basicAuth was succesful # Add Cookie header ONLY if authentication with basicAuth was succesful
if($pwok && (!defined($authcookie) || $secret ne $authcookie)) { if($pwok && (!defined($authcookie) || $secret ne $authcookie)) {
@ -168,12 +179,12 @@ allowed_Authenticate($$$$)
} }
} }
return 1 if($pwok); return &$doReturn(1, 1) if($pwok);
my $msg = AttrVal($aName, "basicAuthMsg", "FHEM: login required"); my $msg = AttrVal($aName, "basicAuthMsg", "FHEM: login required");
$cl->{".httpAuthHeader"} = "HTTP/1.1 401 Authorization Required\r\n". $cl->{".httpAuthHeader"} = "HTTP/1.1 401 Authorization Required\r\n".
"WWW-Authenticate: Basic realm=\"$msg\"\r\n"; "WWW-Authenticate: Basic realm=\"$msg\"\r\n";
return 2; return &$doReturn(2, $secret);
} elsif($cl->{TYPE} eq "telnet") { } elsif($cl->{TYPE} eq "telnet") {
my $pw = AttrVal($aName, "password", undef); my $pw = AttrVal($aName, "password", undef);
@ -188,30 +199,31 @@ allowed_Authenticate($$$$)
my $password = $param; my $password = $param;
my $ret = eval $pw; my $ret = eval $pw;
Log3 $aName, 1, "password expression: $@" if($@); Log3 $aName, 1, "password expression: $@" if($@);
return ($ret ? 1 : 2); return &$doReturn($ret ? 1 : 2, $param);
} elsif($pw =~ m/^SHA256:(.{8}):(.*)$/) { } elsif($pw =~ m/^SHA256:(.{8}):(.*)$/) {
if($allowed_haveSha) { if($allowed_haveSha) {
return (Digest::SHA::sha256_base64("$1:$param") eq $2) ? 1 : 2; return &$doReturn(Digest::SHA::sha256_base64("$1:$param") eq $2 ?
1 : 2, $param);
} else { } else {
Log3 $me, 3, "Cant load Digest::SHA to decode $me->{NAME} beiscAuth"; Log3 $me, 3, "Cant load Digest::SHA to decode $me->{NAME} beiscAuth";
} }
} }
return ($pw eq $param) ? 1 : 2; return &$doReturn(($pw eq $param) ? 1 : 2, $param);
} else { } else {
$param =~ m/^basicAuth:(.*)/ if($param); $param =~ m/^basicAuth:(.*)/ if($param);
return allowed_CheckBasicAuth($me, $cl, $1, return &$doReturn(allowed_CheckBasicAuth($me, $cl, $1,
AttrVal($aName,"basicAuth",undef), $param); AttrVal($aName,"basicAuth",undef)), $param);
} }
} }
sub sub
allowed_CheckBasicAuth($$$$@) allowed_CheckBasicAuth($$$$)
{ {
my ($me, $cl, $secret, $basicAuth, $verbose) = @_; my ($me, $cl, $secret, $basicAuth) = @_;
return 0 if(!$basicAuth); return 0 if(!$basicAuth);
@ -239,8 +251,7 @@ allowed_CheckBasicAuth($$$$@)
} }
} }
Log3 $me, 3, "Login denied by $aName for $user via $cl->{NAME}" $cl->{AuthenticatedUser} = $user if($user);
if($pwok != 1 && ($verbose || $user));
return $pwok; return $pwok;
} }
@ -427,18 +438,15 @@ EOF
</li><br> </li><br>
<a name="allowedDevicesRegexp"></a> <a name="allowedDevicesRegexp"></a>
<li>allowedDevices<br> <li>allowedDevicesRegexp<br>
Comma separated list of device names which can be manipulated via the Regexp to match the devicenames, which can be manipulated. The regexp
frontends specified by validFor. The regexp is prepended with ^ and is prepended with ^ and suffixed with $, as usual.
suffixed with $, as usual. Only devices listed in allowedDevices or
matching allowedDevicesRegexp may manipulated.
</li><br> </li><br>
<a name="allowedDevicesRegexp"></a> <a name="allowedIfAuthenticatedByMe"></a>
<li>allowedDevicesRegexp<br> <li>allowedIfAuthenticatedByMe<br>
A regexp to match device names which can be manipulated via the if set (to 1), then the allowed parameters will only be checked, if the
frontends specified by validFor. Only devices listed in allowedDevices authentication was executed by this allowed instance.
or matching allowedDevicesRegexp may manipulated.
</li><br> </li><br>
<a name="basicAuth"></a> <a name="basicAuth"></a>
@ -581,6 +589,19 @@ EOF
Frontend (siehe validFor) ge&auml;ndert werden k&ouml;nnen. Frontend (siehe validFor) ge&auml;ndert werden k&ouml;nnen.
</li><br> </li><br>
<a name="allowedDevicesRegexp"></a>
<li>allowedDevicesRegexp<br>
Regexp um die Ger&auml;te zu spezifizieren, die man bearbeiten darf.
Das Regexp wird (wie in FHEM &uuml;blich) mit ^ und $ erg&auml;nzt.
</li><br>
<a name="allowedIfAuthenticatedByMe"></a>
<li>allowedIfAuthenticatedByMe<br>
falls gesetzt (auf 1), dann werden die allowed Attribute nur dann
angewendet, falls auch die Authentifikation durch diese allowed Instanz
durchgef&uuml;hrt wurde.
</li><br>
<a name="basicAuth"></a> <a name="basicAuth"></a>
<li>basicAuth, basicAuthMsg<br> <li>basicAuth, basicAuthMsg<br>
Erzwingt eine Authentifizierung mit Benutzername/Passwort f&uuml;r die Erzwingt eine Authentifizierung mit Benutzername/Passwort f&uuml;r die

View File

@ -5390,8 +5390,20 @@ Authenticate($$)
foreach my $a (@authenticate) { foreach my $a (@authenticate) {
my $r = CallFn($a, "AuthenticateFn", $defs{$a}, $cl, $arg); my $r = CallFn($a, "AuthenticateFn", $defs{$a}, $cl, $arg);
$needed = $r if($r); $needed = $r if($r);
return $r if($r == 1); last if($r == 1);
} }
if($needed == 2 && $cl->{NAME} ne "SecurityCheck") {
my $adb = $cl->{AuthenticationDeniedBy};
if($adb) {
my $au = $cl->{AuthenticatedUser};
Log3 $adb, 3, "Login denied ".
($au ? "for user >$au< ":"")."via $cl->{NAME}";
}
} else {
delete $cl->{AuthenticationDeniedBy};
}
return $needed; return $needed;
} }