blob: 3b08cab9371ca8cb705dff7363d472461fcbb811 [file] [log] [blame]
# $Id: telnet.py 23 2006-11-08 15:45:33Z dugsong $
# -*- coding: utf-8 -*-
"""Telnet."""
from __future__ import print_function
from __future__ import absolute_import
import struct
from .compat import compat_ord
IAC = 255 # interpret as command:
DONT = 254 # you are not to use option
DO = 253 # please, you use option
WONT = 252 # I won't use option
WILL = 251 # I will use option
SB = 250 # interpret as subnegotiation
GA = 249 # you may reverse the line
EL = 248 # erase the current line
EC = 247 # erase the current character
AYT = 246 # are you there
AO = 245 # abort output--but let prog finish
IP = 244 # interrupt process--permanently
BREAK = 243 # break
DM = 242 # data mark--for connect. cleaning
NOP = 241 # nop
SE = 240 # end sub negotiation
EOR = 239 # end of record (transparent mode)
ABORT = 238 # Abort process
SUSP = 237 # Suspend process
xEOF = 236 # End of file: EOF is already used...
SYNCH = 242 # for telfunc calls
def strip_options(buf):
"""Return a list of lines and dict of options from telnet data."""
l_ = buf.split(struct.pack("B", IAC))
# print l_
b = []
d = {}
subopt = False
for w in l_:
if not w:
continue
o = compat_ord(w[0])
if o > SB:
# print 'WILL/WONT/DO/DONT/IAC', `w`
w = w[2:]
elif o == SE:
# print 'SE', `w`
w = w[1:]
subopt = False
elif o == SB:
# print 'SB', `w`
subopt = True
for opt in (b'USER', b'DISPLAY', b'TERM'):
p = w.find(opt + b'\x01')
if p != -1:
d[opt] = w[p + len(opt) + 1:].split(b'\x00', 1)[0]
w = None
elif subopt:
w = None
if w:
w = w.replace(b'\x00', b'\n').splitlines()
if not w[-1]:
w.pop()
b.extend(w)
return b, d
def test_telnet():
l_ = []
s = (b'\xff\xfb\x25\xff\xfa\x25\x00\x00\x00\xff\xf0\xff\xfd\x26\xff\xfa\x26\x05\xff\xf0\xff\xfa'
b'\x26\x01\x01\x02\xff\xf0\xff\xfb\x18\xff\xfb\x20\xff\xfb\x23\xff\xfb\x27\xff\xfc\x24\xff'
b'\xfa\x20\x00\x33\x38\x34\x30\x30\x2c\x33\x38\x34\x30\x30\xff\xf0\xff\xfa\x23\x00\x64\x6f'
b'\x75\x67\x68\x62\x6f\x79\x2e\x63\x69\x74\x69\x2e\x75\x6d\x69\x63\x68\x2e\x65\x64\x75\x3a'
b'\x30\x2e\x30\xff\xf0\xff\xfa\x27\x00\x00\x44\x49\x53\x50\x4c\x41\x59\x01\x64\x6f\x75\x67'
b'\x68\x62\x6f\x79\x2e\x63\x69\x74\x69\x2e\x75\x6d\x69\x63\x68\x2e\x65\x64\x75\x3a\x30\x2e'
b'\x30\x00\x55\x53\x45\x52\x01\x64\x75\x67\x73\x6f\x6e\x67\xff\xf0\xff\xfa\x18\x00\x58\x54'
b'\x45\x52\x4d\xff\xf0\xff\xfd\x03\xff\xfc\x01\xff\xfb\x1f\xff\xfa\x1f\x00\x50\x00\x28\xff'
b'\xf0\xff\xfd\x05\xff\xfb\x21\xff\xfd\x01\x66\x75\x67\x6c\x79\x0d\x00\x79\x6f\x64\x61\x0d'
b'\x00\x62\x61\x73\x68\x74\x61\x72\x64\x0d\x00')
l_.append(s)
s = (b'\xff\xfd\x01\xff\xfd\x03\xff\xfb\x18\xff\xfb\x1f\xff\xfa\x1f\x00\x58\x00\x32\xff\xf0\x61'
b'\x64\x6d\x69\x6e\x0d\x00\xff\xfa\x18\x00\x4c\x49\x4e\x55\x58\xff\xf0\x66\x6f\x6f\x62\x61'
b'\x72\x0d\x00\x65\x6e\x61\x62\x6c\x65\x0d\x00\x66\x6f\x6f\x62\x61\x72\x0d\x00\x0d\x00\x73'
b'\x68\x6f\x77\x20\x69\x70\x20\x69\x6e\x74\x20\x56\x6c\x61\x6e\x20\x36\x36\x36\x0d\x00')
l_.append(s)
s = (b'\xff\xfb\x25\xff\xfa\x25\x00\x00\x00\xff\xf0\xff\xfd\x26\xff\xfa\x26\x05\xff\xf0\xff\xfa'
b'\x26\x01\x01\x02\xff\xf0\xff\xfb\x26\xff\xfb\x18\xff\xfb\x20\xff\xfb\x23\xff\xfb\x27\xff'
b'\xfc\x24\xff\xfa\x20\x00\x33\x38\x34\x30\x30\x2c\x33\x38\x34\x30\x30\xff\xf0\xff\xfa\x23'
b'\x00\x64\x6f\x75\x67\x68\x62\x6f\x79\x2e\x63\x69\x74\x69\x2e\x75\x6d\x69\x63\x68\x2e\x65'
b'\x64\x75\x3a\x30\x2e\x30\xff\xf0\xff\xfa\x27\x00\x00\x44\x49\x53\x50\x4c\x41\x59\x01\x64'
b'\x6f\x75\x67\x68\x62\x6f\x79\x2e\x63\x69\x74\x69\x2e\x75\x6d\x69\x63\x68\x2e\x65\x64\x75'
b'\x3a\x30\x2e\x30\x00\x55\x53\x45\x52\x01\x64\x75\x67\x73\x6f\x6e\x67\xff\xf0\xff\xfa\x18'
b'\x00\x58\x54\x45\x52\x4d\xff\xf0\xff\xfd\x03\xff\xfc\x01\xff\xfb\x22\xff\xfa\x22\x03\x01'
b'\x03\x00\x03\x62\x03\x04\x02\x0f\x05\x00\xff\xff\x07\x62\x1c\x08\x02\x04\x09\x42\x1a\x0a'
b'\x02\x7f\x0b\x02\x15\x0c\x02\x17\x0d\x02\x12\x0e\x02\x16\x0f\x02\x11\x10\x02\x13\x11\x00'
b'\xff\xff\x12\x00\xff\xff\xff\xf0\xff\xfb\x1f\xff\xfa\x1f\x00\x50\x00\x28\xff\xf0\xff\xfd'
b'\x05\xff\xfb\x21\xff\xfa\x22\x01\x0f\xff\xf0\xff\xfd\x01\xff\xfe\x01\xff\xfa\x22\x03\x01'
b'\x80\x00\xff\xf0\xff\xfd\x01\x77\x65\x72\x64\x0d\x0a\xff\xfe\x01\x79\x6f\x64\x61\x0d\x0a'
b'\xff\xfd\x01\x64\x61\x72\x74\x68\x76\x61\x64\x65\x72\x0d\x0a\xff\xfe\x01')
l_.append(s)
exp = [([b'fugly', b'yoda', b'bashtard'], {b'USER': b'dugsong', b'DISPLAY': b'doughboy.citi.umich.edu:0.0'}),
([b'admin', b'foobar', b'enable', b'foobar', b'', b'show ip int Vlan 666'], {}),
([b'werd', b'yoda', b'darthvader'], {b'USER': b'dugsong', b'DISPLAY': b'doughboy.citi.umich.edu:0.0'})]
assert (list(map(strip_options, l_)) == exp)
def test_trailing_null():
from binascii import unhexlify
buf = unhexlify(
'0100020000'
)
b, d = strip_options(buf)
assert b == [b'\x01', b'\x02']
assert d == {}