98_telnet.pm 21 KB

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