"""Telnet.""" from pypacker import pypacker, triggerlist import struct 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 class TelnetTriggerList(triggerlist.TriggerList): def _pack(self): return b"".join(self) TELNET_OPTION_START = b"\xff\xaa" TELNET_OPTION_END = b"\xff\x00" class Telnet(pypacker.Packet): __hdr__ = ( ("telnet_data", None, TelnetTriggerList), ) def _dissect(self, buf): self._init_triggerlist("telnet_data", buf, self._parse_data) return len(buf) @staticmethod def _parse_data(buf): off = 0 t_data = [] t_len = len(buf) # parse telnet data: # fffaXX = start of options # fff0 = end of options while off < t_len: if buf[off: off + 2] == TELNET_OPTION_START: # add start marker t_data.append(buf[off: off + 3]) off += 3 # find end of option idx_end = buf.find(TELNET_OPTION_END, off) # add option data t_data.append(buf[off: idx_end + 1]) # add end marker t_data.append(TELNET_OPTION_END) off = idx_end + 2 else: # add command t_data.append(buf[off: off + 3]) off += 3 return t_data def strip_options(buf): """Return a list of lines and dict of options from telnet data.""" l = buf.split(struct.pack("B", IAC)) b = [] d = {} subopt = False for w in l: if not w: continue o = 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