|
1 #! /usr/bin/env python |
|
2 |
|
3 # Minimal interface to the Internet telnet protocol. |
|
4 # |
|
5 # It refuses all telnet options and does not recognize any of the other |
|
6 # telnet commands, but can still be used to connect in line-by-line mode. |
|
7 # It's also useful to play with a number of other services, |
|
8 # like time, finger, smtp and even ftp. |
|
9 # |
|
10 # Usage: telnet host [port] |
|
11 # |
|
12 # The port may be a service name or a decimal port number; |
|
13 # it defaults to 'telnet'. |
|
14 |
|
15 |
|
16 import sys, posix, time |
|
17 from socket import * |
|
18 |
|
19 BUFSIZE = 1024 |
|
20 |
|
21 # Telnet protocol characters |
|
22 |
|
23 IAC = chr(255) # Interpret as command |
|
24 DONT = chr(254) |
|
25 DO = chr(253) |
|
26 WONT = chr(252) |
|
27 WILL = chr(251) |
|
28 |
|
29 def main(): |
|
30 host = sys.argv[1] |
|
31 try: |
|
32 hostaddr = gethostbyname(host) |
|
33 except error: |
|
34 sys.stderr.write(sys.argv[1] + ': bad host name\n') |
|
35 sys.exit(2) |
|
36 # |
|
37 if len(sys.argv) > 2: |
|
38 servname = sys.argv[2] |
|
39 else: |
|
40 servname = 'telnet' |
|
41 # |
|
42 if '0' <= servname[:1] <= '9': |
|
43 port = eval(servname) |
|
44 else: |
|
45 try: |
|
46 port = getservbyname(servname, 'tcp') |
|
47 except error: |
|
48 sys.stderr.write(servname + ': bad tcp service name\n') |
|
49 sys.exit(2) |
|
50 # |
|
51 s = socket(AF_INET, SOCK_STREAM) |
|
52 # |
|
53 try: |
|
54 s.connect((host, port)) |
|
55 except error, msg: |
|
56 sys.stderr.write('connect failed: ' + repr(msg) + '\n') |
|
57 sys.exit(1) |
|
58 # |
|
59 pid = posix.fork() |
|
60 # |
|
61 if pid == 0: |
|
62 # child -- read stdin, write socket |
|
63 while 1: |
|
64 line = sys.stdin.readline() |
|
65 s.send(line) |
|
66 else: |
|
67 # parent -- read socket, write stdout |
|
68 iac = 0 # Interpret next char as command |
|
69 opt = '' # Interpret next char as option |
|
70 while 1: |
|
71 data = s.recv(BUFSIZE) |
|
72 if not data: |
|
73 # EOF; kill child and exit |
|
74 sys.stderr.write( '(Closed by remote host)\n') |
|
75 posix.kill(pid, 9) |
|
76 sys.exit(1) |
|
77 cleandata = '' |
|
78 for c in data: |
|
79 if opt: |
|
80 print ord(c) |
|
81 s.send(opt + c) |
|
82 opt = '' |
|
83 elif iac: |
|
84 iac = 0 |
|
85 if c == IAC: |
|
86 cleandata = cleandata + c |
|
87 elif c in (DO, DONT): |
|
88 if c == DO: print '(DO)', |
|
89 else: print '(DONT)', |
|
90 opt = IAC + WONT |
|
91 elif c in (WILL, WONT): |
|
92 if c == WILL: print '(WILL)', |
|
93 else: print '(WONT)', |
|
94 opt = IAC + DONT |
|
95 else: |
|
96 print '(command)', ord(c) |
|
97 elif c == IAC: |
|
98 iac = 1 |
|
99 print '(IAC)', |
|
100 else: |
|
101 cleandata = cleandata + c |
|
102 sys.stdout.write(cleandata) |
|
103 sys.stdout.flush() |
|
104 |
|
105 |
|
106 try: |
|
107 main() |
|
108 except KeyboardInterrupt: |
|
109 pass |