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