98_telnet.pm 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. ##############################################
  2. # $Id: 98_telnet.pm 13443 2017-02-19 12:51:22Z rudolfkoenig $
  3. # Note: this is not really a telnet server, but a TCP server with slight telnet
  4. # features (disable echo on password)
  5. package main;
  6. use strict;
  7. use warnings;
  8. use TcpServerUtils;
  9. ##########################
  10. sub
  11. telnet_Initialize($)
  12. {
  13. my ($hash) = @_;
  14. $hash->{DefFn} = "telnet_Define";
  15. $hash->{ReadFn} = "telnet_Read";
  16. $hash->{AsyncOutputFn} = "telnet_Output";
  17. $hash->{UndefFn} = "telnet_Undef";
  18. $hash->{AttrFn} = "telnet_Attr";
  19. $hash->{NotifyFn}= "telnet_SecurityCheck";
  20. $hash->{AttrList} = "globalpassword password prompt allowedCommands ".
  21. "allowfrom SSL connectTimeout connectInterval ".
  22. "encoding:utf8,latin1 sslVersion";
  23. $hash->{ActivateInformFn} = "telnet_ActivateInform";
  24. $cmds{encoding} = { Fn=>"CommandTelnetEncoding",
  25. ClientFilter => "telnet",
  26. Hlp=>"[utf8|latin1],query and set the character encoding ".
  27. "for the current telnet session" };
  28. $cmds{inform} = { Fn=>"CommandTelnetInform",
  29. ClientFilter => "telnet",
  30. Hlp=>"{on|off|log|raw|timer|status},echo all events to this client" };
  31. }
  32. sub
  33. CommandTelnetEncoding($$)
  34. {
  35. my ($hash, $param) = @_;
  36. my $ret = "";
  37. if( !$param ) {
  38. $ret = "current encoding is $hash->{encoding}";
  39. } elsif( $param eq "utf8" || $param eq "latin1" ) {
  40. $hash->{encoding} = $param;
  41. syswrite($hash->{CD}, sprintf("%c%c%c", 255, 253, 0) );
  42. $ret = "encoding changed to $param";
  43. } else {
  44. $ret = "unknown encoding >>$param<<";
  45. }
  46. return $ret;
  47. }
  48. #####################################
  49. sub
  50. telnet_SecurityCheck($$)
  51. {
  52. my ($ntfy, $dev) = @_;
  53. return if($dev->{NAME} ne "global" ||
  54. !grep(m/^INITIALIZED$/, @{$dev->{CHANGED}}));
  55. my $motd = AttrVal("global", "motd", "");
  56. if($motd =~ "^SecurityCheck") {
  57. my @list1 = devspec2array("TYPE=telnet");
  58. my @list2 = devspec2array("TYPE=allowed");
  59. my @list3;
  60. for my $l (@list1) { # This is a hack, as hardcoded to basicAuth
  61. next if(!$defs{$l} || $defs{$l}{TEMPORARY}); # Blocking.pm /Forum #47022
  62. my $fnd = 0;
  63. for my $a (@list2) {
  64. next if(!$defs{$a});
  65. my $vf = AttrVal($a, "validFor","");
  66. $fnd = 1 if(($vf && $vf =~ m/\b$l\b/) &&
  67. (AttrVal($a, "password","") ||
  68. AttrVal($a, "globalpassword","")));
  69. }
  70. push @list3, $l if(!$fnd);
  71. }
  72. $motd .= (join(",", sort @list3).
  73. " has no associated allowed device with password/globalpassword.\n")
  74. if(@list3);
  75. $attr{global}{motd} = $motd;
  76. }
  77. delete $modules{telnet}{NotifyFn};
  78. return;
  79. }
  80. ##########################
  81. sub
  82. telnet_ClientConnect($)
  83. {
  84. my ($hash) = @_;
  85. my $name = $hash->{NAME};
  86. $hash->{DEF} =~ m/^(IPV6:)?(.*):(\d+)$/;
  87. my ($isIPv6, $server, $port) = ($1, $2, $3);
  88. Log3 $name, 4, "$name: Connecting to $server:$port...";
  89. my @opts = (
  90. PeerAddr => "$server:$port",
  91. Timeout => AttrVal($name, "connectTimeout", 2),
  92. );
  93. my $client;
  94. if($hash->{SSL}) {
  95. $client = IO::Socket::SSL->new(@opts);
  96. } else {
  97. $client = IO::Socket::INET->new(@opts);
  98. }
  99. if($client) {
  100. $hash->{FD} = $client->fileno();
  101. $hash->{CD} = $client; # sysread / close won't work on fileno
  102. $hash->{BUF} = "";
  103. $hash->{CONNECTS}++;
  104. $selectlist{$name} = $hash;
  105. $hash->{STATE} = "Connected";
  106. RemoveInternalTimer($hash);
  107. Log3 $name, 3, "$name: connected to $server:$port";
  108. } else {
  109. telnet_ClientDisconnect($hash, 1);
  110. }
  111. }
  112. ##########################
  113. sub
  114. telnet_ClientDisconnect($$)
  115. {
  116. my ($hash, $connect) = @_;
  117. my $name = $hash->{NAME};
  118. close($hash->{CD}) if($hash->{CD});
  119. delete($hash->{FD});
  120. delete($hash->{CD});
  121. delete($selectlist{$name});
  122. $hash->{STATE} = "Disconnected";
  123. InternalTimer(gettimeofday()+AttrVal($name, "connectInterval", 60),
  124. "telnet_ClientConnect", $hash, 0);
  125. if($connect) {
  126. Log3 $name, 4, "$name: Connect failed.";
  127. } else {
  128. Log3 $name, 3, "$name: Disconnected";
  129. }
  130. }
  131. ##########################
  132. sub
  133. telnet_Define($$$)
  134. {
  135. my ($hash, $def) = @_;
  136. my @a = split("[ \t][ \t]*", $def);
  137. my ($name, $type, $pport, $global) = split("[ \t]+", $def);
  138. my $port = $pport;
  139. $port =~ s/^IPV6://;
  140. my $isServer = 1 if(defined($port) && $port =~ m/^\d+$/);
  141. my $isClient = 1 if($port && $port =~ m/^(.+):\d+$/);
  142. return "Usage: define <name> telnet { [IPV6:]<tcp-portnr> [global] | ".
  143. " [IPV6:]serverName:port }"
  144. if(!($isServer || $isClient) ||
  145. ($isClient && $global));
  146. # Make sure that fhem only runs once
  147. if($isServer) {
  148. my $ret = TcpServer_Open($hash, $pport, $global);
  149. if($ret && !$init_done) {
  150. Log3 $name, 1, "$ret. Exiting.";
  151. exit(1);
  152. }
  153. return $ret;
  154. }
  155. if($isClient) {
  156. $hash->{isClient} = 1;
  157. telnet_ClientConnect($hash);
  158. }
  159. }
  160. ##########################
  161. sub
  162. telnet_Read($)
  163. {
  164. my ($hash) = @_;
  165. my $name = $hash->{NAME};
  166. if($hash->{SERVERSOCKET}) { # Accept and create a child
  167. my $chash = TcpServer_Accept($hash, "telnet");
  168. return if(!$chash);
  169. $chash->{canAsyncOutput} = 1;
  170. $chash->{encoding} = AttrVal($name, "encoding", "utf8");
  171. $chash->{prompt} = AttrVal($name, "prompt",
  172. AttrVal('global','title','fhem'));
  173. if($chash->{prompt} =~ m/^{.*}$/s) {
  174. $chash->{prompt} = eval $chash->{prompt};
  175. $chash->{prompt} =~ s/\n//;
  176. }
  177. $chash->{prompt} .= '>'; # Not really nice, but dont know better.
  178. syswrite($chash->{CD}, sprintf("%c%c%c", 255, 253, 0) )
  179. if( AttrVal($name, "encoding", "") ); #DO BINARY
  180. $chash->{CD}->flush();
  181. my $auth = Authenticate($chash, undef);
  182. syswrite($chash->{CD}, sprintf("%c%c%cPassword: ", 255, 251, 1)) # WILL ECHO
  183. if($auth);
  184. $chash->{Authenticated} = 0 if(!$auth);
  185. return;
  186. }
  187. my $buf;
  188. my $ret = sysread($hash->{CD}, $buf, 256);
  189. if(!defined($ret) || $ret <= 0) {
  190. if($hash->{isClient}) {
  191. telnet_ClientDisconnect($hash, 0);
  192. } else {
  193. delete $hash->{canAsyncOutput};
  194. CommandDelete(undef, $name);
  195. }
  196. return;
  197. }
  198. if(ord($buf) == 4) { # EOT / ^D
  199. CommandQuit($hash, "");
  200. return;
  201. }
  202. $buf =~ s/\r//g;
  203. my $sname = ($hash->{isClient} ? $name : $hash->{SNAME});
  204. if(!defined($hash->{Authenticated}) || $hash->{Authenticated}) {
  205. $buf =~ s/\xff..//g; # Telnet IAC stuff
  206. $buf =~ s/\xfd(.)//; # Telnet Do ?
  207. syswrite($hash->{CD}, sprintf("%c%c%c", 0xff, 0xfc, ord($1)))
  208. if(defined($1)) # Wont / ^C handling
  209. }
  210. $hash->{BUF} .= $buf;
  211. my @ret;
  212. my $gotCmd;
  213. while($hash->{BUF} =~ m/\n/) {
  214. my ($cmd, $rest) = split("\n", $hash->{BUF}, 2);
  215. $hash->{BUF} = $rest;
  216. if(!defined($hash->{Authenticated})) {
  217. syswrite($hash->{CD}, sprintf("%c%c%c\r\n", 255, 252, 1)); # WONT ECHO
  218. if(Authenticate($hash, $cmd) != 2) {
  219. $hash->{Authenticated} = 1;
  220. next;
  221. } else {
  222. if($hash->{isClient}) {
  223. telnet_ClientDisconnect($hash, 0);
  224. } else {
  225. delete($hash->{rcvdQuit});
  226. CommandDelete(undef, $name);
  227. }
  228. return;
  229. }
  230. }
  231. $gotCmd = 1;
  232. if($cmd) {
  233. if($cmd =~ m/\\ *$/) { # Multi-line
  234. $cmd =~ s/\\ *$//;
  235. $hash->{prevlines} .= $cmd . "\n";
  236. } else {
  237. if($hash->{prevlines}) {
  238. $cmd = $hash->{prevlines} . $cmd;
  239. undef($hash->{prevlines});
  240. }
  241. $cmd = latin1ToUtf8($cmd) if( $hash->{encoding} eq "latin1" );
  242. $ret = AnalyzeCommandChain($hash, $cmd);
  243. push @ret, $ret if(defined($ret));
  244. }
  245. } else {
  246. $hash->{showPrompt} = 1; # Empty return
  247. if(!$hash->{motdDisplayed}) {
  248. my $motd = $attr{global}{motd};
  249. push @ret, $motd if($motd && $motd ne "none");
  250. $hash->{motdDisplayed} = 1;
  251. }
  252. }
  253. next if($rest);
  254. }
  255. $ret = "";
  256. $ret .= (join("\n", @ret) . "\n") if(@ret);
  257. $ret .= ($hash->{prevlines} ? "> " : $hash->{prompt}." ")
  258. if($gotCmd && $hash->{showPrompt} && !$hash->{rcvdQuit});
  259. $ret =~ s/\n/\r\n/g if($hash->{Authenticated}); # only for DOS telnet
  260. telnet_Output($hash, $ret, 1);
  261. if($hash->{rcvdQuit}) {
  262. if($hash->{isClient}) {
  263. delete($hash->{rcvdQuit});
  264. telnet_ClientDisconnect($hash, 0);
  265. } else {
  266. CommandDelete(undef, $name);
  267. }
  268. }
  269. }
  270. sub
  271. telnet_Output($$$)
  272. {
  273. my ($hash,$ret,$nonl) = @_;
  274. if($ret) {
  275. $ret = utf8ToLatin1($ret) if( $hash->{encoding} eq "latin1" );
  276. if(!$nonl) { # AsyncOutput stuff
  277. $ret = "\n$ret\n$hash->{prompt} " if( $hash->{showPrompt});
  278. $ret = "$ret\n" if(!$hash->{showPrompt});
  279. }
  280. for(;;) {
  281. utf8::encode($ret) if(utf8::is_utf8($ret) && $ret =~ m/[^\x00-\xFF]/);
  282. my $l = syswrite($hash->{CD}, $ret);
  283. last if(!$l || $l == length($ret));
  284. $ret = substr($ret, $l);
  285. }
  286. $hash->{CD}->flush();
  287. }
  288. return undef;
  289. }
  290. ##########################
  291. sub
  292. telnet_Attr(@)
  293. {
  294. my ($type, $devName, $attrName, @param) = @_;
  295. my @a = @_;
  296. my $hash = $defs{$devName};
  297. if($type eq "set" && $attrName eq "SSL") {
  298. TcpServer_SetSSL($hash);
  299. if($hash->{CD}) {
  300. my $ret = IO::Socket::SSL->start_SSL($hash->{CD});
  301. Log3 $devName, 1, "$hash->{NAME} start_SSL: $ret" if($ret);
  302. }
  303. }
  304. if(($attrName eq "allowedCommands" ||
  305. $attrName eq "password" ||
  306. $attrName eq "globalpassword" ) && $type eq "set") {
  307. my $aName = "allowed_$devName";
  308. my $exists = ($defs{$aName} ? 1 : 0);
  309. AnalyzeCommand(undef, "defmod $aName allowed");
  310. AnalyzeCommand(undef, "attr $aName validFor $devName");
  311. AnalyzeCommand(undef, "attr $aName $attrName ".join(" ",@param));
  312. return "$devName: ".($exists ? "modifying":"creating").
  313. " device $aName for attribute $attrName";
  314. }
  315. return undef;
  316. }
  317. sub
  318. telnet_Undef($$)
  319. {
  320. my ($hash, $arg) = @_;
  321. delete($logInform{$hash->{NAME}});
  322. delete($inform{$hash->{NAME}});
  323. return TcpServer_Close($hash);
  324. }
  325. #####################################
  326. sub
  327. CommandTelnetInform($$)
  328. {
  329. my ($cl, $param) = @_;
  330. return if(!$cl);
  331. my $name = $cl->{NAME};
  332. return "Usage: inform {on|off|raw|timer|log|status} [regexp]"
  333. if($param !~ m/^(on|off|raw|timer|log|status)/);
  334. if($param eq "status") {
  335. my $i = $inform{$name};
  336. return $i ? ($i->{type} . ($i->{regexp} ? " ".$i->{regexp} : "")) : "off";
  337. }
  338. if($param eq "off") {
  339. delete($logInform{$name});
  340. delete($inform{$name});
  341. } elsif($param eq "log") {
  342. $logInform{$name} = sub($$){
  343. my ($me, $msg) = @_; # _NO_ Log3 here!
  344. telnet_Output($defs{$me}, $msg."\n", 1);
  345. }
  346. } elsif($param ne "off") {
  347. my ($type, $regexp) = split(" ", $param);
  348. $inform{$name}{NR} = $cl->{NR};
  349. $inform{$name}{type} = $type;
  350. if($regexp) {
  351. eval { "Hallo" =~ m/$regexp/ };
  352. return "Bad regexp: $@" if($@);
  353. $inform{$name}{regexp} = $regexp;
  354. }
  355. Log 4, "Setting inform to $param";
  356. }
  357. return undef;
  358. }
  359. sub
  360. telnet_ActivateInform($)
  361. {
  362. my ($cl) = @_;
  363. CommandTelnetInform($cl, "log");
  364. }
  365. 1;
  366. =pod
  367. =item helper
  368. =item summary telnet server for FHEM
  369. =item summary_DE FHEM telnet Server
  370. =begin html
  371. <a name="telnet"></a>
  372. <h3>telnet</h3>
  373. <ul>
  374. <br>
  375. <a name="telnetdefine"></a>
  376. <b>Define</b>
  377. <ul>
  378. <code>define &lt;name&gt; telnet &lt;portNumber&gt;
  379. [global|hostname]</code><br>
  380. or<br>
  381. <code>define &lt;name&gt; telnet &lt;servername&gt:&lt;portNumber&gt;</code>
  382. <br><br>
  383. First form, <b>server</b> mode:<br>
  384. Listen on the TCP/IP port <code>&lt;portNumber&gt;</code> for incoming
  385. connections. If the second parameter is <b>not</b> specified,
  386. the server will only listen to localhost connections. If the second
  387. parameter is global, telnet will listen on all interfaces, else it wil try
  388. to resolve the parameter as a hostname, and listen only on this interface.
  389. <br>
  390. To use IPV6, specify the portNumber as IPV6:&lt;number&gt;, in this
  391. case the perl module IO::Socket:INET6 will be requested.
  392. On Linux you may have to install it with cpan -i IO::Socket::INET6 or
  393. apt-get libio-socket-inet6-perl; OSX and the FritzBox-7390 perl already has
  394. this module.<br>
  395. Examples:
  396. <ul>
  397. <code>define tPort telnet 7072 global</code><br>
  398. <code>attr tPort SSL</code><br>
  399. <code>attr allowed_tPort allowed</code><br>
  400. <code>attr allowed_tPort validFor tPort</code><br>
  401. <code>attr allowed_tPort globalpassword mySecret</code><br>
  402. </ul>
  403. Note: The old global attribute port is automatically converted to a
  404. telnet instance with the name telnetPort. The global allowfrom attibute is
  405. lost in this conversion.
  406. <br><br>
  407. Second form, <b>client</b> mode:<br>
  408. Connect to the specified server port, and execute commands received from
  409. there just like in server mode. This can be used to connect to a fhem
  410. instance sitting behind a firewall, when installing exceptions in the
  411. firewall is not desired or possible. Note: this client mode supprts SSL,
  412. but not IPV6.<br>
  413. Example:
  414. <ul>
  415. Start tcptee first on publicly reachable host outside the firewall.<ul>
  416. perl contrib/tcptee.pl --bidi 3000</ul>
  417. Configure fhem inside the firewall:<ul>
  418. define tClient telnet &lt;tcptee_host&gt;:3000</ul>
  419. Connect to the fhem from outside of the firewall:<ul>
  420. telnet &lt;tcptee_host&gt; 3000</ul>
  421. </ul>
  422. </ul>
  423. <br>
  424. <a name="telnetset"></a>
  425. <b>Set</b> <ul>N/A</ul><br>
  426. <a name="telnetget"></a>
  427. <b>Get</b> <ul>N/A</ul><br>
  428. <a name="telnetattr"></a>
  429. <b>Attributes:</b>
  430. <ul>
  431. <a name="prompt"></a>
  432. <li>prompt<br>
  433. Sets the string for the telnet prompt, the default is fhem&gt;
  434. </li><br>
  435. <a name="SSL"></a>
  436. <li>SSL<br>
  437. Enable SSL encryption of the connection, see the description <a
  438. href="#HTTPS">here</a> on generating the needed SSL certificates. To
  439. connect to such a port use one of the following commands:
  440. <ul>
  441. socat openssl:fhemhost:fhemport,verify=0 readline<br>
  442. ncat --ssl fhemhost fhemport<br>
  443. openssl s_client -connect fhemhost:fhemport<br>
  444. </ul>
  445. </li><br>
  446. <a name="allowfrom"></a>
  447. <li>allowfrom<br>
  448. Regexp of allowed ip-addresses or hostnames. If set,
  449. only connections from these addresses are allowed.
  450. </li><br>
  451. <a name="connectTimeout"></a>
  452. <li>connectTimeout<br>
  453. Wait at maximum this many seconds for the connection to be established.
  454. Default is 2.
  455. </li><br>
  456. <a name="connectInterval"></a>
  457. <li>connectInterval<br>
  458. After closing a connection, or if a connection cannot be estblished,
  459. try to connect again after this many seconds. Default is 60.
  460. </li><br>
  461. <a name="encoding"></a>
  462. <li>encoding<br>
  463. Sets the encoding for the data send to the client. Possible values are
  464. latin1 and utf8. Default is utf8.
  465. </li><br>
  466. <li>sslVersion<br>
  467. See the global attribute sslVersion.
  468. </li><br>
  469. </ul>
  470. </ul>
  471. =end html
  472. =begin html_DE
  473. <a name="telnet"></a>
  474. <h3>telnet</h3>
  475. <ul>
  476. <br>
  477. <a name="telnetdefine"></a>
  478. <b>Define</b>
  479. <ul>
  480. <code>define &lt;name&gt; telnet &lt;portNumber&gt;
  481. [global|hostname]</code><br> oder<br>
  482. <code>define &lt;name&gt; telnet &lt;servername&gt:&lt;portNummer&gt;</code>
  483. <br><br>
  484. Erste Form, <b>Server</b>-mode:<br>
  485. &Uuml;berwacht den TCP/IP-Port <code>&lt;portNummer&gt;</code> auf
  486. ankommende Verbindungen. Wenn der zweite Parameter <b>nicht</b>
  487. angegeben wird, wird der Server nur auf Verbindungen von localhost achten.
  488. Falls der zweite Parameter global ist, dann wird telnet auf allen lokalen
  489. Netzwerk-Interfaces zuh&ouml;ren, ansonsten wird der Parameter als Hostname
  490. oder Adresse interpretiert, und nur diese lokale Adresse bedient.
  491. <br>
  492. F&uuml;r den Gebrauch von IPV6 muss die Portnummer als IPV6:&lt;nummer&gt;
  493. angegeben werden, in diesem Fall wird das Perl-Modul IO::Socket:INET6
  494. angesprochen. Unter Linux kann es sein, dass dieses Modul mittels cpan -i
  495. IO::Socket::INET6 oder apt-get libio-socket-inet6-perl nachinstalliert werden
  496. muss; OSX und Fritzbox-7390 enthalten bereits dieses Modul.<br>
  497. Beispiele:
  498. <ul>
  499. <code>define tPort telnet 7072 global</code><br>
  500. <code>attr tPort SSL</code><br>
  501. <code>attr allowed_tPort allowed</code><br>
  502. <code>attr allowed_tPort validFor tPort</code><br>
  503. <code>attr allowed_tPort globalpassword mySecret</code><br>
  504. </ul>
  505. Hinweis: Das alte (pre 5.3) "global attribute port" wird automatisch in
  506. eine telnet-Instanz mit dem Namen telnetPort umgewandelt. Im Rahmen dieser
  507. Umwandlung geht das globale Attribut allowfrom verloren.
  508. <br><br>
  509. Zweite Form, <b>Client</b>-mode:<br>
  510. Verbindet zu einem angegebenen Server-Port und f&uuml;hrt die von dort aus
  511. empfangenen Anweisungen - genau wie im Server-mode - aus. Dies kann
  512. verwendet werden, um sich mit einer fhem-Instanz, die sich hinter einer
  513. Firewall befindet, zu verbinden, f&uuml;r den Fall, wenn das Installieren
  514. von Ausnahmen in der Firewall nicht erw&uuml;nscht oder nicht m&ouml;glich
  515. sind. Hinweis: Dieser Client-mode unterst&uuml;tzt zwar SSL, aber nicht
  516. IPV6.<br>
  517. Beispiel:
  518. <ul>
  519. Starten von tcptee auf einem &ouml;ffentlich erreichbaren Host ausserhalb
  520. der Firewall:<ul>
  521. <code>perl contrib/tcptee.pl --bidi 3000</code></ul>
  522. Konfigurieren von fhem innerhalb der Firewall:<ul>
  523. <code>define tClient telnet &lt;tcptee_host&gt;:3000</code></ul>
  524. Verbinden mit fhem (hinter der Firewall) von ausserhalb der Firewall:<ul>
  525. <code>telnet &lt;tcptee_host&gt; 3000</code></ul>
  526. </ul>
  527. </ul>
  528. <br>
  529. <a name="telnetset"></a>
  530. <b>Set</b> <ul>N/A</ul><br>
  531. <a name="telnetget"></a>
  532. <b>Get</b> <ul>N/A</ul><br>
  533. <a name="telnetattr"></a>
  534. <b>Attribute</b>
  535. <ul>
  536. <a name="prompt"></a>
  537. <li>prompt<br>
  538. Gibt die Zeichenkette an, welche in der Telnet-Sitzung als
  539. Kommandoprompt ausgegeben wird. Die Voreinstellung ist fhem&gt;
  540. </li><br>
  541. <a name="SSL"></a>
  542. <li>SSL<br>
  543. SSL-Verschl&uuml;sselung f&uuml;r eine Verbindung aktivieren. <a
  544. href="#HTTPS">Hier</a> gibt es eine Beschreibung, wie das erforderliche
  545. SSL-Zertifikat generiert werden kann. Um eine Verbindung mit solch
  546. einem Port herzustellen, sind folgende Befehle m&ouml;glich:
  547. <ul>
  548. <code>
  549. socat openssl:fhemhost:fhemport,verify=0 readline<br>
  550. ncat --ssl fhemhost fhemport<br>
  551. openssl s_client -connect fhemhost:fhemport<br>
  552. </code>
  553. </ul>
  554. </li><br>
  555. <a name="allowfrom"></a>
  556. <li>allowfrom<br>
  557. Regexp der erlaubten IP-Adressen oder Hostnamen. Wenn dieses Attribut
  558. gesetzt wurde, werden ausschlie&szlig;lich Verbindungen von diesen
  559. Adressen akzeptiert.
  560. </li><br>
  561. <a name="connectTimeout"></a>
  562. <li>connectTimeout<br>
  563. Gibt die maximale Wartezeit in Sekunden an, in der die Verbindung
  564. aufgebaut sein muss. Standardwert ist 2.
  565. </li><br>
  566. <a name="connectInterval"></a>
  567. <li>connectInterval<br>
  568. Gibt die Dauer an, die entweder nach Schlie&szlig;en einer Verbindung
  569. oder f&uuml;r den Fall, dass die Verbindung nicht zustande kommt,
  570. gewartet werden muss, bis ein erneuter Verbindungsversuch gestartet
  571. werden soll. Standardwert ist 60.
  572. </li><br>
  573. <a name="encoding"></a>
  574. <li>encoding<br>
  575. Bezeichnet die Zeichentabelle f&uuml;r die zum Client gesendeten Daten.
  576. M&ouml;gliche Werte sind utf8 und latin1. Standardwert ist utf8.
  577. </li><br>
  578. <li>sslVersion<br>
  579. Siehe das global Attribut sslVersion.
  580. </li><br>
  581. </ul>
  582. </ul>
  583. =end html_DE
  584. =cut
  585. 1;