Advertisement
Guest User

Untitled

a guest
Aug 23rd, 2012
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.76 KB | None | 0 0
  1. from constants import *
  2.  
  3. class Options(object):
  4.     NEGOTIATING = 1
  5.     ALREADY_NEGOTIATING = 2
  6.     ALREADY_ENABLED = 3
  7.  
  8. class Handler(object):
  9.     """This class handles the communication in the telnet protocol."""
  10.  
  11.     def __init__(self, socket):
  12.         """Constructor. Takes a socket object."""
  13.         self.socket = socket
  14.         self.writebuffer = ""
  15.         self.readbuffer = ""
  16.         self.iacseq = ""
  17.  
  18.         self.our_options = set()
  19.         self.our_negotiations = set()
  20.         self.their_negotiations = set()
  21.         self.their_options = set()
  22.  
  23.     def send(self, data):
  24.         """Queues data to be sent into our writebuffer. This doesn't actually
  25.        send anything yet through our socket."""
  26.         self.writebuffer += data
  27.  
  28.     def handle_write(self):
  29.         """Tries to write as much from our writebuffer to the socket. Any
  30.        data that we couldn't write will still be in our writebuffer to be
  31.        sent at a later time."""
  32.         sent = self.socket.send(self.writebuffer)
  33.         self.writebuffer = self.writebuffer[sent:]
  34.  
  35.     def handle_read(self):
  36.         """Tries to read from our socket, interpreting telnet commands and
  37.        storing output into our readbuffer."""
  38.         data = self.socket.recv(1024)
  39.         for c in data:
  40.             if not self.iacseq and c != IAC:
  41.                 #This is just normal output
  42.                 self.readbuffer += c
  43.             else:
  44.                 #We're either in the middle of a telnet command or we just
  45.                 #started one
  46.                 self._handle_iac(c)
  47.  
  48.     def _handle_iac(self, char):
  49.         """Called when parsing a telnet command. Telnet commands always starts
  50.        with an IAC and are two or three bytes: if the command is a DO, DONT,
  51.        WILL or WONT then three, or in every other case two."""
  52.         if not self.iacseq:
  53.             #This is the start of a new IAC command sequence (char will always
  54.             #be IAC here)
  55.             self.iacseq += char
  56.         elif len(self.iacseq) == 1:
  57.             #We already have the first byte of the command, this is the second
  58.             #byte
  59.             if char in (WILL, DONT, DO, WONT):
  60.                 #If it's a telnet option negotiation then we need to get one
  61.                 #more byte
  62.                 self.iacseq += char
  63.             else:
  64.                 if char == IAC:
  65.                     #We got IAC IAC: we need to add a single IAC into our
  66.                     #readbuffer
  67.                     self.readbuffer += IAC
  68.                 self.iacseq = ""
  69.         elif len(self.iacseq) == 2:
  70.             #We got two bytes of a command, this is an option negotiation
  71.             self._handle_option_negotiation(self.iacseq[1], char)
  72.             self.iacseq = ""
  73.  
  74.     def _handle_option_negotiation(self, verb, option):
  75.         """Called when we received a full telnet option negotation."""
  76.         if verb == DO:
  77.             self._handle_do(option)
  78.         elif verb == DONT:
  79.             self._handle_dont(option)
  80.         elif verb == WILL:
  81.             self._handle_will(option)
  82.         elif verb == WONT:
  83.             self._handle_wont(option)
  84.  
  85.     def _handle_do(self, option):
  86.         """Called after we have received an IAC DO <option>"""
  87.         if option in self.our_negotiations:
  88.             self.our_options.add(option)
  89.             self.local_option_enabled(option)
  90.             self.our_negotiations.remove(option)
  91.         elif option not in self.our_options:
  92.             self.send(IAC + WONT + option)
  93.  
  94.     def _handle_dont(self, option):
  95.         """Called after we have received an IAC DONT <option>"""
  96.         if option in self.our_negotiations:
  97.             self.our_negotiations.remove(option)
  98.         elif option in self.our_options:
  99.             self.our_options.remove(option)
  100.             self.local_option_disabled(option)
  101.             self.send(IAC + WONT + option)
  102.  
  103.     def _handle_will(self, option):
  104.         """Called after we have received an IAC WILL <option>"""
  105.         if option in self.their_negotiations:
  106.             self.their_options.add(option)
  107.             self.remote_option_enabled(option)
  108.             self.their_negotiations.remove(option)
  109.         elif option not in self.their_options:
  110.             self.send(IAC + DONT + option)
  111.  
  112.     def _handle_wont(self, option):
  113.         """Called after we have received an IAC WONT <option>"""
  114.         if option in self.their_negotiations:
  115.             self.their_negotiations.remove(option)
  116.         elif option in self.their_options:
  117.             self.their_options.remove(option)
  118.             self.remote_option_disabled(option)
  119.             self.send(IAC + DONT + option)
  120.  
  121.     def enable_local_option(self, option):
  122.         """Tells the remote end that we want to start using option on our end.
  123.        (IAC WILL option).
  124.        If the remote ends agrees then local_option_enabled(option) will
  125.        be called."""
  126.         if option in self.our_options:
  127.             return Options.ALREADY_ENABLED
  128.         elif option in self.our_negotiations:
  129.             return Options.ALREADY_NEGOTIATING
  130.         else:
  131.             self.send(IAC + WILL + option)
  132.             self.our_negotiations.add(option)
  133.             return Options.NEGOTIATING
  134.         return
  135.  
  136.     def enable_remote_option(self, option):
  137.         """Tells the remote end that we want them to start using option on their
  138.        end (IAC DO option).
  139.        If the remote ends agrees then remote_option_enabled(option) will
  140.        be called."""
  141.         if option in self.their_options:
  142.             return Options.ALREADY_ENABLED
  143.         elif option in self.their_negotiations:
  144.             return Options.ALREADY_NEGOTIATING
  145.         else:
  146.             self.send(IAC + DO + option)
  147.             self.their_negotiations.add(option)
  148.             return Options.NEGOTIATING
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement