From 6d26b4c934eb33af428b04fa7384500c163ddfa0 Mon Sep 17 00:00:00 2001 From: rudolfkoenig <> Date: Tue, 29 Dec 2015 19:08:19 +0000 Subject: [PATCH] 96_allowed.pm: Authorization/Authentication modularized git-svn-id: https://svn.fhem.de/fhem/trunk@10298 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 10 +- fhem/FHEM/01_FHEMWEB.pm | 236 ++++++--------- fhem/FHEM/96_allowed.pm | 446 +++++++++++++++++++++++++++++ fhem/FHEM/98_telnet.pm | 179 ++++-------- fhem/docs/commandref_frame.html | 1 + fhem/docs/commandref_frame_DE.html | 1 + fhem/fhem.pl | 81 +++++- 7 files changed, 666 insertions(+), 288 deletions(-) create mode 100755 fhem/FHEM/96_allowed.pm diff --git a/fhem/CHANGED b/fhem/CHANGED index 9f459f5ee..0aed52271 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,12 +1,14 @@ # 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. + - feature: allowed module added. allowedCommands, basicAuth, password, + globalpassword attributes moved to this module. - bugfix: YAMAHA_AVR: fixing not working volumeStraight set command - change: FB_CALLLIST: start call processing only when "event:" is triggered by corresponding FB_CALLMONITOR device. - - change: FB_CALLMONITOR: default value for attr fritzbox-remote-phonebook-via - has been changed to "tr064" (previous: "web") to ensure - no problems with new Fritz!OS web layout. - Besides TR-064 is official supported by AVM. + - change: FB_CALLMONITOR: default value for attr + fritzbox-remote-phonebook-via has been changed to "tr064" + (previous: "web") to ensure no problems with new Fritz!OS web + layout. Besides TR-064 is official supported by AVM. - feature: PHILIPS_AUDIO: Favorite station selection - feature: YAMAHA_AVR: new set commands and readings for tuner control - new set commands tunerFrequency,tunerPreset for diff --git a/fhem/FHEM/01_FHEMWEB.pm b/fhem/FHEM/01_FHEMWEB.pm index 90d4669ce..7f8349633 100755 --- a/fhem/FHEM/01_FHEMWEB.pm +++ b/fhem/FHEM/01_FHEMWEB.pm @@ -218,10 +218,22 @@ FW_SecurityCheck($$) !grep(m/^INITIALIZED$/, @{$dev->{CHANGED}})); my $motd = AttrVal("global", "motd", ""); if($motd =~ "^SecurityCheck") { - my @list = grep { !AttrVal($_, "basicAuth", undef) } - devspec2array("TYPE=FHEMWEB"); - $motd .= (join(",", sort @list)." has no basicAuth attribute.\n") - if(@list); + 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"; @@ -362,44 +374,24 @@ FW_Read($$) ############################# - # BASIC HTTP AUTH - my @headerOptions = grep /OPTIONS/, @FW_httpheader; # Need example - my $basicAuth = AttrVal($FW_wname, "basicAuth", undef); - if($basicAuth) { - my $secret = $FW_httpheader{Authorization}; - $secret =~ s/^Basic //i if($secret); - my $pwok = ($secret && $secret eq $basicAuth); - if($secret && $basicAuth =~ m/^{.*}$/ || $headerOptions[0]) { - eval "use MIME::Base64"; - if($@) { - Log3 $FW_wname, 1, $@; + # AUTH + if(!defined($FW_chash->{Authenticated})) { + my $ret = Authenticate($FW_chash, \%FW_httpheader); + if($ret == 0) { + $FW_chash->{Authenticated} = 0; # not needed - } else { - my ($user, $password) = split(":", decode_base64($secret)); - $pwok = eval $basicAuth; - Log3 $FW_wname, 1, "basicAuth expression: $@" if($@); - } + } elsif($ret == 1) { + $FW_chash->{Authenticated} = 1; # ok + + } else { + TcpServer_WriteBlocking($hash, + $FW_chash->{".httpAuthHeader"}. + $FW_headercors. + "Content-Length: 0\r\n\r\n"); + delete $hash->{CONTENT_LENGTH}; + FW_Read($hash, 1) if($hash->{BUF}); + return; } - if($headerOptions[0]) { - TcpServer_WriteBlocking($hash, - "HTTP/1.1 200 OK\r\n". - $FW_headercors. - "Content-Length: 0\r\n\r\n"); - delete $hash->{CONTENT_LENGTH}; - FW_Read($hash, 1) if($hash->{BUF}); - return; - }; - if(!$pwok) { - my $msg = AttrVal($FW_wname, "basicAuthMsg", "Fhem: login required"); - TcpServer_WriteBlocking($hash, - "HTTP/1.1 401 Authorization Required\r\n". - "WWW-Authenticate: Basic realm=\"$msg\"\r\n". - $FW_headercors. - "Content-Length: 0\r\n\r\n"); - delete $hash->{CONTENT_LENGTH}; - FW_Read($hash, 1) if($hash->{BUF}); - return; - }; } ############################# @@ -1847,8 +1839,7 @@ FW_style($$) my ($cmd, $msg) = @_; my @a = split(" ", $cmd); - my $ac = AttrVal($FW_wname,"allowedCommands",""); - return if($ac && $ac !~ m/\b$a[0]\b/); + return if(!Authorized($FW_chash, "cmd", $a[0])); my $start = "
"; my $end = "
"; @@ -2173,11 +2164,9 @@ FW_fC($@) my ($cmd, $unique) = @_; my $ret; if($unique) { - $ret = AnalyzeCommand($FW_chash, $cmd, - AttrVal($FW_wname,"allowedCommands",undef)); + $ret = AnalyzeCommand($FW_chash, $cmd); } else { - $ret = AnalyzeCommandChain($FW_chash, $cmd, - AttrVal($FW_wname,"allowedCommands",undef)); + $ret = AnalyzeCommandChain($FW_chash, $cmd); } return $ret; } @@ -2185,52 +2174,65 @@ FW_fC($@) sub FW_Attr(@) { - my @a = @_; - my $hash = $defs{$a[1]}; - my $name = $hash->{NAME}; + my ($type, $devName, $attrName, @param) = @_; + my $hash = $defs{$devName}; my $sP = "stylesheetPrefix"; my $retMsg; - if($a[0] eq "set" && $a[2] eq "HTTPS") { + if($type eq "set" && $attrName eq "HTTPS") { TcpServer_SetSSL($hash); } - if($a[0] eq "set") { # Converting styles - if($a[2] eq "smallscreen" || $a[2] eq "touchpad") { - $attr{$name}{$sP} = $a[2]; - $retMsg="$name: attribute $a[2] deprecated, converted to $sP"; - $a[3] = $a[2]; $a[2] = $sP; - } - } - if($a[2] eq $sP) { - # AttrFn is called too early, we have to set/del the attr here - if($a[0] eq "set") { - $attr{$name}{$sP} = (defined($a[3]) ? $a[3] : "default"); - FW_readIcons($attr{$name}{$sP}); - } else { - delete $attr{$name}{$sP}; + if($type eq "set") { # Converting styles + if($attrName eq "smallscreen" || $attrName eq "touchpad") { + $attr{$devName}{$sP} = $attrName; + $retMsg="$devName: attribute $attrName deprecated, converted to $sP"; + $param[0] = $attrName; $attrName = $sP; } } - if($a[2] eq "iconPath" && $a[0] eq "set") { - foreach my $pe (split(":", $a[3])) { + if($attrName eq $sP) { + # AttrFn is called too early, we have to set/del the attr here + if($type eq "set") { + $attr{$devName}{$sP} = (defined($param[0]) ? $param[0] : "default"); + FW_readIcons($attr{$devName}{$sP}); + } else { + delete $attr{$devName}{$sP}; + } + } + + if(($attrName eq "allowedCommands" || + $attrName eq "basicAuth" || + $attrName eq "basicAuthMsg") + && $type eq "set") { + my $aName = "allowed_$devName"; + my $exists = ($defs{$aName} ? 1 : 0); + AnalyzeCommand(undef, "defmod $aName allowed"); + AnalyzeCommand(undef, "attr $aName validFor $devName"); + AnalyzeCommand(undef, "attr $aName $attrName ".join(" ",@param)); + return "$devName: ".($exists ? "modifying":"creating"). + " device $aName for attribute $attrName"; + } + + if($attrName eq "iconPath" && $type eq "set") { + foreach my $pe (split(":", $param[0])) { $pe =~ s+\.\.++g; FW_readIcons($pe); } } - if($a[2] eq "JavaScripts" && $a[0] eq "set") { # create some attributes + if($attrName eq "JavaScripts" && $type eq "set") { # create some attributes my (%a, @add); map { $a{$_} = 1 } split(" ", $modules{FHEMWEB}{AttrList}); map { $_ =~ s+.*/++; $_ =~ s/.js$//; $_ =~ s/fhem_//; $_ .= "Param"; push @add, $_ if(!$a{$_} && $_ !~ m/^-/); - } split(" ", $a[3]); + } split(" ", $param[0]); $modules{FHEMWEB}{AttrList} .= " ".join(" ",@add) if(@add); } - if($a[2] eq "csrfToken" && $a[0] eq "set") { - my $csrf = $a[3]; + if($attrName eq "csrfToken" && $type eq "set") { + my $csrf = $param[0]; if($csrf eq "random") { my ($x,$y) = gettimeofday(); $csrf = rand($y)*rand($x); @@ -2238,7 +2240,7 @@ FW_Attr(@) $hash->{CSRFTOKEN} = $csrf; } - if($a[2] eq "csrfToken" && $a[0] eq "del") { + if($attrName eq "csrfToken" && $type eq "del") { delete($hash->{CSRFTOKEN}); } @@ -2937,50 +2939,13 @@ FW_widgetOverride($$)