コード例 #1
0
 def _send_kexinit(self):
     """_send_kexinit(self) -> None
     Sets self2remote.kexinit_packet.
     Separate function to help with unittests.
     """
     cookie = random.get_random_data(16)
     server_keys = [x.name for x in self.self2remote.supported_server_keys]
     server_keys.reverse()
     packet = ssh_packet.pack_payload(
         ssh_packet.PAYLOAD_MSG_KEXINIT,
         (
             SSH_MSG_KEXINIT,
             cookie,
             [x.name for x in self.self2remote.supported_key_exchanges],
             # [x.name for x in self.self2remote.supported_server_keys],
             server_keys,
             [x.name for x in self.c2s.supported_ciphers],
             [x.name for x in self.s2c.supported_ciphers],
             [x.name for x in self.c2s.supported_macs],
             [x.name for x in self.s2c.supported_macs],
             [x.name for x in self.c2s.supported_compressions],
             [x.name for x in self.s2c.supported_compressions],
             [x.name for x in self.c2s.supported_languages],
             [x.name for x in self.s2c.supported_languages],
             self.self2remote.proactive_kex,  # first_kex_packet_follows
             0  # reserved
         ))
     self.self2remote.kexinit_packet = packet
     return packet
コード例 #2
0
    def _send_packet(self, data):
        # Packet is:
        # uint32 packet_length
        # byte padding_length
        # byte[n1] payload
        # byte[n2] random padding
        # byte[m] MAC
        self.debug.write(ssh_debug.DEBUG_3, 'send_packet( len(data)=%i )',
                         (len(data), ))
        data = self.self2remote.compression.compress(data)

        # packet_len + padding_length + payload + random_padding
        # must be multiple of cipher block size.
        block_size = max(8, self.self2remote.cipher.block_size)
        padding_length = block_size - ((5 + len(data)) % block_size)
        if padding_length < 4:
            padding_length += block_size
        # Total packet size must also be at least 16 bytes.
        base_size = 5 + len(data) + padding_length
        minimum_size = max(16, block_size)
        if base_size < minimum_size:
            self.debug.write(ssh_debug.DEBUG_2,
                             'send_packet: base size too small')
            # Add enough padding to make it big enough.
            # Make a first guess of the padding length.
            padding_length_guess = minimum_size - base_size
            # See how much larger it should be to make it a multiple of the
            # block size.
            additional_padding_length = block_size - (
                (5 + len(data) + padding_length_guess) % block_size)
            padding_length = padding_length_guess + additional_padding_length

        self.debug.write(ssh_debug.DEBUG_2, 'send_packet: padding_length=%i',
                         (padding_length, ))
        self.debug.write(ssh_debug.DEBUG_2, 'send_packet: cipher=%s',
                         (self.self2remote.cipher.name, ))

        packet_length = 1 + len(data) + padding_length
        self.debug.write(ssh_debug.DEBUG_2, 'send_packet: packet_length=%i',
                         (packet_length, ))

        random_padding = random.get_random_data(padding_length)
        chunk = struct.pack('>Ic', packet_length,
                            chr(padding_length)) + data + random_padding
        self.debug.write(ssh_debug.DEBUG_2, 'send_packet: chunk_length=%i',
                         (len(chunk), ))

        mac = self.self2remote.mac.digest(
            self.self2remote.packet_sequence_number, chunk)
        self.self2remote.inc_packet_sequence_number()
        self.debug.write(ssh_debug.DEBUG_2, 'send_packet: mac=%r', (mac, ))

        # self.debug.write(ssh_debug.DEBUG_2, 'send_packet: chunk=%r', (chunk,))
        encrypted_chunk = self.self2remote.cipher.encrypt(chunk)
        # self.debug.write(ssh_debug.DEBUG_2, 'send_packet: encrypted_chunk=%r', (encrypted_chunk,))

        self.transport.write(encrypted_chunk + mac)