1 r"""TELNET client class.
2
3 Based on RFC 854: TELNET Protocol Specification, by J. Postel and
4 J. Reynolds
5
6 Example:
7
8 >>> from telnetlib import Telnet
9 >>> tn = Telnet('www.python.org', 79) # connect to finger port
10 >>> tn.write(b'guido\r\n')
11 >>> print(tn.read_all())
12 Login Name TTY Idle When Where
13 guido Guido van Rossum pts/2 <Dec 2 11:10> snag.cnri.reston..
14
15 >>>
16
17 Note that read_all() won't read until eof -- it just reads some data
18 -- but it guarantees to read at least one byte unless EOF is hit.
19
20 It is possible to pass a Telnet object to a selector in order to wait until
21 more data is available. Note that in this case, read_eager() may return b''
22 even if there was data on the socket, because the protocol negotiation may have
23 eaten the data. This is why EOFError is needed in some cases to distinguish
24 between "no data" and "connection closed" (since the socket also appears ready
25 for reading when it is closed).
26
27 To do:
28 - option negotiation
29 - timeout should be intrinsic to the connection object instead of an
30 option on one of the read calls only
31
32 """
33
34
35 # Imported modules
36 import sys
37 import socket
38 import selectors
39 from time import monotonic as _time
40 import warnings
41
42 warnings._deprecated(__name__, remove=(3, 13))
43
44 __all__ = ["Telnet"]
45
46 # Tunable parameters
47 DEBUGLEVEL = 0
48
49 # Telnet protocol defaults
50 TELNET_PORT = 23
51
52 # Telnet protocol characters (don't change)
53 IAC = bytes([255]) # "Interpret As Command"
54 DONT = bytes([254])
55 DO = bytes([253])
56 WONT = bytes([252])
57 WILL = bytes([251])
58 theNULL = bytes([0])
59
60 SE = bytes([240]) # Subnegotiation End
61 NOP = bytes([241]) # No Operation
62 DM = bytes([242]) # Data Mark
63 BRK = bytes([243]) # Break
64 IP = bytes([244]) # Interrupt process
65 AO = bytes([245]) # Abort output
66 AYT = bytes([246]) # Are You There
67 EC = bytes([247]) # Erase Character
68 EL = bytes([248]) # Erase Line
69 GA = bytes([249]) # Go Ahead
70 SB = bytes([250]) # Subnegotiation Begin
71
72
73 # Telnet protocol options code (don't change)
74 # These ones all come from arpa/telnet.h
75 BINARY = bytes([0]) # 8-bit data path
76 ECHO = bytes([1]) # echo
77 RCP = bytes([2]) # prepare to reconnect
78 SGA = bytes([3]) # suppress go ahead
79 NAMS = bytes([4]) # approximate message size
80 STATUS = bytes([5]) # give status
81 TM = bytes([6]) # timing mark
82 RCTE = bytes([7]) # remote controlled transmission and echo
83 NAOL = bytes([8]) # negotiate about output line width
84 NAOP = bytes([9]) # negotiate about output page size
85 NAOCRD = bytes([10]) # negotiate about CR disposition
86 NAOHTS = bytes([11]) # negotiate about horizontal tabstops
87 NAOHTD = bytes([12]) # negotiate about horizontal tab disposition
88 NAOFFD = bytes([13]) # negotiate about formfeed disposition
89 NAOVTS = bytes([14]) # negotiate about vertical tab stops
90 NAOVTD = bytes([15]) # negotiate about vertical tab disposition
91 NAOLFD = bytes([16]) # negotiate about output LF disposition
92 XASCII = bytes([17]) # extended ascii character set
93 LOGOUT = bytes([18]) # force logout
94 BM = bytes([19]) # byte macro
95 DET = bytes([20]) # data entry terminal
96 SUPDUP = bytes([21]) # supdup protocol
97 SUPDUPOUTPUT = bytes([22]) # supdup output
98 SNDLOC = bytes([23]) # send location
99 TTYPE = bytes([24]) # terminal type
100 EOR = bytes([25]) # end or record
101 TUID = bytes([26]) # TACACS user identification
102 OUTMRK = bytes([27]) # output marking
103 TTYLOC = bytes([28]) # terminal location number
104 VT3270REGIME = bytes([29]) # 3270 regime
105 X3PAD = bytes([30]) # X.3 PAD
106 NAWS = bytes([31]) # window size
107 TSPEED = bytes([32]) # terminal speed
108 LFLOW = bytes([33]) # remote flow control
109 LINEMODE = bytes([34]) # Linemode option
110 XDISPLOC = bytes([35]) # X Display Location
111 OLD_ENVIRON = bytes([36]) # Old - Environment variables
112 AUTHENTICATION = bytes([37]) # Authenticate
113 ENCRYPT = bytes([38]) # Encryption option
114 NEW_ENVIRON = bytes([39]) # New - Environment variables
115 # the following ones come from
116 # http://www.iana.org/assignments/telnet-options
117 # Unfortunately, that document does not assign identifiers
118 # to all of them, so we are making them up
119 TN3270E = bytes([40]) # TN3270E
120 XAUTH = bytes([41]) # XAUTH
121 CHARSET = bytes([42]) # CHARSET
122 RSP = bytes([43]) # Telnet Remote Serial Port
123 COM_PORT_OPTION = bytes([44]) # Com Port Control Option
124 SUPPRESS_LOCAL_ECHO = bytes([45]) # Telnet Suppress Local Echo
125 TLS = bytes([46]) # Telnet Start TLS
126 KERMIT = bytes([47]) # KERMIT
127 SEND_URL = bytes([48]) # SEND-URL
128 FORWARD_X = bytes([49]) # FORWARD_X
129 PRAGMA_LOGON = bytes([138]) # TELOPT PRAGMA LOGON
130 SSPI_LOGON = bytes([139]) # TELOPT SSPI LOGON
131 PRAGMA_HEARTBEAT = bytes([140]) # TELOPT PRAGMA HEARTBEAT
132 EXOPL = bytes([255]) # Extended-Options-List
133 NOOPT = bytes([0])
134
135
136 # poll/select have the advantage of not requiring any extra file descriptor,
137 # contrarily to epoll/kqueue (also, they require a single syscall).
138 if hasattr(selectors, 'PollSelector'):
139 _TelnetSelector = selectors.PollSelector
140 else:
141 _TelnetSelector = selectors.SelectSelector
142
143
144 class ESC[4;38;5;81mTelnet:
145
146 """Telnet interface class.
147
148 An instance of this class represents a connection to a telnet
149 server. The instance is initially not connected; the open()
150 method must be used to establish a connection. Alternatively, the
151 host name and optional port number can be passed to the
152 constructor, too.
153
154 Don't try to reopen an already connected instance.
155
156 This class has many read_*() methods. Note that some of them
157 raise EOFError when the end of the connection is read, because
158 they can return an empty string for other reasons. See the
159 individual doc strings.
160
161 read_until(expected, [timeout])
162 Read until the expected string has been seen, or a timeout is
163 hit (default is no timeout); may block.
164
165 read_all()
166 Read all data until EOF; may block.
167
168 read_some()
169 Read at least one byte or EOF; may block.
170
171 read_very_eager()
172 Read all data available already queued or on the socket,
173 without blocking.
174
175 read_eager()
176 Read either data already queued or some data available on the
177 socket, without blocking.
178
179 read_lazy()
180 Read all data in the raw queue (processing it first), without
181 doing any socket I/O.
182
183 read_very_lazy()
184 Reads all data in the cooked queue, without doing any socket
185 I/O.
186
187 read_sb_data()
188 Reads available data between SB ... SE sequence. Don't block.
189
190 set_option_negotiation_callback(callback)
191 Each time a telnet option is read on the input flow, this callback
192 (if set) is called with the following parameters :
193 callback(telnet socket, command, option)
194 option will be chr(0) when there is no option.
195 No other action is done afterwards by telnetlib.
196
197 """
198
199 def __init__(self, host=None, port=0,
200 timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
201 """Constructor.
202
203 When called without arguments, create an unconnected instance.
204 With a hostname argument, it connects the instance; port number
205 and timeout are optional.
206 """
207 self.debuglevel = DEBUGLEVEL
208 self.host = host
209 self.port = port
210 self.timeout = timeout
211 self.sock = None
212 self.rawq = b''
213 self.irawq = 0
214 self.cookedq = b''
215 self.eof = 0
216 self.iacseq = b'' # Buffer for IAC sequence.
217 self.sb = 0 # flag for SB and SE sequence.
218 self.sbdataq = b''
219 self.option_callback = None
220 if host is not None:
221 self.open(host, port, timeout)
222
223 def open(self, host, port=0, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
224 """Connect to a host.
225
226 The optional second argument is the port number, which
227 defaults to the standard telnet port (23).
228
229 Don't try to reopen an already connected instance.
230 """
231 self.eof = 0
232 if not port:
233 port = TELNET_PORT
234 self.host = host
235 self.port = port
236 self.timeout = timeout
237 sys.audit("telnetlib.Telnet.open", self, host, port)
238 self.sock = socket.create_connection((host, port), timeout)
239
240 def __del__(self):
241 """Destructor -- close the connection."""
242 self.close()
243
244 def msg(self, msg, *args):
245 """Print a debug message, when the debug level is > 0.
246
247 If extra arguments are present, they are substituted in the
248 message using the standard string formatting operator.
249
250 """
251 if self.debuglevel > 0:
252 print('Telnet(%s,%s):' % (self.host, self.port), end=' ')
253 if args:
254 print(msg % args)
255 else:
256 print(msg)
257
258 def set_debuglevel(self, debuglevel):
259 """Set the debug level.
260
261 The higher it is, the more debug output you get (on sys.stdout).
262
263 """
264 self.debuglevel = debuglevel
265
266 def close(self):
267 """Close the connection."""
268 sock = self.sock
269 self.sock = None
270 self.eof = True
271 self.iacseq = b''
272 self.sb = 0
273 if sock:
274 sock.close()
275
276 def get_socket(self):
277 """Return the socket object used internally."""
278 return self.sock
279
280 def fileno(self):
281 """Return the fileno() of the socket object used internally."""
282 return self.sock.fileno()
283
284 def write(self, buffer):
285 """Write a string to the socket, doubling any IAC characters.
286
287 Can block if the connection is blocked. May raise
288 OSError if the connection is closed.
289
290 """
291 if IAC in buffer:
292 buffer = buffer.replace(IAC, IAC+IAC)
293 sys.audit("telnetlib.Telnet.write", self, buffer)
294 self.msg("send %r", buffer)
295 self.sock.sendall(buffer)
296
297 def read_until(self, match, timeout=None):
298 """Read until a given string is encountered or until timeout.
299
300 When no match is found, return whatever is available instead,
301 possibly the empty string. Raise EOFError if the connection
302 is closed and no cooked data is available.
303
304 """
305 n = len(match)
306 self.process_rawq()
307 i = self.cookedq.find(match)
308 if i >= 0:
309 i = i+n
310 buf = self.cookedq[:i]
311 self.cookedq = self.cookedq[i:]
312 return buf
313 if timeout is not None:
314 deadline = _time() + timeout
315 with _TelnetSelector() as selector:
316 selector.register(self, selectors.EVENT_READ)
317 while not self.eof:
318 if selector.select(timeout):
319 i = max(0, len(self.cookedq)-n)
320 self.fill_rawq()
321 self.process_rawq()
322 i = self.cookedq.find(match, i)
323 if i >= 0:
324 i = i+n
325 buf = self.cookedq[:i]
326 self.cookedq = self.cookedq[i:]
327 return buf
328 if timeout is not None:
329 timeout = deadline - _time()
330 if timeout < 0:
331 break
332 return self.read_very_lazy()
333
334 def read_all(self):
335 """Read all data until EOF; block until connection closed."""
336 self.process_rawq()
337 while not self.eof:
338 self.fill_rawq()
339 self.process_rawq()
340 buf = self.cookedq
341 self.cookedq = b''
342 return buf
343
344 def read_some(self):
345 """Read at least one byte of cooked data unless EOF is hit.
346
347 Return b'' if EOF is hit. Block if no data is immediately
348 available.
349
350 """
351 self.process_rawq()
352 while not self.cookedq and not self.eof:
353 self.fill_rawq()
354 self.process_rawq()
355 buf = self.cookedq
356 self.cookedq = b''
357 return buf
358
359 def read_very_eager(self):
360 """Read everything that's possible without blocking in I/O (eager).
361
362 Raise EOFError if connection closed and no cooked data
363 available. Return b'' if no cooked data available otherwise.
364 Don't block unless in the midst of an IAC sequence.
365
366 """
367 self.process_rawq()
368 while not self.eof and self.sock_avail():
369 self.fill_rawq()
370 self.process_rawq()
371 return self.read_very_lazy()
372
373 def read_eager(self):
374 """Read readily available data.
375
376 Raise EOFError if connection closed and no cooked data
377 available. Return b'' if no cooked data available otherwise.
378 Don't block unless in the midst of an IAC sequence.
379
380 """
381 self.process_rawq()
382 while not self.cookedq and not self.eof and self.sock_avail():
383 self.fill_rawq()
384 self.process_rawq()
385 return self.read_very_lazy()
386
387 def read_lazy(self):
388 """Process and return data that's already in the queues (lazy).
389
390 Raise EOFError if connection closed and no data available.
391 Return b'' if no cooked data available otherwise. Don't block
392 unless in the midst of an IAC sequence.
393
394 """
395 self.process_rawq()
396 return self.read_very_lazy()
397
398 def read_very_lazy(self):
399 """Return any data available in the cooked queue (very lazy).
400
401 Raise EOFError if connection closed and no data available.
402 Return b'' if no cooked data available otherwise. Don't block.
403
404 """
405 buf = self.cookedq
406 self.cookedq = b''
407 if not buf and self.eof and not self.rawq:
408 raise EOFError('telnet connection closed')
409 return buf
410
411 def read_sb_data(self):
412 """Return any data available in the SB ... SE queue.
413
414 Return b'' if no SB ... SE available. Should only be called
415 after seeing a SB or SE command. When a new SB command is
416 found, old unread SB data will be discarded. Don't block.
417
418 """
419 buf = self.sbdataq
420 self.sbdataq = b''
421 return buf
422
423 def set_option_negotiation_callback(self, callback):
424 """Provide a callback function called after each receipt of a telnet option."""
425 self.option_callback = callback
426
427 def process_rawq(self):
428 """Transfer from raw queue to cooked queue.
429
430 Set self.eof when connection is closed. Don't block unless in
431 the midst of an IAC sequence.
432
433 """
434 buf = [b'', b'']
435 try:
436 while self.rawq:
437 c = self.rawq_getchar()
438 if not self.iacseq:
439 if c == theNULL:
440 continue
441 if c == b"\021":
442 continue
443 if c != IAC:
444 buf[self.sb] = buf[self.sb] + c
445 continue
446 else:
447 self.iacseq += c
448 elif len(self.iacseq) == 1:
449 # 'IAC: IAC CMD [OPTION only for WILL/WONT/DO/DONT]'
450 if c in (DO, DONT, WILL, WONT):
451 self.iacseq += c
452 continue
453
454 self.iacseq = b''
455 if c == IAC:
456 buf[self.sb] = buf[self.sb] + c
457 else:
458 if c == SB: # SB ... SE start.
459 self.sb = 1
460 self.sbdataq = b''
461 elif c == SE:
462 self.sb = 0
463 self.sbdataq = self.sbdataq + buf[1]
464 buf[1] = b''
465 if self.option_callback:
466 # Callback is supposed to look into
467 # the sbdataq
468 self.option_callback(self.sock, c, NOOPT)
469 else:
470 # We can't offer automatic processing of
471 # suboptions. Alas, we should not get any
472 # unless we did a WILL/DO before.
473 self.msg('IAC %d not recognized' % ord(c))
474 elif len(self.iacseq) == 2:
475 cmd = self.iacseq[1:2]
476 self.iacseq = b''
477 opt = c
478 if cmd in (DO, DONT):
479 self.msg('IAC %s %d',
480 cmd == DO and 'DO' or 'DONT', ord(opt))
481 if self.option_callback:
482 self.option_callback(self.sock, cmd, opt)
483 else:
484 self.sock.sendall(IAC + WONT + opt)
485 elif cmd in (WILL, WONT):
486 self.msg('IAC %s %d',
487 cmd == WILL and 'WILL' or 'WONT', ord(opt))
488 if self.option_callback:
489 self.option_callback(self.sock, cmd, opt)
490 else:
491 self.sock.sendall(IAC + DONT + opt)
492 except EOFError: # raised by self.rawq_getchar()
493 self.iacseq = b'' # Reset on EOF
494 self.sb = 0
495 self.cookedq = self.cookedq + buf[0]
496 self.sbdataq = self.sbdataq + buf[1]
497
498 def rawq_getchar(self):
499 """Get next char from raw queue.
500
501 Block if no data is immediately available. Raise EOFError
502 when connection is closed.
503
504 """
505 if not self.rawq:
506 self.fill_rawq()
507 if self.eof:
508 raise EOFError
509 c = self.rawq[self.irawq:self.irawq+1]
510 self.irawq = self.irawq + 1
511 if self.irawq >= len(self.rawq):
512 self.rawq = b''
513 self.irawq = 0
514 return c
515
516 def fill_rawq(self):
517 """Fill raw queue from exactly one recv() system call.
518
519 Block if no data is immediately available. Set self.eof when
520 connection is closed.
521
522 """
523 if self.irawq >= len(self.rawq):
524 self.rawq = b''
525 self.irawq = 0
526 # The buffer size should be fairly small so as to avoid quadratic
527 # behavior in process_rawq() above
528 buf = self.sock.recv(50)
529 self.msg("recv %r", buf)
530 self.eof = (not buf)
531 self.rawq = self.rawq + buf
532
533 def sock_avail(self):
534 """Test whether data is available on the socket."""
535 with _TelnetSelector() as selector:
536 selector.register(self, selectors.EVENT_READ)
537 return bool(selector.select(0))
538
539 def interact(self):
540 """Interaction function, emulates a very dumb telnet client."""
541 if sys.platform == "win32":
542 self.mt_interact()
543 return
544 with _TelnetSelector() as selector:
545 selector.register(self, selectors.EVENT_READ)
546 selector.register(sys.stdin, selectors.EVENT_READ)
547
548 while True:
549 for key, events in selector.select():
550 if key.fileobj is self:
551 try:
552 text = self.read_eager()
553 except EOFError:
554 print('*** Connection closed by remote host ***')
555 return
556 if text:
557 sys.stdout.write(text.decode('ascii'))
558 sys.stdout.flush()
559 elif key.fileobj is sys.stdin:
560 line = sys.stdin.readline().encode('ascii')
561 if not line:
562 return
563 self.write(line)
564
565 def mt_interact(self):
566 """Multithreaded version of interact()."""
567 import _thread
568 _thread.start_new_thread(self.listener, ())
569 while 1:
570 line = sys.stdin.readline()
571 if not line:
572 break
573 self.write(line.encode('ascii'))
574
575 def listener(self):
576 """Helper for mt_interact() -- this executes in the other thread."""
577 while 1:
578 try:
579 data = self.read_eager()
580 except EOFError:
581 print('*** Connection closed by remote host ***')
582 return
583 if data:
584 sys.stdout.write(data.decode('ascii'))
585 else:
586 sys.stdout.flush()
587
588 def expect(self, list, timeout=None):
589 """Read until one from a list of a regular expressions matches.
590
591 The first argument is a list of regular expressions, either
592 compiled (re.Pattern instances) or uncompiled (strings).
593 The optional second argument is a timeout, in seconds; default
594 is no timeout.
595
596 Return a tuple of three items: the index in the list of the
597 first regular expression that matches; the re.Match object
598 returned; and the text read up till and including the match.
599
600 If EOF is read and no text was read, raise EOFError.
601 Otherwise, when nothing matches, return (-1, None, text) where
602 text is the text received so far (may be the empty string if a
603 timeout happened).
604
605 If a regular expression ends with a greedy match (e.g. '.*')
606 or if more than one expression can match the same input, the
607 results are undeterministic, and may depend on the I/O timing.
608
609 """
610 re = None
611 list = list[:]
612 indices = range(len(list))
613 for i in indices:
614 if not hasattr(list[i], "search"):
615 if not re: import re
616 list[i] = re.compile(list[i])
617 if timeout is not None:
618 deadline = _time() + timeout
619 with _TelnetSelector() as selector:
620 selector.register(self, selectors.EVENT_READ)
621 while not self.eof:
622 self.process_rawq()
623 for i in indices:
624 m = list[i].search(self.cookedq)
625 if m:
626 e = m.end()
627 text = self.cookedq[:e]
628 self.cookedq = self.cookedq[e:]
629 return (i, m, text)
630 if timeout is not None:
631 ready = selector.select(timeout)
632 timeout = deadline - _time()
633 if not ready:
634 if timeout < 0:
635 break
636 else:
637 continue
638 self.fill_rawq()
639 text = self.read_very_lazy()
640 if not text and self.eof:
641 raise EOFError
642 return (-1, None, text)
643
644 def __enter__(self):
645 return self
646
647 def __exit__(self, type, value, traceback):
648 self.close()
649
650
651 def test():
652 """Test program for telnetlib.
653
654 Usage: python telnetlib.py [-d] ... [host [port]]
655
656 Default host is localhost; default port is 23.
657
658 """
659 debuglevel = 0
660 while sys.argv[1:] and sys.argv[1] == '-d':
661 debuglevel = debuglevel+1
662 del sys.argv[1]
663 host = 'localhost'
664 if sys.argv[1:]:
665 host = sys.argv[1]
666 port = 0
667 if sys.argv[2:]:
668 portstr = sys.argv[2]
669 try:
670 port = int(portstr)
671 except ValueError:
672 port = socket.getservbyname(portstr, 'tcp')
673 with Telnet() as tn:
674 tn.set_debuglevel(debuglevel)
675 tn.open(host, port, timeout=0.5)
676 tn.interact()
677
678 if __name__ == '__main__':
679 test()