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 sock = self.sock 258 self.sock = 0 259 self.eof = 1 260 self.iacseq = '' 261 self.sb = 0 262 if sock: 263 sock.close() 264 265 def get_socket(self): 266 """Return the socket object used internally.""" 267 return self.sock 268 269 def fileno(self): 270 """Return the fileno() of the socket object used internally.""" 271 return self.sock.fileno() 272 273 def write(self, buffer): 274 """Write a string to the socket, doubling any IAC characters. 275 276 Can block if the connection is blocked. May raise 277 socket.error if the connection is closed. 278 279 """ 280 if IAC in buffer: 281 buffer = buffer.replace(IAC, IAC+IAC) 282 self.msg("send %r", buffer) 283 self.sock.sendall(buffer) 284 285 def read_until(self, match, timeout=None): 286 """Read until a given string is encountered or until timeout. 287 288 When no match is found, return whatever is available instead, 289 possibly the empty string. Raise EOFError if the connection 290 is closed and no cooked data is available. 291 292 """ 293 if self._has_poll: 294 return self._read_until_with_poll(match, timeout) 295 else: 296 return self._read_until_with_select(match, timeout) 297 298 def _read_until_with_poll(self, match, timeout): 299 """Read until a given string is encountered or until timeout. 300 301 This method uses select.poll() to implement the timeout. 302 """ 303 n = len(match) 304 call_timeout = timeout 305 if timeout is not None: 306 from time import time 307 time_start = time() 308 self.process_rawq() 309 i = self.cookedq.find(match) 310 if i < 0: 311 poller = select.poll() 312 poll_in_or_priority_flags = select.POLLIN | select.POLLPRI 313 poller.register(self, poll_in_or_priority_flags) 314 while i < 0 and not self.eof: 315 try: 316 # Poll takes its timeout in milliseconds. 317 ready = poller.poll(None if timeout is None 318 else 1000 * call_timeout) 319 except select.error as e: 320 if e[0] == errno.EINTR: 321 if timeout is not None: 322 elapsed = time() - time_start 323 call_timeout = timeout-elapsed 324 continue 325 raise 326 for fd, mode in ready: 327 if mode & poll_in_or_priority_flags: 328 i = max(0, len(self.cookedq)-n) 329 self.fill_rawq() 330 self.process_rawq() 331 i = self.cookedq.find(match, i) 332 if timeout is not None: 333 elapsed = time() - time_start 334 if elapsed >= timeout: 335 break 336 call_timeout = timeout-elapsed 337 poller.unregister(self) 338 if i >= 0: 339 i = i + n 340 buf = self.cookedq[:i] 341 self.cookedq = self.cookedq[i:] 342 return buf 343 return self.read_very_lazy() 344 345 def _read_until_with_select(self, match, timeout=None): 346 """Read until a given string is encountered or until timeout. 347 348 The timeout is implemented using select.select(). 349 """ 350 n = len(match) 351 self.process_rawq() 352 i = self.cookedq.find(match) 353 if i >= 0: 354 i = i+n 355 buf = self.cookedq[:i] 356 self.cookedq = self.cookedq[i:] 357 return buf 358 s_reply = ([self], [], []) 359 s_args = s_reply 360 if timeout is not None: 361 s_args = s_args + (timeout,) 362 from time import time 363 time_start = time() 364 while not self.eof and select.select(*s_args) == s_reply: 365 i = max(0, len(self.cookedq)-n) 366 self.fill_rawq() 367 self.process_rawq() 368 i = self.cookedq.find(match, i) 369 if i >= 0: 370 i = i+n 371 buf = self.cookedq[:i] 372 self.cookedq = self.cookedq[i:] 373 return buf 374 if timeout is not None: 375 elapsed = time() - time_start 376 if elapsed >= timeout: 377 break 378 s_args = s_reply + (timeout-elapsed,) 379 return self.read_very_lazy() 380 381 def read_all(self): 382 """Read all data until EOF; block until connection closed.""" 383 self.process_rawq() 384 while not self.eof: 385 self.fill_rawq() 386 self.process_rawq() 387 buf = self.cookedq 388 self.cookedq = '' 389 return buf 390 391 def read_some(self): 392 """Read at least one byte of cooked data unless EOF is hit. 393 394 Return '' if EOF is hit. Block if no data is immediately 395 available. 396 397 """ 398 self.process_rawq() 399 while not self.cookedq and not self.eof: 400 self.fill_rawq() 401 self.process_rawq() 402 buf = self.cookedq 403 self.cookedq = '' 404 return buf 405 406 def read_very_eager(self): 407 """Read everything that's possible without blocking in I/O (eager). 408 409 Raise EOFError if connection closed and no cooked data 410 available. Return '' if no cooked data available otherwise. 411 Don't block unless in the midst of an IAC sequence. 412 413 """ 414 self.process_rawq() 415 while not self.eof and self.sock_avail(): 416 self.fill_rawq() 417 self.process_rawq() 418 return self.read_very_lazy() 419 420 def read_eager(self): 421 """Read readily available data. 422 423 Raise EOFError if connection closed and no cooked data 424 available. Return '' if no cooked data available otherwise. 425 Don't block unless in the midst of an IAC sequence. 426 427 """ 428 self.process_rawq() 429 while not self.cookedq and not self.eof and self.sock_avail(): 430 self.fill_rawq() 431 self.process_rawq() 432 return self.read_very_lazy() 433 434 def read_lazy(self): 435 """Process and return data that's already in the queues (lazy). 436 437 Raise EOFError if connection closed and no data available. 438 Return '' if no cooked data available otherwise. Don't block 439 unless in the midst of an IAC sequence. 440 441 """ 442 self.process_rawq() 443 return self.read_very_lazy() 444 445 def read_very_lazy(self): 446 """Return any data available in the cooked queue (very lazy). 447 448 Raise EOFError if connection closed and no data available. 449 Return '' if no cooked data available otherwise. Don't block. 450 451 """ 452 buf = self.cookedq 453 self.cookedq = '' 454 if not buf and self.eof and not self.rawq: 455 raise EOFError, 'telnet connection closed' 456 return buf 457 458 def read_sb_data(self): 459 """Return any data available in the SB ... SE queue. 460 461 Return '' if no SB ... SE available. Should only be called 462 after seeing a SB or SE command. When a new SB command is 463 found, old unread SB data will be discarded. Don't block. 464 465 """ 466 buf = self.sbdataq 467 self.sbdataq = '' 468 return buf 469 470 def set_option_negotiation_callback(self, callback): 471 """Provide a callback function called after each receipt of a telnet option.""" 472 self.option_callback = callback 473 474 def process_rawq(self): 475 """Transfer from raw queue to cooked queue. 476 477 Set self.eof when connection is closed. Don't block unless in 478 the midst of an IAC sequence. 479 480 """ 481 buf = ['', ''] 482 try: 483 while self.rawq: 484 c = self.rawq_getchar() 485 if not self.iacseq: 486 if c == theNULL: 487 continue 488 if c == "\021": 489 continue 490 if c != IAC: 491 buf[self.sb] = buf[self.sb] + c 492 continue 493 else: 494 self.iacseq += c 495 elif len(self.iacseq) == 1: 496 # 'IAC: IAC CMD [OPTION only for WILL/WONT/DO/DONT]' 497 if c in (DO, DONT, WILL, WONT): 498 self.iacseq += c 499 continue 500 501 self.iacseq = '' 502 if c == IAC: 503 buf[self.sb] = buf[self.sb] + c 504 else: 505 if c == SB: # SB ... SE start. 506 self.sb = 1 507 self.sbdataq = '' 508 elif c == SE: 509 self.sb = 0 510 self.sbdataq = self.sbdataq + buf[1] 511 buf[1] = '' 512 if self.option_callback: 513 # Callback is supposed to look into 514 # the sbdataq 515 self.option_callback(self.sock, c, NOOPT) 516 else: 517 # We can't offer automatic processing of 518 # suboptions. Alas, we should not get any 519 # unless we did a WILL/DO before. 520 self.msg('IAC %d not recognized' % ord(c)) 521 elif len(self.iacseq) == 2: 522 cmd = self.iacseq[1] 523 self.iacseq = '' 524 opt = c 525 if cmd in (DO, DONT): 526 self.msg('IAC %s %d', 527 cmd == DO and 'DO' or 'DONT', ord(opt)) 528 if self.option_callback: 529 self.option_callback(self.sock, cmd, opt) 530 else: 531 self.sock.sendall(IAC + WONT + opt) 532 elif cmd in (WILL, WONT): 533 self.msg('IAC %s %d', 534 cmd == WILL and 'WILL' or 'WONT', ord(opt)) 535 if self.option_callback: 536 self.option_callback(self.sock, cmd, opt) 537 else: 538 self.sock.sendall(IAC + DONT + opt) 539 except EOFError: # raised by self.rawq_getchar() 540 self.iacseq = '' # Reset on EOF 541 self.sb = 0 542 pass 543 self.cookedq = self.cookedq + buf[0] 544 self.sbdataq = self.sbdataq + buf[1] 545 546 def rawq_getchar(self): 547 """Get next char from raw queue. 548 549 Block if no data is immediately available. Raise EOFError 550 when connection is closed. 551 552 """ 553 if not self.rawq: 554 self.fill_rawq() 555 if self.eof: 556 raise EOFError 557 c = self.rawq[self.irawq] 558 self.irawq = self.irawq + 1 559 if self.irawq >= len(self.rawq): 560 self.rawq = '' 561 self.irawq = 0 562 return c 563 564 def fill_rawq(self): 565 """Fill raw queue from exactly one recv() system call. 566 567 Block if no data is immediately available. Set self.eof when 568 connection is closed. 569 570 """ 571 if self.irawq >= len(self.rawq): 572 self.rawq = '' 573 self.irawq = 0 574 # The buffer size should be fairly small so as to avoid quadratic 575 # behavior in process_rawq() above 576 buf = self.sock.recv(50) 577 self.msg("recv %r", buf) 578 self.eof = (not buf) 579 self.rawq = self.rawq + buf 580 581 def sock_avail(self): 582 """Test whether data is available on the socket.""" 583 return select.select([self], [], [], 0) == ([self], [], []) 584 585 def interact(self): 586 """Interaction function, emulates a very dumb telnet client.""" 587 if sys.platform == "win32": 588 self.mt_interact() 589 return 590 while 1: 591 rfd, wfd, xfd = select.select([self, sys.stdin], [], []) 592 if self in rfd: 593 try: 594 text = self.read_eager() 595 except EOFError: 596 print '*** Connection closed by remote host ***' 597 break 598 if text: 599 sys.stdout.write(text) 600 sys.stdout.flush() 601 if sys.stdin in rfd: 602 line = sys.stdin.readline() 603 if not line: 604 break 605 self.write(line) 606 607 def mt_interact(self): 608 """Multithreaded version of interact().""" 609 import thread 610 thread.start_new_thread(self.listener, ()) 611 while 1: 612 line = sys.stdin.readline() 613 if not line: 614 break 615 self.write(line) 616 617 def listener(self): 618 """Helper for mt_interact() -- this executes in the other thread.""" 619 while 1: 620 try: 621 data = self.read_eager() 622 except EOFError: 623 print '*** Connection closed by remote host ***' 624 return 625 if data: 626 sys.stdout.write(data) 627 else: 628 sys.stdout.flush() 629 630 def expect(self, list, timeout=None): 631 """Read until one from a list of a regular expressions matches. 632 633 The first argument is a list of regular expressions, either 634 compiled (re.RegexObject instances) or uncompiled (strings). 635 The optional second argument is a timeout, in seconds; default 636 is no timeout. 637 638 Return a tuple of three items: the index in the list of the 639 first regular expression that matches; the match object 640 returned; and the text read up till and including the match. 641 642 If EOF is read and no text was read, raise EOFError. 643 Otherwise, when nothing matches, return (-1, None, text) where 644 text is the text received so far (may be the empty string if a 645 timeout happened). 646 647 If a regular expression ends with a greedy match (e.g. '.*') 648 or if more than one expression can match the same input, the 649 results are undeterministic, and may depend on the I/O timing. 650 651 """ 652 if self._has_poll: 653 return self._expect_with_poll(list, timeout) 654 else: 655 return self._expect_with_select(list, timeout) 656 657 def _expect_with_poll(self, expect_list, timeout=None): 658 """Read until one from a list of a regular expressions matches. 659 660 This method uses select.poll() to implement the timeout. 661 """ 662 re = None 663 expect_list = expect_list[:] 664 indices = range(len(expect_list)) 665 for i in indices: 666 if not hasattr(expect_list[i], "search"): 667 if not re: import re 668 expect_list[i] = re.compile(expect_list[i]) 669 call_timeout = timeout 670 if timeout is not None: 671 from time import time 672 time_start = time() 673 self.process_rawq() 674 m = None 675 for i in indices: 676 m = expect_list[i].search(self.cookedq) 677 if m: 678 e = m.end() 679 text = self.cookedq[:e] 680 self.cookedq = self.cookedq[e:] 681 break 682 if not m: 683 poller = select.poll() 684 poll_in_or_priority_flags = select.POLLIN | select.POLLPRI 685 poller.register(self, poll_in_or_priority_flags) 686 while not m and not self.eof: 687 try: 688 ready = poller.poll(None if timeout is None 689 else 1000 * call_timeout) 690 except select.error as e: 691 if e[0] == errno.EINTR: 692 if timeout is not None: 693 elapsed = time() - time_start 694 call_timeout = timeout-elapsed 695 continue 696 raise 697 for fd, mode in ready: 698 if mode & poll_in_or_priority_flags: 699 self.fill_rawq() 700 self.process_rawq() 701 for i in indices: 702 m = expect_list[i].search(self.cookedq) 703 if m: 704 e = m.end() 705 text = self.cookedq[:e] 706 self.cookedq = self.cookedq[e:] 707 break 708 if timeout is not None: 709 elapsed = time() - time_start 710 if elapsed >= timeout: 711 break 712 call_timeout = timeout-elapsed 713 poller.unregister(self) 714 if m: 715 return (i, m, text) 716 text = self.read_very_lazy() 717 if not text and self.eof: 718 raise EOFError 719 return (-1, None, text) 720 721 def _expect_with_select(self, list, timeout=None): 722 """Read until one from a list of a regular expressions matches. 723 724 The timeout is implemented using select.select(). 725 """ 726 re = None 727 list = list[:] 728 indices = range(len(list)) 729 for i in indices: 730 if not hasattr(list[i], "search"): 731 if not re: import re 732 list[i] = re.compile(list[i]) 733 if timeout is not None: 734 from time import time 735 time_start = time() 736 while 1: 737 self.process_rawq() 738 for i in indices: 739 m = list[i].search(self.cookedq) 740 if m: 741 e = m.end() 742 text = self.cookedq[:e] 743 self.cookedq = self.cookedq[e:] 744 return (i, m, text) 745 if self.eof: 746 break 747 if timeout is not None: 748 elapsed = time() - time_start 749 if elapsed >= timeout: 750 break 751 s_args = ([self.fileno()], [], [], timeout-elapsed) 752 r, w, x = select.select(*s_args) 753 if not r: 754 break 755 self.fill_rawq() 756 text = self.read_very_lazy() 757 if not text and self.eof: 758 raise EOFError 759 return (-1, None, text) 760 761 762def test(): 763 """Test program for telnetlib. 764 765 Usage: python telnetlib.py [-d] ... [host [port]] 766 767 Default host is localhost; default port is 23. 768 769 """ 770 debuglevel = 0 771 while sys.argv[1:] and sys.argv[1] == '-d': 772 debuglevel = debuglevel+1 773 del sys.argv[1] 774 host = 'localhost' 775 if sys.argv[1:]: 776 host = sys.argv[1] 777 port = 0 778 if sys.argv[2:]: 779 portstr = sys.argv[2] 780 try: 781 port = int(portstr) 782 except ValueError: 783 port = socket.getservbyname(portstr, 'tcp') 784 tn = Telnet() 785 tn.set_debuglevel(debuglevel) 786 tn.open(host, port, timeout=0.5) 787 tn.interact() 788 tn.close() 789 790if __name__ == '__main__': 791 test() 792