Exemplo n.º 1
0
 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
Exemplo n.º 2
0
 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
Exemplo n.º 3
0
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
Exemplo n.º 4
0
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