def read_header(self, s): if self._read_header(s): if self.multihandler.config['crypto_only']: return None return 8, self.read_options if not self.multihandler.config['crypto_allowed']: return None self.encrypted = True self.encrypter = Crypto(False) self._write_buffer(s) return self.encrypter.keylength, self.read_crypto_header
class NewSocketHandler: # hand a new socket off where it belongs def __init__(self, multihandler, connection): self.multihandler = multihandler self.connection = connection connection.set_handler(self) self.closed = False self.buffer = '' self.complete = False self.read = self._read self.write = connection.write self.next_len = 1 + len(protocol_name) self.next_func = self.read_header self.multihandler.rawserver.add_task(self._auto_close, 30) def _auto_close(self): if not self.complete: self.close() def close(self): if not self.closed: self.connection.close() self.closed = True # copied from Encrypter and modified def _read_header(self, s): if s == chr(len(protocol_name)) + protocol_name: self.protocol = protocol_name return 8, self.read_options return None def read_header(self, s): if self._read_header(s): if self.multihandler.config['crypto_only']: return None return 8, self.read_options if not self.multihandler.config['crypto_allowed']: return None self.encrypted = True self.encrypter = Crypto(False) self._write_buffer(s) return self.encrypter.keylength, self.read_crypto_header def read_crypto_header(self, s): self.encrypter.received_key(s) self.write(self.encrypter.pubkey + self.encrypter.padding()) self._max_search = 520 return 0, self.read_crypto_block3a def _search_for_pattern(self, s, pat): p = s.find(pat) if p < 0: self._max_search -= len(s) + 1 - len(pat) if self._max_search < 0: self.close() return False self._write_buffer(s[1 - len(pat):]) return False self._write_buffer(s[p + len(pat):]) return True def read_crypto_block3a(self, s): if not self._search_for_pattern(s, self.encrypter.block3a): return -1, self.read_crypto_block3a # wait for more data return 20, self.read_crypto_block3b def read_crypto_block3b(self, s): srs = self.multihandler.singlerawservers for k in srs: if self.encrypter.test_skey(s, k): srs[k]._external_connection_made(self.connection, None, self.buffer, encrypted=self.encrypter) return True return None def read_options(self, s): self.options = s return 20, self.read_download_id def read_download_id(self, s): srs = self.multihandler.singlerawservers if s in srs: if srs[s].protocol == self.protocol: srs[s]._external_connection_made(self.connection, self.options, self.buffer) return True return None def read_dead(self, s): return None def data_came_in(self, garbage, s): self.read(s) def _write_buffer(self, s): self.buffer = s + self.buffer def _read(self, s): self.buffer += s while True: if self.closed: return # self.next_len = # of characters function expects # or 0 = all characters in the buffer # or -1 = wait for next read, then all characters in the buffer if self.next_len <= 0: m = self.buffer self.buffer = '' elif len(self.buffer) >= self.next_len: m = self.buffer[:self.next_len] self.buffer = self.buffer[self.next_len:] else: return try: x = self.next_func(m) except: self.next_len, self.next_func = 1, self.read_dead raise if x is None: self.close() return if x: self.complete = True return self.next_len, self.next_func = x if self.next_len < 0: # already checked buffer return # wait for additional data def connection_flushed(self, ss): pass def connection_lost(self, ss): self.closed = True
class NewSocketHandler: # hand a new socket off where it belongs def __init__(self, multihandler, connection): self.multihandler = multihandler self.connection = connection connection.set_handler(self) self.closed = False self.buffer = '' self.complete = False self.read = self._read self.write = connection.write self.next_len, self.next_func = 1+len(PROTOCOL_NAME), self.read_header self.multihandler.rawserver.add_task(self._auto_close, 30) def _auto_close(self): if not self.complete: self.close() def close(self): if not self.closed: self.connection.close() self.closed = True # copied from Encrypter and modified def _read_header(self, s): if s == chr(len(PROTOCOL_NAME))+PROTOCOL_NAME: self.protocol = PROTOCOL_NAME return 8, self.read_options elif s[:3] == "GET": self.protocol = "HTTP" return True else: self.protocol = "UNKNOWN" return None def read_header(self, s): if self._read_header(s): if self.protocol == "HTTP": return True if self.multihandler.config['crypto_only']: return None return 8, self.read_options if not self.multihandler.config['crypto_allowed']: return None self.encrypted = True self.encrypter = Crypto(False) self._write_buffer(s) return self.encrypter.keylength, self.read_crypto_header def read_crypto_header(self, s): self.encrypter.received_key(s) self.write(self.encrypter.pubkey+self.encrypter.padding()) self._max_search = 520 return 0, self.read_crypto_block3a def _search_for_pattern(self, s, pat): p = s.find(pat) if p < 0: self._max_search -= len(s)+1-len(pat) if self._max_search < 0: self.close() return False self._write_buffer(s[1-len(pat):]) return False self._write_buffer(s[p+len(pat):]) return True def read_crypto_block3a(self, s): if not self._search_for_pattern(s,self.encrypter.block3a): return -1, self.read_crypto_block3a # wait for more data return 20, self.read_crypto_block3b def read_crypto_block3b(self, s): for k in self.multihandler.singlerawservers.keys(): if self.encrypter.test_skey(s,k): self.multihandler.singlerawservers[k]._external_connection_made( self.connection, None, self.buffer, encrypted = self.encrypter ) return True return None def read_options(self, s): self.options = Bitfield(64, s) return 20, self.read_download_id def read_download_id(self, s): if s in self.multihandler.singlerawservers: if self.multihandler.singlerawservers[s].protocol == self.protocol: self.multihandler.singlerawservers[s]._external_connection_made( self.connection, self.options, self.buffer) return True return None def read_dead(self, s): return None def data_came_in(self, garbage, s): self.read(s) def _write_buffer(self, s): self.buffer = s+self.buffer def _read(self, s): self.buffer += s while True: if self.closed: return # self.next_len = # of characters function expects # or 0 = all characters in the buffer # or -1 = wait for next read, then all characters in the buffer if self.next_len <= 0: m = self.buffer self.buffer = '' elif len(self.buffer) >= self.next_len: m = self.buffer[:self.next_len] self.buffer = self.buffer[self.next_len:] else: return try: x = self.next_func(m) except: self.next_len, self.next_func = 1, self.read_dead raise if x is None: self.close() return if x == True: if self.protocol == "HTTP" and self.multihandler.http: self.multihandler.http.external_connection_made(self.connection) self.multihandler.http.data_came_in(self.connection, s) self.complete = True return self.next_len, self.next_func = x if self.next_len < 0: # already checked buffer return # wait for additional data def connection_flushed(self, ss): pass def connection_lost(self, ss): self.closed = True