(root)/
Python-3.12.0/
Lib/
telnetlib.py
       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()