diff --git a/CHANGED b/CHANGED index 125d708d8..85b8a78fa 100644 --- a/CHANGED +++ b/CHANGED @@ -47,6 +47,7 @@ - feature: time and internet helper routines added to fhem.pl (Boris) - change: separating common functions used by the FHEM modules into *Utils.pm files from fhem.pl + - feature: portpassword and basicAuth may use evaluated functions - 2011-12-31 (5.2) - bugfix: applying smallscreen attributes to firefox/opera diff --git a/FHEM/FritzBoxUtils.pm b/FHEM/FritzBoxUtils.pm new file mode 100644 index 000000000..72d10cfff --- /dev/null +++ b/FHEM/FritzBoxUtils.pm @@ -0,0 +1,49 @@ +############################################## +# $Id: FritzBoxUtils.pm 1148 2011-12-28 19:21:19Z rudolfkoenig $ +package main; + +use strict; +use warnings; +use Digest::MD5 "md5_hex"; +use HttpUtils; + +my ($lastOkPw, $lastOkTime) =("", 0); + +sub +FB_getPage($$$) +{ + my ($host, $pw, $page) = @_; + my $data = GetFileFromURL("http://$host". + "/cgi-bin/webcm?getpage=../html/login_sid.xml", undef, undef, 1); + return undef if(!$data); + my $chl; + $chl = $1 if($data =~ /(\w+)<\/Challenge>/i); + my $chlAnsw .= "$chl-$pw"; + $chlAnsw =~ s/(.)/$1.chr(0)/eg; # works probably only with ascii + $chlAnsw = "$chl-".lc(md5_hex($chlAnsw)); + my @d = ( "login:command/response=$chlAnsw", "getpage=$page" ); + $data = join("&", map {join("=", map {urlEncode($_)} split("=",$_,2))} @d); + return GetFileFromURL("http://$host/cgi-bin/webcm", undef, $data, 1); +} + +sub +FB_checkPw($$) +{ + my ($host, $pw) = @_; + my $now = time(); + + return 1 if($lastOkPw eq $pw && ($now - $lastOkTime) < 300); # 5min cache + + my $data = FB_getPage($host, $pw, "../html/de/internet/connect_status.txt"); + + if(defined($data) && $data =~ m/"checkStatus":/) { + $lastOkPw = $pw; $lastOkTime = $now; + return 1; + + } else { + return 0; + + } +} + +1; diff --git a/FHEM/HttpUtils.pm b/FHEM/HttpUtils.pm index ebc4d22f0..52f25138c 100644 --- a/FHEM/HttpUtils.pm +++ b/FHEM/HttpUtils.pm @@ -22,7 +22,7 @@ sub GetFileFromURL($@) { my ($url, $timeout, $data, $noshutdown) = @_; - $timeout = 2.0 if(!defined($timeout)); + $timeout = 4.0 if(!defined($timeout)); if($url !~ /^(http):\/\/([^:\/]+)(:\d+)?(\/.*)$/) { Log 1, "GetFileFromURL $url: malformed URL"; diff --git a/TODO b/TODO index a4700ea87..1a0cf76fc 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,8 @@ FHEM: +- FHEMWEB warning +- finish updatefhem +- autoload commands -> rename updatefhem, CULflash, etc + - FHEM2FHEM reconnect - HomeMatic set log 2 - implement wiki decisions diff --git a/docs/commandref.html b/docs/commandref.html index cfc3ab604..370e6932b 100644 --- a/docs/commandref.html +++ b/docs/commandref.html @@ -1340,7 +1340,15 @@ A line ending with \ will be concatenated with the next one, so long lines
  • portpassword
    Specify a port password, which has to be entered as the very first - string after the connection is established. + string after the connection is established. If the argument is enclosed + in {}, then it will be evaluated, and the $password variable will be + set to the password entered. If the return value is true, then the + password will be accepted. + Example:
    + + attr global portpassword secret
    + attr global portpassword {use FritzBoxUtils;;FB_checkPw("localhost","$password") } +

  • @@ -8519,7 +8527,19 @@ KlikAanKlikUit, NEXA, CHACON, HomeEasy UK.
    You need to define an RFXtrx433 You can of course use other means of base64 encoding, e.g. online Base64 encoders. If basicAuthMsg is set, it will be displayed in the - popup window when requesting the username/password. + popup window when requesting the username/password.
    +
    + If the argument of basicAuth is enclosed in {}, then it will be + evaluated, and the $user and $password variable will be set to the + values entered. If the return value is true, then the password will be + accepted. + Example:
    + + attr WEB basicAuth { "$user:$password" eq "admin:secret" }
    + attr WEB basicAuth {use FritzBoxUtils;;FB_checkPw("localhost","$password") } +
    + +
    diff --git a/fhem.pl b/fhem.pl index 28157a052..dd41ced19 100755 --- a/fhem.pl +++ b/fhem.pl @@ -652,7 +652,15 @@ AnalyzeInput($) if($attr{global}{portpassword} && !$client{$c}{pwEntered}) { syswrite($client{$c}{fd}, sprintf("%c%c%c\r\n", 255, 252, 1)); # WONT ECHO - if($attr{global}{portpassword} eq $cmd) { + + my $ret = ($attr{global}{portpassword} eq $cmd); + if($attr{global}{portpassword} =~ m/^{.*}$/) { # Expression as pw + my $password = $cmd; + $ret = eval $attr{global}{portpassword}; + Log 1, "portpasswd expression: $@" if($@); + } + + if($ret) { $client{$c}{pwEntered} = 1; next; } else { diff --git a/webfrontend/pgm2/01_FHEMWEB.pm b/webfrontend/pgm2/01_FHEMWEB.pm index 8bb3a0dee..1cf552da8 100755 --- a/webfrontend/pgm2/01_FHEMWEB.pm +++ b/webfrontend/pgm2/01_FHEMWEB.pm @@ -268,15 +268,27 @@ FW_Read($) $hash->{BUF} .= $buf; return if($hash->{BUF} !~ m/\n\n$/ && $hash->{BUF} !~ m/\r\n\r\n$/); - #Log 0, "Got: >$hash->{BUF}<"; @FW_httpheader = split("[\r\n]", $hash->{BUF}); ############################# # BASIC HTTP AUTH my $basicAuth = AttrVal($FW_wname, "basicAuth", undef); if($basicAuth) { - my @auth = grep /^Authorization: Basic $basicAuth/, @FW_httpheader; - if(!@auth) { + $hash->{BUF} =~ m/^Authorization: Basic (.*)/m; + my $secret = $1; + my $pwok = ($secret && $secret eq $basicAuth); + if($secret && $basicAuth =~ m/^{.*}$/) { + eval "use MIME::Base64"; + if($@) { + Log 1, $@; + + } else { + my ($user, $password) = split(":", decode_base64($secret)); + $pwok = eval $basicAuth; + Log 1, "basicAuth expression: $@" if($@); + } + } + if(!$pwok) { my $msg = AttrVal($FW_wname, "basicAuthMsg", "Fhem: login required"); print $c "HTTP/1.1 401 Authorization Required\r\n", "WWW-Authenticate: Basic realm=\"$msg\"\r\n", @@ -628,7 +640,6 @@ FW_makeTable($$@) next if($r && ($r ne "HASH" || !defined($hash->{$n}{VAL}))); pF "", ($row&1)?"odd":"even"; $row++; - my $val = $hash->{$n}; if($n eq "DEF" && !$FW_hiddenroom{input}) { @@ -1542,8 +1553,7 @@ FW_style($$) my @fl = ("fhem.cfg"); push(@fl, ""); - #push(@fl, FW_fileList("$FW_dir/.*(sh|Util.*|cfg|holiday)")); - push(@fl, FW_fileList("$MW_dir/.*(sh|Util.*|cfg|holiday)")); + push(@fl, FW_fileList("$MW_dir/.*(sh|[0-9].*Util.*|cfg|holiday)")); push(@fl, ""); push(@fl, FW_fileList("$FW_dir/.*.(css|svg)")); push(@fl, "");