source: python/trunk/Lib/telnetlib.py@ 394

Last change on this file since 394 was 391, checked in by dmik, 11 years ago

python: Merge vendor 2.7.6 to trunk.

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