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