96_allowed.pm 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. ##############################################
  2. # $Id: 96_allowed.pm 17506 2018-10-11 11:01:44Z rudolfkoenig $
  3. package main;
  4. use strict;
  5. use warnings;
  6. use vars qw(@FW_httpheader); # HTTP header, line by line
  7. use MIME::Base64;
  8. my $allowed_haveSha;
  9. sub allowed_CheckBasicAuth($$$$@);
  10. #####################################
  11. sub
  12. allowed_Initialize($)
  13. {
  14. my ($hash) = @_;
  15. $hash->{DefFn} = "allowed_Define";
  16. $hash->{AuthorizeFn} = "allowed_Authorize";
  17. $hash->{AuthenticateFn} = "allowed_Authenticate";
  18. $hash->{SetFn} = "allowed_Set";
  19. $hash->{AttrFn} = "allowed_Attr";
  20. no warnings 'qw';
  21. my @attrList = qw(
  22. allowedCommands
  23. allowedDevices
  24. allowedDevicesRegexp
  25. basicAuth
  26. basicAuthExpiry
  27. basicAuthMsg
  28. disable:0,1
  29. globalpassword
  30. password
  31. validFor
  32. );
  33. use warnings 'qw';
  34. $hash->{AttrList} = join(" ", @attrList)." ".$readingFnAttributes;
  35. $hash->{UndefFn} = "allowed_Undef";
  36. $hash->{FW_detailFn} = "allowed_fhemwebFn";
  37. eval { require Digest::SHA; };
  38. if($@) {
  39. Log3 $hash, 4, $@;
  40. $allowed_haveSha = 0;
  41. } else {
  42. $allowed_haveSha = 1;
  43. }
  44. }
  45. #####################################
  46. sub
  47. allowed_Define($$)
  48. {
  49. my ($hash, $def) = @_;
  50. my @l = split(" ", $def);
  51. if(@l > 2) {
  52. my %list;
  53. for(my $i=2; $i<@l; $i++) {
  54. $list{$l[$i]} = 1;
  55. }
  56. $hash->{devices} = \%list;
  57. }
  58. $auth_refresh = 1;
  59. readingsSingleUpdate($hash, "state", "validFor:", 0);
  60. SecurityCheck() if($init_done);
  61. return undef;
  62. }
  63. sub
  64. allowed_Undef($$)
  65. {
  66. $auth_refresh = 1;
  67. return undef;
  68. }
  69. #####################################
  70. # Return 0 for don't care, 1 for Allowed, 2 for forbidden.
  71. sub
  72. allowed_Authorize($$$$)
  73. {
  74. my ($me, $cl, $type, $arg) = @_;
  75. return 0 if($me->{disabled});
  76. if( $cl->{SNAME} ) {
  77. return 0 if(!$me->{validFor} || $me->{validFor} !~ m/\b$cl->{SNAME}\b/);
  78. } else {
  79. return 0 if(!$me->{validFor} || $me->{validFor} !~ m/\b$cl->{NAME}\b/);
  80. }
  81. if($type eq "cmd") {
  82. return 0 if(!$me->{allowedCommands});
  83. # Return 0: allow stacking with other instances, see Forum#46380
  84. return 0 if($me->{allowedCommands} =~ m/\b\Q$arg\E\b/);
  85. Log3 $me, 3, "Forbidden command $arg for $cl->{NAME}";
  86. stacktrace() if(AttrVal($me, "verbose", 5));
  87. return 2;
  88. }
  89. if($type eq "devicename") {
  90. return 0 if(!$me->{allowedDevices} &&
  91. !$me->{allowedDevicesRegexp});
  92. return 1 if($me->{allowedDevices} &&
  93. $me->{allowedDevices} =~ m/\b\Q$arg\E\b/);
  94. return 1 if($me->{allowedDevicesRegexp} &&
  95. $arg =~ m/^$me->{allowedDevicesRegexp}$/);
  96. Log3 $me, 3, "Forbidden device $arg for $cl->{NAME}";
  97. stacktrace() if(AttrVal($me, "verbose", 5));
  98. return 2;
  99. }
  100. return 0;
  101. }
  102. #####################################
  103. # Return 0 for authentication not needed, 1 for auth-ok, 2 for wrong password
  104. sub
  105. allowed_Authenticate($$$$)
  106. {
  107. my ($me, $cl, $param) = @_;
  108. return 0 if($me->{disabled});
  109. return 0 if(!$me->{validFor} || $me->{validFor} !~ m/\b$cl->{SNAME}\b/);
  110. my $aName = $me->{NAME};
  111. if($cl->{TYPE} eq "FHEMWEB") {
  112. my $basicAuth = AttrVal($aName, "basicAuth", undef);
  113. delete $cl->{".httpAuthHeader"};
  114. return 0 if(!$basicAuth);
  115. return 2 if(!$param);
  116. my $FW_httpheader = $param;
  117. my $secret = $FW_httpheader->{Authorization};
  118. $secret =~ s/^Basic //i if($secret);
  119. # Check for Cookie in headers if no basicAuth header is set
  120. my $authcookie;
  121. if (!$secret && $FW_httpheader->{Cookie}) {
  122. if(AttrVal($aName, "basicAuthExpiry", 0)) {
  123. my $cookie = "; ".$FW_httpheader->{Cookie}.";";
  124. $authcookie = $1 if ( $cookie =~ /; AuthToken=([^;]+);/ );
  125. $secret = $authcookie;
  126. }
  127. }
  128. my $pwok = (allowed_CheckBasicAuth($me, $cl, $secret, $basicAuth, 0) == 1);
  129. # Add Cookie header ONLY if authentication with basicAuth was succesful
  130. if($pwok && (!defined($authcookie) || $secret ne $authcookie)) {
  131. my $time = AttrVal($aName, "basicAuthExpiry", 0);
  132. if ( $time ) {
  133. my ($user, $password) = split(":", decode_base64($secret)) if($secret);
  134. $time = int($time*86400+time());
  135. # generate timestamp according to RFC-1130 in Expires
  136. my $expires = FmtDateTimeRFC1123($time);
  137. readingsBeginUpdate($me);
  138. readingsBulkUpdate($me,'lastAuthUser', $user, 1);
  139. readingsBulkUpdate($me,'lastAuthExpires', $time, 1);
  140. readingsBulkUpdate($me,'lastAuthExpiresFmt', $expires, 1);
  141. readingsEndUpdate($me, 1);
  142. # set header with expiry
  143. $cl->{".httpAuthHeader"} = "Set-Cookie: AuthToken=".$secret.
  144. "; Path=/ ; Expires=$expires\r\n" ;
  145. }
  146. }
  147. return 1 if($pwok);
  148. my $msg = AttrVal($aName, "basicAuthMsg", "FHEM: login required");
  149. $cl->{".httpAuthHeader"} = "HTTP/1.1 401 Authorization Required\r\n".
  150. "WWW-Authenticate: Basic realm=\"$msg\"\r\n";
  151. return 2;
  152. } elsif($cl->{TYPE} eq "telnet") {
  153. my $pw = AttrVal($aName, "password", undef);
  154. if(!$pw) {
  155. $pw = AttrVal($aName, "globalpassword", undef);
  156. $pw = undef if($pw && $cl->{NAME} =~ m/_127.0.0.1_/);
  157. }
  158. return 0 if(!$pw);
  159. return 2 if(!defined($param));
  160. if($pw =~ m/^{.*}$/) {
  161. my $password = $param;
  162. my $ret = eval $pw;
  163. Log3 $aName, 1, "password expression: $@" if($@);
  164. return ($ret ? 1 : 2);
  165. } elsif($pw =~ m/^SHA256:(.{8}):(.*)$/) {
  166. if($allowed_haveSha) {
  167. return (Digest::SHA::sha256_base64("$1:$param") eq $2) ? 1 : 2;
  168. } else {
  169. Log3 $me, 3, "Cant load Digest::SHA to decode $me->{NAME} beiscAuth";
  170. }
  171. }
  172. return ($pw eq $param) ? 1 : 2;
  173. } else {
  174. $param =~ m/^basicAuth:(.*)/ if($param);
  175. return allowed_CheckBasicAuth($me, $cl, $1,
  176. AttrVal($aName,"basicAuth",undef), $param);
  177. }
  178. }
  179. sub
  180. allowed_CheckBasicAuth($$$$@)
  181. {
  182. my ($me, $cl, $secret, $basicAuth, $verbose) = @_;
  183. return 0 if(!$basicAuth);
  184. my $aName = $me->{NAME};
  185. my $pwok = ($secret && $secret eq $basicAuth) ? 1 : 2; # Base64
  186. my ($user, $password) = split(":", decode_base64($secret)) if($secret);
  187. ($user,$password) = ("","") if(!defined($user) || !defined($password));
  188. if($secret && $basicAuth =~ m/^{.*}$/) {
  189. $pwok = eval $basicAuth;
  190. if($@) {
  191. Log3 $aName, 1, "basicAuth expression: $@";
  192. $pwok = 2;
  193. } else {
  194. $pwok = ($pwok ? 1 : 2);
  195. }
  196. } elsif($basicAuth =~ m/^SHA256:(.{8}):(.*)$/) {
  197. if($allowed_haveSha) {
  198. $pwok = (Digest::SHA::sha256_base64("$1:$user:$password") eq $2 ? 1 : 2);
  199. } else {
  200. Log3 $me, 3, "Cannot load Digest::SHA to decode $aName basicAuth";
  201. $pwok = 2;
  202. }
  203. }
  204. Log3 $me, 3, "Login denied by $aName for $user via $cl->{NAME}"
  205. if($pwok != 1 && ($verbose || $user));
  206. return $pwok;
  207. }
  208. sub
  209. allowed_Set(@)
  210. {
  211. my ($hash, @a) = @_;
  212. my %sets = (globalpassword=>1, password=>1, basicAuth=>2);
  213. return "no set argument specified" if(int(@a) < 2);
  214. return "Unknown argument $a[1], choose one of ".join(" ",sort keys %sets)
  215. if(!defined($sets{$a[1]}));
  216. return "$a[1] needs $sets{$a[1]} parameters"
  217. if(@a-2 != $sets{$a[1]});
  218. return "Cannot load Digest::SHA" if(!$allowed_haveSha);
  219. my $plain = ($a[1] eq "basicAuth" ? "$a[2]:$a[3]" : $a[2]);
  220. my ($x,$y) = gettimeofday();
  221. my $salt = substr(sprintf("%08X", rand($y)*rand($x)),0,8);
  222. CommandAttr($hash->{CL}, "$a[0] $a[1] SHA256:$salt:".
  223. Digest::SHA::sha256_base64("$salt:$plain"));
  224. }
  225. sub
  226. allowed_Attr(@)
  227. {
  228. my ($type, $devName, $attrName, @param) = @_;
  229. my $hash = $defs{$devName};
  230. my $set = ($type eq "del" ? 0 : (!defined($param[0]) || $param[0]) ? 1 : 0);
  231. if($attrName eq "disable") {
  232. readingsSingleUpdate($hash, "state", $set ? "disabled" : "active", 1);
  233. if($set) {
  234. $hash->{disabled} = 1;
  235. } else {
  236. delete($hash->{disabled});
  237. }
  238. } elsif($attrName eq "allowedCommands" || # hoping for some speedup
  239. $attrName eq "allowedDevices" ||
  240. $attrName eq "allowedDevicesRegexp" ||
  241. $attrName eq "validFor") {
  242. if($set) {
  243. $hash->{$attrName} = join(" ", @param);
  244. } else {
  245. delete($hash->{$attrName});
  246. }
  247. if($attrName eq "validFor") {
  248. readingsSingleUpdate($hash, "state", "validFor:".join(",",@param), 1);
  249. InternalTimer(1, "SecurityCheck", 0) if($init_done);
  250. }
  251. } elsif(($attrName eq "basicAuth" ||
  252. $attrName eq "password" || $attrName eq "globalpassword") &&
  253. $type eq "set") {
  254. foreach my $d (devspec2array("TYPE=(FHEMWEB|telnet)")) {
  255. delete $defs{$d}{Authenticated} if($defs{$d});
  256. }
  257. InternalTimer(1, "SecurityCheck", 0) if($init_done);
  258. }
  259. return undef;
  260. }
  261. #########################
  262. sub
  263. allowed_fhemwebFn($$$$)
  264. {
  265. my ($FW_wname, $d, $room, $pageHash) = @_; # pageHash is set for summaryFn.
  266. my $hash = $defs{$d};
  267. my $vf = $defs{$d}{validFor} ? $defs{$d}{validFor} : "";
  268. my (@F_arr, @t_arr);
  269. my @arr = map {
  270. my $ca = $modules{$defs{$_}{TYPE}}{CanAuthenticate};
  271. push(@F_arr, $_) if($ca == 1);
  272. push(@t_arr, $_) if($ca == 2);
  273. "<input type='checkbox' ".($vf =~ m/\b$_\b/ ? "checked ":"").
  274. "name='$_' class='vfAttr'><label>$_</label>"
  275. }
  276. grep { !$defs{$_}{SNAME} &&
  277. $modules{$defs{$_}{TYPE}}{CanAuthenticate} }
  278. sort keys %defs;
  279. my $r = "<input id='vfAttr' type='button' value='attr'> $d validFor <ul>".
  280. join("<br>",@arr)."</ul><script>var dev='$d';".<<'EOF';
  281. $("#vfAttr").click(function(){
  282. var names=[];
  283. $("input.vfAttr:checked").each(function(){names.push($(this).attr("name"))});
  284. FW_cmd(FW_root+"?cmd=attr "+dev+" validFor "+names.join(",")+"&XHR=1");
  285. });
  286. </script>
  287. EOF
  288. $r .= "For ".join(",",@F_arr).
  289. ": \"set $d basicAuth &lt;username&gt; &lt;password&gt;\"<br>"
  290. if(@F_arr);
  291. $r .= "For ".join(",",@t_arr).
  292. ": \"set $d password &lt;password&gt;\" or".
  293. " \"set $d globalpassword &lt;password&gt;\"<br>"
  294. if(@t_arr);
  295. return $r;
  296. }
  297. 1;
  298. =pod
  299. =item helper
  300. =item summary authorize command execution based on frontend
  301. =item summary_DE authorisiert Befehlsausf&uuml;hrung basierend auf dem Frontend
  302. =begin html
  303. <a name="allowed"></a>
  304. <h3>allowed</h3>
  305. <ul>
  306. <br>
  307. <a name="alloweddefine"></a>
  308. <b>Define</b>
  309. <ul>
  310. <code>define &lt;name&gt; allowed &lt;deviceList&gt;</code>
  311. <br><br>
  312. Authorize execution of commands and modification of devices based on the
  313. frontend used and/or authenticate users.<br><br>
  314. If there are multiple instances defined which are valid for a given
  315. frontend device, then all authorizations must succeed. For authentication
  316. it is sufficient when one of the instances succeeds. The checks are
  317. executed in alphabetical order of the allowed instance names.<br><br>
  318. <b>Note:</b> this module should work as intended, but no guarantee
  319. can be given that there is no way to circumvent it.<br><br>
  320. Examples:
  321. <ul><code>
  322. define allowedWEB allowed<br>
  323. attr allowedWEB validFor WEB,WEBphone,WEBtablet<br>
  324. attr allowedWEB basicAuth { "$user:$password" eq "admin:secret" }<br>
  325. attr allowedWEB allowedCommands set,get<br><br>
  326. define allowedTelnet allowed<br>
  327. attr allowedTelnet validFor telnetPort<br>
  328. attr allowedTelnet password secret<br>
  329. </code></ul>
  330. <br>
  331. </ul>
  332. <a name="allowedset"></a>
  333. <b>Set</b>
  334. <ul>
  335. <li>basicAuth &lt;username&gt; &lt;password&gt;</li>
  336. <li>password &lt;password&gt;</li>
  337. <li>globalpassword &lt;password&gt;<br>
  338. these commands set the corresponding attribute, by computing an SHA256
  339. hash from the arguments and a salt. Note: the perl module Device::SHA is
  340. needed.
  341. </li>
  342. </ul><br>
  343. <a name="allowedget"></a>
  344. <b>Get</b> <ul>N/A</ul><br>
  345. <a name="allowedattr"></a>
  346. <b>Attributes</b>
  347. <ul>
  348. <li><a href="#disable">disable</a></li><br>
  349. <a name="allowedCommands"></a>
  350. <li>allowedCommands<br>
  351. A comma separated list of commands allowed from the matching frontend
  352. (see validFor).<br>
  353. If set to an empty list <code>, (i.e. comma only)</code>
  354. then no comands are allowed. If set to <code>get,set</code>, then only
  355. a "regular" usage is allowed via set and get, but changing any
  356. configuration is forbidden.<br>
  357. </li><br>
  358. <a name="allowedDevices"></a>
  359. <li>allowedDevices<br>
  360. A comma or space separated list of device names which can be
  361. manipulated via the matching frontend (see validFor).
  362. </li><br>
  363. <a name="allowedDevicesRegexp"></a>
  364. <li>allowedDevices<br>
  365. Comma separated list of device names which can be manipulated via the
  366. frontends specified by validFor. The regexp is prepended with ^ and
  367. suffixed with $, as usual. Only devices listed in allowedDevices or
  368. matching allowedDevicesRegexp may manipulated.
  369. </li><br>
  370. <a name="allowedDevicesRegexp"></a>
  371. <li>allowedDevicesRegexp<br>
  372. A regexp to match device names which can be manipulated via the
  373. frontends specified by validFor. Only devices listed in allowedDevices
  374. or matching allowedDevicesRegexp may manipulated.
  375. </li><br>
  376. <a name="basicAuth"></a>
  377. <li>basicAuth, basicAuthMsg<br>
  378. request a username/password authentication for FHEMWEB access.
  379. It can be a base64 encoded string of user:password, an SHA256 hash
  380. (which should be set via the corresponding set command) or a perl
  381. expression if enclosed in {}, where $user and $password are set, and
  382. which returns true if accepted or false if not. Examples:
  383. <ul><code>
  384. attr allowed basicAuth ZmhlbXVzZXI6c2VjcmV0<br>
  385. attr allowed basicAuth SHA256:F87740B5:q8dHeiClaPLaWVsR/rqkzcBhw/JvvwVi4bEwKmJc/Is<br>
  386. attr allowed basicAuth {"$user:$password" eq "fhemuser:secret"}<br>
  387. </code></ul>
  388. If basicAuthMsg is set, it will be displayed in the popup window when
  389. requesting the username/password. Note: not all browsers support this
  390. feature.<br>
  391. </li><br>
  392. <a name="basicAuthExpiry"></a>
  393. <li>basicAuthExpiry<br>
  394. allow the basicAuth to be kept valid for a given number of days.
  395. So username/password as specified in basicAuth are only requested
  396. after a certain period.
  397. This is achieved by sending a cookie to the browser that will expire
  398. after the given period.
  399. Only valid if basicAuth is set.
  400. </li><br>
  401. <a name="password"></a>
  402. <li>password<br>
  403. Specify a password for telnet instances, which has to be entered as the
  404. very first string after the connection is established. The same rules
  405. apply as for basicAuth, with the expception that there is no user to be
  406. specified.<br>
  407. Note: if this attribute is set, you have to specify a password as the
  408. first argument when using fhem.pl in client mode:
  409. <ul>
  410. perl fhem.pl localhost:7072 secret "set lamp on"
  411. </ul>
  412. </li><br>
  413. <a name="globalpassword"></a>
  414. <li>globalpassword<br>
  415. Just like the attribute password, but a password will only required for
  416. non-local connections.
  417. </li><br>
  418. <a name="validFor"></a>
  419. <li>validFor<br>
  420. A comma separated list of frontend names. Currently supported frontends
  421. are all devices connected through the FHEM TCP/IP library, e.g. telnet
  422. and FHEMWEB. The allowed instance is only active, if this attribute is
  423. set.
  424. </li>
  425. </ul>
  426. <br>
  427. </ul>
  428. =end html
  429. =begin html_DE
  430. <a name="allowed"></a>
  431. <h3>allowed</h3>
  432. <ul>
  433. <br>
  434. <a name="alloweddefine"></a>
  435. <b>Define</b>
  436. <ul>
  437. <code>define &lt;name&gt; allowed &lt;deviceList&gt;</code>
  438. <br><br>
  439. Authorisiert das Ausf&uuml;hren von Kommandos oder das &Auml;ndern von
  440. Ger&auml;ten abh&auml;ngig vom verwendeten Frontend.<br>
  441. Falls man mehrere allowed Instanzen definiert hat, die f&uuml;r dasselbe
  442. Frontend verantwortlich sind, dann m&uuml;ssen alle Authorisierungen
  443. genehmigt sein, um das Befehl ausf&uuml;hren zu k&ouml;nnen. Auf der
  444. anderen Seite reicht es, wenn einer der Authentifizierungen positiv
  445. entschieden wird. Die Pr&uuml;fungen werden in alphabetischer Reihenfolge
  446. der Instanznamen ausgef&uuml;hrt. <br><br>
  447. <b>Achtung:</b> das Modul sollte wie hier beschrieben funktionieren,
  448. allerdings k&ouml;nnen wir keine Garantie geben, da&szlig; man sie nicht
  449. &uuml;berlisten, und Schaden anrichten kann.<br><br>
  450. Beispiele:
  451. <ul><code>
  452. define allowedWEB allowed<br>
  453. attr allowedWEB validFor WEB,WEBphone,WEBtablet<br>
  454. attr allowedWEB basicAuth { "$user:$password" eq "admin:secret" }<br>
  455. attr allowedWEB allowedCommands set,get<br><br>
  456. define allowedTelnet allowed<br>
  457. attr allowedTelnet validFor telnetPort<br>
  458. attr allowedTelnet password secret<br>
  459. </code></ul>
  460. <br>
  461. </ul>
  462. <a name="allowedset"></a>
  463. <b>Set</b>
  464. <ul>
  465. <li>basicAuth &lt;username&gt; &lt;password&gt;</li>
  466. <li>password &lt;password&gt;</li>
  467. <li>globalpassword &lt;password&gt;<br>
  468. diese Befehle setzen das entsprechende Attribut, indem sie aus den
  469. Parameter und ein Salt ein SHA256 Hashwert berechnen. Achtung: das perl
  470. Modul Device::SHA wird ben&ouml;tigt.
  471. </li>
  472. </ul><br>
  473. <a name="allowedget"></a>
  474. <b>Get</b> <ul>N/A</ul><br>
  475. <a name="allowedattr"></a>
  476. <b>Attribute</b>
  477. <ul>
  478. <li><a href="#disable">disable</a>
  479. </li><br>
  480. <a name="allowedCommands"></a>
  481. <li>allowedCommands<br>
  482. Eine Komma getrennte Liste der erlaubten Befehle des passenden
  483. Frontends (siehe validFor). Bei einer leeren Liste (, dh. nur ein
  484. Komma) wird dieser Frontend "read-only".
  485. Falls es auf <code>get,set</code> gesetzt ist, dann sind in dieser
  486. Frontend keine Konfigurations&auml;nderungen m&ouml;glich, nur
  487. "normale" Bedienung der Schalter/etc.
  488. </li><br>
  489. <a name="allowedDevices"></a>
  490. <li>allowedDevices<br>
  491. Komma getrennte Liste von Ger&auml;tenamen, die mit dem passenden
  492. Frontend (siehe validFor) ge&auml;ndert werden k&ouml;nnen.
  493. </li><br>
  494. <a name="basicAuth"></a>
  495. <li>basicAuth, basicAuthMsg<br>
  496. Erzwingt eine Authentifizierung mit Benutzername/Passwort f&uuml;r die
  497. zugerdnete FHEMWEB Instanzen. Der Wert kann entweder das base64
  498. kodierte Benutzername:Passwort sein, ein SHA256 hash (was man am besten
  499. mit dem passenden set Befehl erzeugt), oder, falls er in {}
  500. eingeschlossen ist, ein Perl Ausdruck. F&uuml;r Letzteres wird
  501. $user und $passwort gesetzt, und muss wahr zur&uuml;ckliefern, falls
  502. Benutzername und Passwort korrekt sind. Beispiele:
  503. <ul><code>
  504. attr allowed basicAuth ZmhlbXVzZXI6c2VjcmV0<br>
  505. attr allowed basicAuth SHA256:F87740B5:q8dHeiClaPLaWVsR/rqkzcBhw/JvvwVi4bEwKmJc/Is<br>
  506. attr allowed basicAuth {"$user:$password" eq "fhemuser:secret"}<br>
  507. </code></ul>
  508. basicAuthMsg wird (in manchen Browsern) in dem Passwort Dialog als
  509. &Uuml;berschrift angezeigt.<br>
  510. </li><br>
  511. <a name="password"></a>
  512. <li>password<br>
  513. Betrifft nur telnet Instanzen (siehe validFor): Bezeichnet ein
  514. Passwort, welches als allererster String eingegeben werden muss,
  515. nachdem die Verbindung aufgebaut wurde. F&uuml;r die Werte gelten die
  516. Regeln von basicAuth, mit der Ausnahme, dass nur Passwort und kein
  517. Benutzername spezifiziert wird.<br> Falls dieser Parameter gesetzt
  518. wird, sendet FHEM telnet IAC Requests, um ein Echo w&auml;hrend der
  519. Passworteingabe zu unterdr&uuml;cken. Ebenso werden alle
  520. zur&uuml;ckgegebenen Zeilen mit \r\n abgeschlossen.<br>
  521. Falls dieses Attribut gesetzt wird, muss als erstes Argument ein
  522. Passwort angegeben werden, wenn fhem.pl im Client-mode betrieben wird:
  523. <ul><code>
  524. perl fhem.pl localhost:7072 secret "set lamp on"
  525. </code></ul>
  526. </li><br>
  527. <a name="globalpassword"></a>
  528. <li>globalpassword<br>
  529. Betrifft nur telnet Instanzen (siehe validFor): Entspricht dem
  530. Attribut password; ein Passwort wird aber ausschlie&szlig;lich f&uuml;r
  531. nicht-lokale Verbindungen verlangt.
  532. </li><br>
  533. <a name="validFor"></a>
  534. <li>validFor<br>
  535. Komma separierte Liste von Frontend-Instanznamen. Aktuell werden nur
  536. Frontends unterst&uuml;tzt, die das FHEM TCP/IP Bibliothek verwenden,
  537. z.Bsp. telnet und FHEMWEB. Falls nicht gesetzt, ist die allowed Instanz
  538. nicht aktiv.
  539. </li>
  540. </ul>
  541. <br>
  542. </ul>
  543. =end html_DE
  544. =cut