Пример #1
0
 def msg_kexdh_init(self, packet):
     # mpint     e
     msg, self.client_exchange_value = ssh_packet.unpack_payload(
         KEXDH_INIT_PAYLOAD, packet)
     # XXX make sure e is a valid number
     # This is y.
     self.server_random_value = ssh_random.get_random_number(512)
     # p is large safe prime (DH_PRIME)
     # g is a generator for a subgroup of GF(p) (DH_GENERATOR)
     # compute f=g**y mod p
     self.server_exchange_value = pow(DH_GENERATOR,
                                      self.server_random_value, DH_PRIME)
     self.shared_secret = pow(self.client_exchange_value,
                              self.server_random_value, DH_PRIME)
     K_S = self.transport.server_key.get_public_key_blob()
     payload_inputs = (self.c2s_version_string, self.s2c_version_string,
                       self.c2s_kexinit_packet, self.s2c_kexinit_packet,
                       K_S, self.client_exchange_value,
                       self.server_exchange_value, self.shared_secret)
     H = ssh_packet.pack_payload(KEXDH_HASH_PAYLOAD, payload_inputs)
     self.exchange_hash = hashlib.sha1(H).digest()
     if self.session_id is None:
         # The session id is the first exchange hash.
         self.session_id = self.exchange_hash
     H_sig = self.transport.server_key.sign(self.exchange_hash)
     packet = ssh_packet.pack_payload(
         KEXDH_REPLY_PAYLOAD,
         (SSH_MSG_KEXDH_REPLY, K_S, self.server_exchange_value, H_sig))
     self.transport.send_packet(packet)
Пример #2
0
    def send_channel_request(self, request_type, payload, data, want_reply=1, default_reply_handler=True):
        """send_channel_request(self, request_type, payload, data, want_reply=1, default_reply_handler=True) -> None
        This is a generic mechanism for sending a channel request packet.

        <request_type>: Request type to send.
        <payload>: The ssh_packet format definition.
        <data>: The data to go with the payload.
        <want_reply>: The want_reply flag.
        <default_reply_handler>: If true and want_reply is True, then the
                default reply handler will be used.  The default reply
                handler is pretty simple.  Will just return if
                CHANNEL_REQUEST_SUCCESS is received.  Will raise
                Channel_Request_Failure if FAILURE is received.
        """
        # XXX: There is a problem with the spec.  It does not indicate how to
        #      match requests with responses.  IIRC, they talked about it on
        #      the mailing list and updated the spec.  Need to investigate if
        #      they have clarified the spec on how to handle this.
        # XXX: Or maybe concurrent channel requests on the same channel are
        #      not allowed?
        if self.remote_channel.closed:
            raise Channel_Closed_Error
        pkt = packet.pack_payload(
            SSH_MSG_CHANNEL_REQUEST_PAYLOAD,
            (SSH_MSG_CHANNEL_REQUEST, self.remote_channel.channel_id, request_type, int(want_reply)),
        )
        pkt_data = packet.pack_payload(payload, data)
        self.transport.send_packet(pkt + pkt_data)
        if want_reply and default_reply_handler:
            # Wait for response.
            assert len(self.channel_request_cv) == 0, "Concurrent channel requests not supported!"
            if not self.channel_request_cv.wait():
                raise Channel_Request_Failure
Пример #3
0
    def _try_auth(self, packet, loaded_key, username, service_name):
        self.transport.debug.write(
            ssh_debug.DEBUG_1, 'Publickey Auth: Got OK for this key type.')
        msg, key_algorithm_name, key_blob = unpack_payload(
            PAYLOAD_MSG_USERAUTH_PK_OK, packet)
        assert (key_algorithm_name == loaded_key.name)
        # XXX: Check key_blob, too?
        # Send the actual request.
        # Compute signature.
        session_id = self.transport.key_exchange.session_id
        sig_data = pack_payload(
            PAYLOAD_USERAUTH_REQUEST_PK_SIGNATURE,
            (session_id, SSH_MSG_USERAUTH_REQUEST, username,
             service_name, 'publickey', 1, loaded_key.name,
             loaded_key.get_public_key_blob()))
        signature = loaded_key.sign(sig_data)

        self.transport.debug.write(
            ssh_debug.DEBUG_1, 'Publickey Auth: Sending userauth request.')
        packet = pack_payload(
            PAYLOAD_MSG_USERAUTH_REQUEST_PK,
            (SSH_MSG_USERAUTH_REQUEST, username, service_name, 'publickey', 1,
             loaded_key.name, loaded_key.get_public_key_blob(), signature))
        self.transport.send_packet(packet)
        message_type, packet = self.transport.receive_message(
            (SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE))
        if message_type == SSH_MSG_USERAUTH_SUCCESS:
            # Success.
            return
        elif message_type == SSH_MSG_USERAUTH_FAILURE:
            self.msg_userauth_failure(packet)
            raise Authentication_Error
        else:
            # Should never happen.
            raise ValueError(message_type)
Пример #4
0
 def authenticate(self, username, service_name):
     password = self.get_password(username)
     packet = pack_payload(PAYLOAD_MSG_USERAUTH_REQUEST_PASSWORD,
                           (SSH_MSG_USERAUTH_REQUEST, username,
                            service_name, 'password', 0, password))
     self.transport.send_packet(packet)
     # While loop in case we get a CHANGEREQ packet.
     while 1:
         try:
             message_type, packet = self.transport.receive_message(
                 (SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE,
                  SSH_MSG_USERAUTH_PASSWD_CHANGEREQ))
         except EOFError:
             # In case of an expired user, an EOFError is raised
             # Expired accounts are also considered as authentication errors
             raise Authentication_Error
         if message_type == SSH_MSG_USERAUTH_SUCCESS:
             # Success!
             return
         elif message_type == SSH_MSG_USERAUTH_FAILURE:
             self.msg_userauth_failure(packet)
             # XXX: Could ask for user's password again?
             # XXX: Should handle partial_success flag for CHANGEREQ response.
             raise Authentication_Error
         elif message_type == SSH_MSG_USERAUTH_PASSWD_CHANGEREQ:
             self.msg_userauth_passwd_changereq(packet, username,
                                                service_name)
         else:
             # Should never happen.
             raise ValueError(message_type)
Пример #5
0
 def send_unimplemented(self, sequence_number):
     self.debug.write(ssh_debug.DEBUG_3,
                      'send_unimplemented(sequence_number=%i)',
                      (sequence_number, ))
     self.send_packet(
         ssh_packet.pack_payload(ssh_packet.PAYLOAD_MSG_UNIMPLEMENTED,
                                 (SSH_MSG_UNIMPLEMENTED, sequence_number)))
Пример #6
0
    def authenticate(self, authentication_method, service_name):
        """authenticate(self, authentication_method, service) -> None
        Authenticate with the remote side.

        <authentication_method>:
        <service_name>: The name of the service that you want to use after
                        authenticating.  Typically 'ssh-connection'.
        """
        # Ask the remote side if it is OK to use this authentication service.
        self.debug.write(debug.DEBUG_3, 'authenticate: sending service request (%s)', (authentication_method.name,))
        service_request_packet = ssh_packet.pack_payload(ssh_packet.PAYLOAD_MSG_SERVICE_REQUEST,
                                                         (transport.SSH_MSG_SERVICE_REQUEST,
                                                          authentication_method.name))
        self.send_packet(service_request_packet)
        # Server will disconnect if it doesn't like our service request.
        self.debug.write(debug.DEBUG_3, 'authenticate: waiting for SERVICE_ACCEPT')
        message_type, packet = self.receive_message((transport.SSH_MSG_SERVICE_ACCEPT,))
        msg, accepted_service_name = ssh_packet.unpack_payload(ssh_packet.PAYLOAD_MSG_SERVICE_ACCEPT, packet)
        self.debug.write(debug.DEBUG_3, 'authenticate: got SERVICE_ACCEPT')
        if accepted_service_name != authentication_method.name:
            self.send_disconnect(transport.SSH_DISCONNECT_PROTOCOL_ERROR,
                                 'accepted service does not match requested service "%s"!="%s"' %
                                 (authentication_method.name, accepted_service_name))
        # This authetnication service is OK, try to authenticate.
        authentication_method.authenticate(service_name)
Пример #7
0
    def authenticate(self, authentication_method, service_name):
        """authenticate(self, authentication_method, service) -> None
        Authenticate with the remote side.

        <authentication_method>:
        <service_name>: The name of the service that you want to use after
                        authenticating.  Typically 'ssh-connection'.
        """
        # Ask the remote side if it is OK to use this authentication service.
        self.debug.write(debug.DEBUG_3, "authenticate: sending service request (%s)", (authentication_method.name,))
        service_request_packet = ssh_packet.pack_payload(
            ssh_packet.PAYLOAD_MSG_SERVICE_REQUEST, (transport.SSH_MSG_SERVICE_REQUEST, authentication_method.name)
        )
        self.send_packet(service_request_packet)
        # Server will disconnect if it doesn't like our service request.
        self.debug.write(debug.DEBUG_3, "authenticate: waiting for SERVICE_ACCEPT")
        message_type, packet = self.receive_message((transport.SSH_MSG_SERVICE_ACCEPT,))
        msg, accepted_service_name = ssh_packet.unpack_payload(ssh_packet.PAYLOAD_MSG_SERVICE_ACCEPT, packet)
        self.debug.write(debug.DEBUG_3, "authenticate: got SERVICE_ACCEPT")
        if accepted_service_name != authentication_method.name:
            self.send_disconnect(
                transport.SSH_DISCONNECT_PROTOCOL_ERROR,
                'accepted service does not match requested service "%s"!="%s"'
                % (authentication_method.name, accepted_service_name),
            )
        # This authetnication service is OK, try to authenticate.
        authentication_method.authenticate(service_name)
Пример #8
0
    def open(self):
        """open(self) -> None
        Opens the channel to the remote side.
        """
        assert self.closed
        self.connection_service.register_channel(self)
        self.transport.debug.write(debug.DEBUG_2, "sending channel open request channel ID %i", (self.channel_id,))

        # Send the open request.
        additional_data = self.get_additional_open_data()
        packet_payload = SSH_MSG_CHANNEL_OPEN_PAYLOAD + self.additional_packet_data_types
        packet_data = (
            SSH_MSG_CHANNEL_OPEN,
            self.name,
            self.channel_id,
            self.window_size,
            self.max_packet_size,
        ) + additional_data
        pkt = packet.pack_payload(packet_payload, packet_data)
        self.transport.send_packet(pkt)
        success, data = self.channel_open_cv.wait()
        if success:
            self.set_additional_open_data(data)
        else:
            reason_code, reason_text, language = data
            raise Channel_Open_Error(self.channel_id, reason_code, reason_text, language)
Пример #9
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)
     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],
                                  [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
Пример #10
0
    def send(self, data):
        """send(self, data) -> None
        Send the given data string.
        """
        data_start = 0
        while data_start < len(data):
            if self.remote_channel.closed:
                raise Channel_Closed_Error
            while self.remote_channel.window_data_left == 0:
                # Currently waiting for window update.
                self.window_data_added_cv.wait()
                # check again inside loop since if we're closed, the window
                # might never update
                if self.remote_channel.closed:
                    raise Channel_Closed_Error
            # Send what we can.
            max_size = min(self.remote_channel.window_data_left,
                           self.remote_channel.max_packet_size)
            data_to_send = data[data_start:data_start + max_size]
            data_start += max_size

            pkt = packet.pack_payload(
                SSH_MSG_CHANNEL_DATA_PAYLOAD,
                (SSH_MSG_CHANNEL_DATA, self.remote_channel.channel_id,
                 data_to_send))
            self.transport.debug.write(
                debug.DEBUG_3, 'channel %i window lowered by %i to %i',
                (self.remote_channel.channel_id, len(data_to_send),
                 self.remote_channel.window_data_left))
            self.remote_channel.window_data_left -= len(data_to_send)
            self.transport.send_packet(pkt)
Пример #11
0
 def get_encryption_key(self, letter, required_size):
     """get_encryption_key(self, letter, required_size) -> key
     Computes an encryption key with the given letter.
     <required_size> is the length of the key that you require (in bytes).
     """
     shared_secret = ssh_packet.pack_payload((ssh_packet.MPINT,), (self.shared_secret,))
     key = self.get_hash_object(
             shared_secret,
             self.exchange_hash,
             letter,
             self.session_id).digest()
     if len(key) > required_size:
         # Key is too big...return only what is needed.
         key = key[:required_size]
     elif len(key) < required_size:
         # Key is not big enough...compute additional hashes until big enough.
         # K1 = HASH(K || H || X || session_id)   (X is e.g. "A")
         # K2 = HASH(K || H || K1)
         # K3 = HASH(K || H || K1 || K2)
         # ...
         # key = K1 || K2 || K3 || ...
         self.transport.debug.write(ssh_debug.DEBUG_2, 'get_encryption_key: computed key is too small len(key)=%i required_size=%i', (len(key), required_size))
         key_data = [key]
         key_data_len = len(key)
         while key_data_len < required_size:
             additional_key_data = self.get_hash_object(shared_secret, self.exchange_hash, ''.join(key_data)).digest()
             key_data.append(additional_key_data)
             key_data_len += len(additional_key_data)
         key = ''.join(key_data)[:required_size]
     else:
         # Key is just the right length.
         pass
     return key
Пример #12
0
 def handle_request(self, request_type, want_reply, type_specific_packet_data):
     #W ('interactive_session_server: handle_request %r %r %r\n' % (request_type, want_reply, type_specific_packet_data))
     if self.request_handlers.has_key(request_type):
         self.request_handlers[request_type] (self, want_reply, type_specific_packet_data)
     elif want_reply:
         packet = ssh_packet.pack_payload(SSH_MSG_CHANNEL_FAILURE_PAYLOAD, (self.remote_channel.channel_id,))
         self.transport.send_packet(packet)
Пример #13
0
    def send_extended(self, data, data_type_code):
        """send_extended(self, data, data_type_code) -> None
        Send the given data string as extended data with the given data_type_code.
        """
        data_start = 0

        while data_start < len(data):
            if self.remote_channel.closed:
                raise Channel_Closed_Error
            while self.remote_channel.window_data_left == 0:
                # Currently waiting for window update.
                self.window_data_added_cv.wait()
                # check again inside loop since if we're closed, the window
                # might never update
                if self.remote_channel.closed:
                    raise Channel_Closed_Error

            # Send what we can.
            max_size = min(self.remote_channel.window_data_left,
                           self.remote_channel.max_packet_size)
            data_to_send = data[data_start:data_start + max_size]
            data_start += max_size

            pkt = packet.pack_payload(
                SSH_MSG_CHANNEL_EXTENDED_DATA_PAYLOAD,
                (SSH_MSG_CHANNEL_EXTENDED_DATA, self.remote_channel.channel_id,
                 data_type_code, data_to_send))
            self.remote_channel.window_data_left -= len(data_to_send)
            self.transport.send_packet(pkt)
Пример #14
0
    def send(self, data):
        """send(self, data) -> None
        Send the given data string.
        """
        data_start = 0
        while data_start < len(data):
            if self.remote_channel.closed:
                raise Channel_Closed_Error
            while self.remote_channel.window_data_left == 0:
                # Currently waiting for window update.
                self.window_data_added_cv.wait()
                # check again inside loop since if we're closed, the window
                # might never update
                if self.remote_channel.closed:
                    raise Channel_Closed_Error
            # Send what we can.
            max_size = min(self.remote_channel.window_data_left, self.remote_channel.max_packet_size)
            data_to_send = data[data_start : data_start + max_size]
            data_start += max_size

            pkt = packet.pack_payload(
                SSH_MSG_CHANNEL_DATA_PAYLOAD, (SSH_MSG_CHANNEL_DATA, self.remote_channel.channel_id, data_to_send)
            )
            self.transport.debug.write(
                debug.DEBUG_3,
                "channel %i window lowered by %i to %i",
                (self.remote_channel.channel_id, len(data_to_send), self.remote_channel.window_data_left),
            )
            self.remote_channel.window_data_left -= len(data_to_send)
            self.transport.send_packet(pkt)
Пример #15
0
    def open(self):
        """open(self) -> None
        Opens the channel to the remote side.
        """
        assert self.closed
        self.connection_service.register_channel(self)
        self.transport.debug.write(
            debug.DEBUG_2, 'sending channel open request channel ID %i',
            (self.channel_id, ))

        # Send the open request.
        additional_data = self.get_additional_open_data()
        packet_payload = SSH_MSG_CHANNEL_OPEN_PAYLOAD + self.additional_packet_data_types
        packet_data = (SSH_MSG_CHANNEL_OPEN, self.name, self.channel_id,
                       self.window_size,
                       self.max_packet_size) + additional_data
        pkt = packet.pack_payload(packet_payload, packet_data)
        self.transport.send_packet(pkt)
        success, data = self.channel_open_cv.wait()
        if success:
            self.set_additional_open_data(data)
        else:
            reason_code, reason_text, language = data
            raise Channel_Open_Error(self.channel_id, reason_code, reason_text,
                                     language)
Пример #16
0
    def send_extended(self, data, data_type_code):
        """send_extended(self, data, data_type_code) -> None
        Send the given data string as extended data with the given data_type_code.
        """
        data_start = 0

        while data_start < len(data):
            if self.remote_channel.closed:
                raise Channel_Closed_Error
            while self.remote_channel.window_data_left == 0:
                # Currently waiting for window update.
                self.window_data_added_cv.wait()
                # check again inside loop since if we're closed, the window
                # might never update
                if self.remote_channel.closed:
                    raise Channel_Closed_Error

            # Send what we can.
            max_size = min(self.remote_channel.window_data_left, self.remote_channel.max_packet_size)
            data_to_send = data[data_start : data_start + max_size]
            data_start += max_size

            pkt = packet.pack_payload(
                SSH_MSG_CHANNEL_EXTENDED_DATA_PAYLOAD,
                (SSH_MSG_CHANNEL_EXTENDED_DATA, self.remote_channel.channel_id, data_type_code, data_to_send),
            )
            self.remote_channel.window_data_left -= len(data_to_send)
            self.transport.send_packet(pkt)
Пример #17
0
 def authenticate(self, username, service_name):
     password = self.get_password(username)
     packet = pack_payload(PAYLOAD_MSG_USERAUTH_REQUEST_PASSWORD,
                           (SSH_MSG_USERAUTH_REQUEST,
                            username,
                            service_name,
                            'password',
                            0,
                            password
                            ))
     self.transport.send_packet(packet)
     # While loop in case we get a CHANGEREQ packet.
     while 1:
         try:
             message_type, packet = self.transport.receive_message((
                 SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE,
                 SSH_MSG_USERAUTH_PASSWD_CHANGEREQ))
         except EOFError:
             # In case of an expired user, an EOFError is raised
             # Expired accounts are also considered as authentication errors
             raise Authentication_Error
         if message_type == SSH_MSG_USERAUTH_SUCCESS:
             # Success!
             return
         elif message_type == SSH_MSG_USERAUTH_FAILURE:
             self.msg_userauth_failure(packet)
             # XXX: Could ask for user's password again?
             # XXX: Should handle partial_success flag for CHANGEREQ response.
             raise Authentication_Error
         elif message_type == SSH_MSG_USERAUTH_PASSWD_CHANGEREQ:
             self.msg_userauth_passwd_changereq(packet, username, service_name)
         else:
             # Should never happen.
             raise ValueError(message_type)
Пример #18
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
Пример #19
0
 def handle_request(self, request_type, want_reply, type_specific_packet_data):
     # Default is always to fail.  Specific channel types override this method.
     if want_reply:
         pkt = packet.pack_payload(
             SSH_MSG_CHANNEL_FAILURE_PAYLOAD, (SSH_MSG_CHANNEL_FAILURE, self.remote_channel.channel_id)
         )
         self.transport.send_packet(pkt)
Пример #20
0
 def get_public_key_blob(self):
     if self.public_key != (0, 0, 0, 0):
         p, q, g, y = self.public_key
     else:
         p, q, g, y, x = self.private_key
     return packet.pack_payload(DSS_PUBLIC_KEY_PAYLOAD,
                     ('ssh-dss',
                      p, q, g, y))
Пример #21
0
 def get_public_key_blob(self):
     if self.public_key != (0, 0, 0, 0):
         p, q, g, y = self.public_key
     else:
         p, q, g, y, x = self.private_key
     return packet.pack_payload(DSS_PUBLIC_KEY_PAYLOAD,
                                ('ssh-dss',
                                 p, q, g, y))
Пример #22
0
 def send_unimplemented(self, sequence_number):
     self.debug.write(ssh_debug.DEBUG_3, 'send_unimplemented(sequence_number=%i)', (sequence_number,))
     self.send_packet(
         ssh_packet.pack_payload(ssh_packet.PAYLOAD_MSG_UNIMPLEMENTED,
                                     (SSH_MSG_UNIMPLEMENTED,
                                     sequence_number)
                                 )
                     )
Пример #23
0
 def send_window_adjustment(self, bytes_to_add):
     self.transport.debug.write(debug.DEBUG_2, "sending window adjustment to add %i bytes", (bytes_to_add,))
     pkt = packet.pack_payload(
         SSH_MSG_CHANNEL_WINDOW_ADJUST_PAYLOAD,
         (SSH_MSG_CHANNEL_WINDOW_ADJUST, self.remote_channel.channel_id, bytes_to_add),
     )
     self.transport.send_packet(pkt)
     self.window_data_left += bytes_to_add
Пример #24
0
 def handle_request(self, request_type, want_reply,
                    type_specific_packet_data):
     # Default is always to fail.  Specific channel types override this method.
     if want_reply:
         pkt = packet.pack_payload(SSH_MSG_CHANNEL_FAILURE_PAYLOAD, (
             SSH_MSG_CHANNEL_FAILURE,
             self.remote_channel.channel_id,
         ))
         self.transport.send_packet(pkt)
Пример #25
0
 def authenticate(self, username, service_name):
     local_username = os.getlogin()
     for key_storage in self.transport.supported_key_storages:
         self.transport.debug.write(
             ssh_debug.DEBUG_1,
             'Publickey Auth: Trying to load keytype "%s" for user "%s".',
             (key_storage.__class__.__name__, local_username))
         loaded_keys = key_storage.load_keys(username=local_username)
         if loaded_keys:
             for loaded_key in loaded_keys:
                 # Test this key type.
                 self.transport.debug.write(
                     ssh_debug.DEBUG_1,
                     'Publickey Auth: Sending PK test for keytype "%s".',
                     (loaded_key.name, ))
                 packet = pack_payload(
                     PAYLOAD_MSG_USERAUTH_REQUEST_PK_TEST,
                     (SSH_MSG_USERAUTH_REQUEST, username, service_name,
                      'publickey', 0, loaded_key.name,
                      loaded_key.get_public_key_blob()))
                 self.transport.send_packet(packet)
                 message_type, packet = self.transport.receive_message((
                     SSH_MSG_USERAUTH_PK_OK,
                     SSH_MSG_USERAUTH_FAILURE,
                 ))
                 if message_type == SSH_MSG_USERAUTH_PK_OK:
                     # This public key is ok to try.
                     try:
                         self._try_auth(packet, loaded_key, username,
                                        service_name)
                     except Authentication_Error:
                         # Nope, didn't work.  Loop and try next.
                         pass
                     else:
                         # Done!
                         return
                 elif message_type == SSH_MSG_USERAUTH_FAILURE:
                     # Key type not allowed.
                     self.msg_userauth_failure(packet)
                     # Loop through and try next key.
                 else:
                     # Should never happen.
                     raise ValueError(message_type)
             else:
                 self.transport.debug.write(
                     ssh_debug.DEBUG_1,
                     'Publickey Auth: No more key storage types left.')
         else:
             self.transport.debug.write(
                 ssh_debug.DEBUG_1,
                 'Publickey Auth: No keys found of this key storage type.')
     else:
         self.transport.debug.write(
             ssh_debug.DEBUG_1,
             'Publickey Auth: No more storage key types left to try.')
         raise Authentication_Error
Пример #26
0
 def sign(self, message):
     n, e, d, p, q = self.private_key
     rsa_obj = RSA.construct((n, e, d, p, q))
     modulus_n_length_in_octets = rsa_obj.size() / 8
     encoded_message = self.emsa_pkcs1_v1_5_encode(
         message, modulus_n_length_in_octets)
     signature = rsa_obj.sign(encoded_message,
                              '')[0]  # Returns tuple of 1 element.
     signature = number.long_to_bytes(signature)
     return packet.pack_payload(RSA_SIG_PAYLOAD, ('ssh-rsa', signature))
Пример #27
0
 def sign(self, message):
     n, e, d, p, q = self.private_key
     rsa_obj = RSA.construct((n, e, d, p, q))
     modulus_n_length_in_octets = rsa_obj.size() / 8
     encoded_message = self.emsa_pkcs1_v1_5_encode(message, modulus_n_length_in_octets)
     signature = rsa_obj.sign(encoded_message, '')[0]    # Returns tuple of 1 element.
     signature = number.long_to_bytes(signature)
     return packet.pack_payload(RSA_SIG_PAYLOAD,
                                ('ssh-rsa',
                                 signature))
Пример #28
0
 def send_window_adjustment(self, bytes_to_add):
     self.transport.debug.write(
         debug.DEBUG_2, 'sending window adjustment to add %i bytes',
         (bytes_to_add, ))
     pkt = packet.pack_payload(
         SSH_MSG_CHANNEL_WINDOW_ADJUST_PAYLOAD,
         (SSH_MSG_CHANNEL_WINDOW_ADJUST, self.remote_channel.channel_id,
          bytes_to_add))
     self.transport.send_packet(pkt)
     self.window_data_left += bytes_to_add
Пример #29
0
    def _try_auth(self, packet, loaded_key, username, service_name):
        self.transport.debug.write(ssh_debug.DEBUG_1, 'Publickey Auth: Got OK for this key type.')
        msg, key_algorithm_name, key_blob = unpack_payload(PAYLOAD_MSG_USERAUTH_PK_OK, packet)
        assert (key_algorithm_name == loaded_key.name)
        # XXX: Check key_blob, too?
        # Send the actual request.
        # Compute signature.
        session_id = self.transport.key_exchange.session_id
        sig_data = pack_payload(PAYLOAD_USERAUTH_REQUEST_PK_SIGNATURE,
                                (session_id,
                                 SSH_MSG_USERAUTH_REQUEST,
                                 username,
                                 service_name,
                                 'publickey',
                                 1,
                                 loaded_key.name,
                                 loaded_key.get_public_key_blob()
                                 ))
        signature = loaded_key.sign(sig_data)

        self.transport.debug.write(ssh_debug.DEBUG_1, 'Publickey Auth: Sending userauth request.')
        packet = pack_payload(PAYLOAD_MSG_USERAUTH_REQUEST_PK,
                              (SSH_MSG_USERAUTH_REQUEST,
                               username,
                               service_name,
                               'publickey',
                               1,
                               loaded_key.name,
                               loaded_key.get_public_key_blob(),
                               signature))
        self.transport.send_packet(packet)
        message_type, packet = self.transport.receive_message((SSH_MSG_USERAUTH_SUCCESS,
                                                               SSH_MSG_USERAUTH_FAILURE))
        if message_type == SSH_MSG_USERAUTH_SUCCESS:
            # Success.
            return
        elif message_type == SSH_MSG_USERAUTH_FAILURE:
            self.msg_userauth_failure(packet)
            raise Authentication_Error
        else:
            # Should never happen.
            raise ValueError(message_type)
Пример #30
0
 def sign(self, message):
     p, q, g, y, x = self.private_key
     dsa_obj = DSA.construct( (y, g, p, q, x) )
     message_hash = hashlib.sha1(message).digest()
     # Get a random number that is greater than 2 and less than q.
     random_number = random.get_random_number_from_range(2, q)
     random_data = number.long_to_bytes(random_number)
     r, s = dsa_obj.sign(message_hash, random_data)
     signature = number.long_to_bytes(r, 20) + number.long_to_bytes(s, 20)
     return packet.pack_payload(DSS_SIG_PAYLOAD,
                         ('ssh-dss',
                          signature))
Пример #31
0
 def sign(self, message):
     p, q, g, y, x = self.private_key
     dsa_obj = DSA.construct((y, g, p, q, x))
     message_hash = hashlib.sha1(message).digest()
     # Get a random number that is greater than 2 and less than q.
     random_number = random.get_random_number_from_range(2, q)
     random_data = number.long_to_bytes(random_number)
     r, s = dsa_obj.sign(message_hash, random_data)
     signature = number.long_to_bytes(r, 20) + number.long_to_bytes(s, 20)
     return packet.pack_payload(DSS_SIG_PAYLOAD,
                                ('ssh-dss',
                                 signature))
Пример #32
0
 def get_initial_client_kex_packet(self):
     self.transport.debug.write(ssh_debug.DEBUG_3, 'get_initial_kex_packet()')
     # Send initial key.
     # This is x.
     self.client_random_value = ssh_random.get_random_number(512)
     # p is large safe prime (DH_PRIME)
     # g is a generator for a subgroup of GF(p) (DH_GENERATOR)
     # compute e=g**x mod p
     self.client_exchange_value = pow(DH_GENERATOR, self.client_random_value, DH_PRIME)
     return ssh_packet.pack_payload(KEXDH_INIT_PAYLOAD,
                                         (SSH_MSG_KEXDH_INIT,
                                          self.client_exchange_value)
                                        )
Пример #33
0
    def send_channel_request(self,
                             request_type,
                             payload,
                             data,
                             want_reply=1,
                             default_reply_handler=True):
        """send_channel_request(self, request_type, payload, data, want_reply=1, default_reply_handler=True) -> None
        This is a generic mechanism for sending a channel request packet.

        <request_type>: Request type to send.
        <payload>: The ssh_packet format definition.
        <data>: The data to go with the payload.
        <want_reply>: The want_reply flag.
        <default_reply_handler>: If true and want_reply is True, then the
                default reply handler will be used.  The default reply
                handler is pretty simple.  Will just return if
                CHANNEL_REQUEST_SUCCESS is received.  Will raise
                Channel_Request_Failure if FAILURE is received.
        """
        # XXX: There is a problem with the spec.  It does not indicate how to
        #      match requests with responses.  IIRC, they talked about it on
        #      the mailing list and updated the spec.  Need to investigate if
        #      they have clarified the spec on how to handle this.
        # XXX: Or maybe concurrent channel requests on the same channel are
        #      not allowed?
        if self.remote_channel.closed:
            raise Channel_Closed_Error
        pkt = packet.pack_payload(
            SSH_MSG_CHANNEL_REQUEST_PAYLOAD,
            (SSH_MSG_CHANNEL_REQUEST, self.remote_channel.channel_id,
             request_type, int(want_reply)))
        pkt_data = packet.pack_payload(payload, data)
        self.transport.send_packet(pkt + pkt_data)
        if want_reply and default_reply_handler:
            # Wait for response.
            assert len(self.channel_request_cv
                       ) == 0, 'Concurrent channel requests not supported!'
            if not self.channel_request_cv.wait():
                raise Channel_Request_Failure
Пример #34
0
 def send_disconnect(self, reason_code, description):
     """send_disconnect(self, reason_code, description) -> None
     """
     self.debug.write(ssh_debug.DEBUG_3,
                      'send_disconnect(reason_code=%r, description=%r)',
                      (reason_code, description))
     # Language tag currently set to the empty string.
     language_tag = ''
     self.send_packet(
         ssh_packet.pack_payload(
             ssh_packet.PAYLOAD_MSG_DISCONNECT,
             (SSH_MSG_DISCONNECT, reason_code, description, language_tag)))
     self.disconnect()
     raise SSH_Protocol_Error(reason_code, description)
Пример #35
0
 def authenticate(self, session_id, serv, user, alg, blob, sig):
     # build the signable data
     to_sign = pack_payload(PAYLOAD_USERAUTH_REQUEST_PK_SIGNATURE,
                            (session_id, SSH_MSG_USERAUTH_REQUEST, user,
                             serv, 'publickey', 1, alg, blob))
     try:
         keys = self.keys[user][serv]
         for key in keys:
             if key.name == alg and key.get_public_key_blob(
             ) == blob and key.verify(to_sign, sig):
                 return True
         return False
     except KeyError:
         return False
Пример #36
0
 def get_initial_client_kex_packet(self):
     self.transport.debug.write(ssh_debug.DEBUG_3,
                                'get_initial_kex_packet()')
     # Send initial key.
     # This is x.
     self.client_random_value = ssh_random.get_random_number(512)
     # p is large safe prime (DH_PRIME)
     # g is a generator for a subgroup of GF(p) (DH_GENERATOR)
     # compute e=g**x mod p
     self.client_exchange_value = pow(DH_GENERATOR,
                                      self.client_random_value, DH_PRIME)
     return ssh_packet.pack_payload(
         KEXDH_INIT_PAYLOAD,
         (SSH_MSG_KEXDH_INIT, self.client_exchange_value))
Пример #37
0
    def msg_kexdh_reply(self, packet):
        # string    server public host key and certificates (K_S)
        # mpint     f
        # string    signature of H
        msg, public_host_key, server_exchange_value, signature_of_h = ssh_packet.unpack_payload(
            KEXDH_REPLY_PAYLOAD, packet)

        # Create a SSH_Public_Private_Key instance from the packed string.
        self.server_public_host_key = parse_public_key(public_host_key)

        # Verify that this is a known host key.
        self.transport.verify_public_host_key(self.server_public_host_key)

        # Make sure f is a valid number
        if server_exchange_value <= 1 or server_exchange_value >= DH_PRIME - 1:
            self.transport.send_disconnect(
                constants.SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
                'Key exchange did not succeed: Server exchange value not valid.'
            )

        # K = f**x mod p
        self.shared_secret = pow(server_exchange_value,
                                 self.client_random_value, DH_PRIME)
        # Verify hash.
        # string    V_C, the client's version string (CR and NL excluded)
        # string    V_S, the server's version string (CR and NL excluded)
        # string    I_C, the payload of the client's SSH_MSG_KEXINIT
        # string    I_S, the payload of the server's SSH_MSG_KEXINIT
        # string    K_S, the host key
        # mpint     e, exchange value sent by the client
        # mpint     f, exchange value sent by the server
        # mpint     K, the shared secret
        H = ssh_packet.pack_payload(
            KEXDH_HASH_PAYLOAD,
            (self.c2s_version_string, self.s2c_version_string,
             self.c2s_kexinit_packet, self.s2c_kexinit_packet, public_host_key,
             self.client_exchange_value, server_exchange_value,
             self.shared_secret))
        # Double check that the signature from the server matches our signature.
        hash = hashlib.sha1(H)
        self.exchange_hash = hash.digest()
        if self.session_id is None:
            # The session id is the first exchange hash.
            self.session_id = self.exchange_hash

        if not self.server_public_host_key.verify(self.exchange_hash,
                                                  signature_of_h):
            self.transport.send_disconnect(
                constants.SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
                'Key exchange did not succeed:  Signature did not match.')
Пример #38
0
 def msg_kexdh_init (self, packet):
     # mpint     e
     msg, self.client_exchange_value = ssh_packet.unpack_payload (KEXDH_INIT_PAYLOAD, packet)
     # XXX make sure e is a valid number
     # This is y.
     self.server_random_value = ssh_random.get_random_number(512)
     # p is large safe prime (DH_PRIME)
     # g is a generator for a subgroup of GF(p) (DH_GENERATOR)
     # compute f=g**y mod p
     self.server_exchange_value = pow(DH_GENERATOR, self.server_random_value, DH_PRIME)
     self.shared_secret = pow (self.client_exchange_value, self.server_random_value, DH_PRIME)
     K_S = self.transport.server_key.get_public_key_blob()
     payload_inputs = (
         self.c2s_version_string,
         self.s2c_version_string,
         self.c2s_kexinit_packet,
         self.s2c_kexinit_packet,
         K_S,
         self.client_exchange_value,
         self.server_exchange_value,
         self.shared_secret
         )
     H = ssh_packet.pack_payload (KEXDH_HASH_PAYLOAD, payload_inputs)
     self.exchange_hash = hashlib.sha1(H).digest()
     if self.session_id is None:
         # The session id is the first exchange hash.
         self.session_id = self.exchange_hash
     H_sig = self.transport.server_key.sign (self.exchange_hash)
     packet = ssh_packet.pack_payload (
         KEXDH_REPLY_PAYLOAD, (
             SSH_MSG_KEXDH_REPLY,
             K_S,
             self.server_exchange_value,
             H_sig
             )
         )
     self.transport.send_packet (packet)
Пример #39
0
    def msg_kexdh_reply(self, packet):
        # string    server public host key and certificates (K_S)
        # mpint     f
        # string    signature of H
        msg, public_host_key, server_exchange_value, signature_of_h = ssh_packet.unpack_payload(KEXDH_REPLY_PAYLOAD, packet)

        W ('kexdh: KEXDH_REPLY public host blob = %r\n' % (public_host_key,))
        # Create a SSH_Public_Private_Key instance from the packed string.
        self.server_public_host_key = parse_public_key(public_host_key)

        # Verify that this is a known host key.
        self.transport.verify_public_host_key(self.server_public_host_key)

        # Make sure f is a valid number
        if server_exchange_value <= 1 or server_exchange_value >= DH_PRIME-1:
            self.transport.send_disconnect(constants.SSH_DISCONNECT_KEY_EXCHANGE_FAILED, 'Key exchange did not succeed: Server exchange value not valid.')

        # K = f**x mod p
        self.shared_secret = pow(server_exchange_value, self.client_random_value, DH_PRIME)
        # Verify hash.
        # string    V_C, the client's version string (CR and NL excluded)
        # string    V_S, the server's version string (CR and NL excluded)
        # string    I_C, the payload of the client's SSH_MSG_KEXINIT
        # string    I_S, the payload of the server's SSH_MSG_KEXINIT
        # string    K_S, the host key
        # mpint     e, exchange value sent by the client
        # mpint     f, exchange value sent by the server
        # mpint     K, the shared secret
        H = ssh_packet.pack_payload(KEXDH_HASH_PAYLOAD,
                                 (self.c2s_version_string,
                                 self.s2c_version_string,
                                 self.c2s_kexinit_packet,
                                 self.s2c_kexinit_packet,
                                 public_host_key,
                                 self.client_exchange_value,
                                 server_exchange_value,
                                 self.shared_secret))
        # Double check that the signature from the server matches our signature.
        hash = hashlib.sha1(H)
        self.exchange_hash = hash.digest()
        if self.session_id is None:
            # The session id is the first exchange hash.
            self.session_id = self.exchange_hash

        if not self.server_public_host_key.verify(self.exchange_hash, signature_of_h):
            self.transport.send_disconnect(constants.SSH_DISCONNECT_KEY_EXCHANGE_FAILED, 'Key exchange did not succeed:  Signature did not match.')

        # Finished...
        self.transport.send_newkeys()
Пример #40
0
 def authenticate(self, username, service_name):
     local_username = os.getlogin()
     for key_storage in self.transport.supported_key_storages:
         self.transport.debug.write(
             ssh_debug.DEBUG_1, 'Publickey Auth: Trying to load keytype "%s" for user "%s".',
             (key_storage.__class__.__name__, local_username))
         loaded_keys = key_storage.load_keys(username=local_username)
         if loaded_keys:
             for loaded_key in loaded_keys:
                 # Test this key type.
                 self.transport.debug.write(
                     ssh_debug.DEBUG_1, 'Publickey Auth: Sending PK test for keytype "%s".', (loaded_key.name,))
                 packet = pack_payload(PAYLOAD_MSG_USERAUTH_REQUEST_PK_TEST,
                                       (SSH_MSG_USERAUTH_REQUEST,
                                        username,
                                        service_name,
                                        'publickey',
                                        0,
                                        loaded_key.name,
                                        loaded_key.get_public_key_blob()
                                        ))
                 self.transport.send_packet(packet)
                 message_type, packet = self.transport.receive_message((SSH_MSG_USERAUTH_PK_OK,
                                                                        SSH_MSG_USERAUTH_FAILURE,
                                                                        ))
                 if message_type == SSH_MSG_USERAUTH_PK_OK:
                     # This public key is ok to try.
                     try:
                         self._try_auth(packet, loaded_key, username, service_name)
                     except Authentication_Error:
                         # Nope, didn't work.  Loop and try next.
                         pass
                     else:
                         # Done!
                         return
                 elif message_type == SSH_MSG_USERAUTH_FAILURE:
                     # Key type not allowed.
                     self.msg_userauth_failure(packet)
                     # Loop through and try next key.
                 else:
                     # Should never happen.
                     raise ValueError(message_type)
             else:
                 self.transport.debug.write(ssh_debug.DEBUG_1, 'Publickey Auth: No more key storage types left.')
         else:
             self.transport.debug.write(ssh_debug.DEBUG_1, 'Publickey Auth: No keys found of this key storage type.')
     else:
         self.transport.debug.write(ssh_debug.DEBUG_1, 'Publickey Auth: No more storage key types left to try.')
         raise Authentication_Error
Пример #41
0
 def authenticate (self, session_id, serv, user, alg, blob, sig):
     # build the signable data
     to_sign = pack_payload (
         PAYLOAD_USERAUTH_REQUEST_PK_SIGNATURE, (
             session_id, SSH_MSG_USERAUTH_REQUEST, user, serv, 'publickey', 1, alg, blob
         )
     )
     try:
         keys = self.keys[user][serv]
         for key in keys:
             if key.name == alg and key.get_public_key_blob() == blob and key.verify (to_sign, sig):
                 return True
         return False
     except KeyError:
         return False
Пример #42
0
 def send_disconnect(self, reason_code, description):
     """send_disconnect(self, reason_code, description) -> None
     """
     self.debug.write(ssh_debug.DEBUG_3, 'send_disconnect(reason_code=%r, description=%r)', (reason_code, description))
     # Language tag currently set to the empty string.
     language_tag = ''
     self.send_packet(
         ssh_packet.pack_payload (
             ssh_packet.PAYLOAD_MSG_DISCONNECT,
               (SSH_MSG_DISCONNECT,
                 reason_code,
                 description,
                 language_tag)
             )
         )
     self.disconnect()
     raise SSH_Protocol_Error, (reason_code, description)
Пример #43
0
 def msg_userauth_passwd_changereq(self, packet, username, service_name):
     # User's password has expired.  Allow the user to enter a new password.
     msg, prompt, language = unpack_payload(
         PAYLOAD_MSG_USERAUTH_PASSWD_CHANGEREQ, packet)
     print safe_string(prompt)
     old_password = self.get_password('%s\'s old password> ' % username)
     while 1:
         new_password = self.get_password('%s\'s new password> ' % username)
         new_password2 = self.get_password('Retype new password> ')
         if new_password != new_password2:
             print 'Passwords did not match!  Try again.'
         else:
             break
     packet = pack_payload(
         PAYLOAD_MSG_USERAUTH_REQUEST_CHANGE_PASSWD,
         (SSH_MSG_USERAUTH_REQUEST, username, service_name, 'password', 1,
          old_password, new_password))
     self.transport.send_packet(packet)
Пример #44
0
    def close(self):
        """close(self) -> None
        Tell remote side to close its channel.
        Our side is not considered "closed" until after we receive
        SSH_MSG_CHANNEL_CLOSE from the remote side.
        """
        if not self.remote_channel.closed:
            self.remote_channel.closed = 1
            pkt = packet.pack_payload(
                SSH_MSG_CHANNEL_CLOSE_PAYLOAD, (SSH_MSG_CHANNEL_CLOSE, self.remote_channel.channel_id)
            )
            self.transport.send_packet(pkt)

            # We need to cause any threads that were trying to write on
            # this channel to stop trying to write. If they were asleep
            # waiting for one of the three condition variables, we need to
            # wake them up. They will notice that self.remote_channel.closed
            # is now true, and will do the right thing.
            self.window_data_added_cv.wake_all()
            self.channel_request_cv.wake_all(False)
            self.channel_open_cv.wake_all((False, (SSH_OPEN_CONNECT_FAILED, "Channel has been closed", None)))
Пример #45
0
 def msg_userauth_passwd_changereq(self, packet, username, service_name):
     # User's password has expired.  Allow the user to enter a new password.
     msg, prompt, language = unpack_payload(PAYLOAD_MSG_USERAUTH_PASSWD_CHANGEREQ, packet)
     print safe_string(prompt)
     old_password = self.get_password('%s\'s old password> ' % username)
     while 1:
         new_password = self.get_password('%s\'s new password> ' % username)
         new_password2 = self.get_password('Retype new password> ')
         if new_password != new_password2:
             print 'Passwords did not match!  Try again.'
         else:
             break
     packet = pack_payload(PAYLOAD_MSG_USERAUTH_REQUEST_CHANGE_PASSWD,
                           (SSH_MSG_USERAUTH_REQUEST,
                            username,
                            service_name,
                            'password',
                            1,
                            old_password,
                            new_password))
     self.transport.send_packet(packet)
Пример #46
0
    def close(self):
        """close(self) -> None
        Tell remote side to close its channel.
        Our side is not considered "closed" until after we receive
        SSH_MSG_CHANNEL_CLOSE from the remote side.
        """
        if not self.remote_channel.closed:
            self.remote_channel.closed = 1
            pkt = packet.pack_payload(
                SSH_MSG_CHANNEL_CLOSE_PAYLOAD,
                (SSH_MSG_CHANNEL_CLOSE, self.remote_channel.channel_id))
            self.transport.send_packet(pkt)

            # We need to cause any threads that were trying to write on
            # this channel to stop trying to write. If they were asleep
            # waiting for one of the three condition variables, we need to
            # wake them up. They will notice that self.remote_channel.closed
            # is now true, and will do the right thing.
            self.window_data_added_cv.wake_all()
            self.channel_request_cv.wake_all(False)
            self.channel_open_cv.wake_all(
                (False, (SSH_OPEN_CONNECT_FAILED, 'Channel has been closed',
                         None)))
Пример #47
0
 def get_encryption_key(self, letter, required_size):
     """get_encryption_key(self, letter, required_size) -> key
     Computes an encryption key with the given letter.
     <required_size> is the length of the key that you require (in bytes).
     """
     shared_secret = ssh_packet.pack_payload((ssh_packet.MPINT,), (self.shared_secret,))
     key = self.get_hash_object(
         shared_secret,
         self.exchange_hash,
         letter,
         self.session_id).digest()
     if len(key) > required_size:
         # Key is too big...return only what is needed.
         key = key[:required_size]
     elif len(key) < required_size:
         # Key is not big enough...compute additional hashes until big enough.
         # K1 = HASH(K || H || X || session_id)   (X is e.g. "A")
         # K2 = HASH(K || H || K1)
         # K3 = HASH(K || H || K1 || K2)
         # ...
         # key = K1 || K2 || K3 || ...
         self.transport.debug.write(
             ssh_debug.DEBUG_2, 'get_encryption_key: computed key is too small len(key)=%i required_size=%i',
             (len(key), required_size))
         key_data = [key]
         key_data_len = len(key)
         while key_data_len < required_size:
             additional_key_data = self.get_hash_object(
                 shared_secret, self.exchange_hash, ''.join(key_data)).digest()
             key_data.append(additional_key_data)
             key_data_len += len(additional_key_data)
         key = ''.join(key_data)[:required_size]
     else:
         # Key is just the right length.
         pass
     return key
Пример #48
0
 def get_private_key_blob(self):
     p, q, g, y, x = self.private_key
     return packet.pack_payload(DSS_PRIVATE_KEY_PAYLOAD,
                                ('ssh-dss',
                                 p, q, g, y, x))
Пример #49
0
 def get_public_key_blob(self):
     e, n = self.public_key
     return packet.pack_payload(RSA_PUBLIC_KEY_PAYLOAD, ('ssh-rsa', e, n))
Пример #50
0
 def get_private_key_blob(self):
     n, e, d, p, q = self.public_key
     return packet.pack_payload(RSA_PRIVATE_KEY_PAYLOAD,
                                ('ssh-rsa', n, e, d, p, q))
Пример #51
0
 def send(self, format, values):
     self.transport.send_packet(pack_payload(format, values))
Пример #52
0
 def send_newkeys(self):
     self.debug.write(ssh_debug.DEBUG_3, 'send_newkeys()')
     packet = ssh_packet.pack_payload(ssh_packet.PAYLOAD_MSG_NEWKEYS,
                                      (SSH_MSG_NEWKEYS, ))
     self.send_packet(packet)
Пример #53
0
    def _connect(self, transport, authenticator):
        # transport is already connected
        # Send identification string.
        self.transport = transport
        if self.s2c.comments:
            comments = ' ' + self.s2c.comments
        else:
            comments = ''
        self.s2c.version_string = 'SSH-' + self.s2c.protocol_version + '-' + self.s2c.software_version + comments
        transport.write(self.s2c.version_string + '\r\n')
        # Receive client's identification string.
        while 1:
            line = transport.read_line()
            if line.startswith('SSH-'):
                # Got the identification string.
                self.c2s.version_string = line
                # See if there are any optional comments.
                i = line.find(' ')
                if i != -1:
                    self.c2s.comments = line[i + 1:]
                    line = line[:i]
                # Break up the identification string into its parts.
                parts = line.split('-')
                if len(parts) != 3:
                    self.send_disconnect(
                        ssh_transport.SSH_DISCONNECT_PROTOCOL_ERROR,
                        'server identification invalid: %r' % line)
                self.c2s.protocol_version = parts[1]
                self.c2s.software_version = parts[2]
                if self.c2s.protocol_version not in ('1.99', '2.0'):
                    self.send_disconnect(
                        ssh_transport.
                        SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED,
                        'protocol version not supported: %r' %
                        self.c2s.protocol_version)
                break

        self.send_kexinit()
        self.s2c.set_preferred('key_exchange')
        self.s2c.set_preferred('server_key')

        if self.self2remote.proactive_kex:
            # Go ahead and send our kex packet with our preferred algorithm.
            # This will assume the client side supports the algorithm.
            self.s2c.set_preferred('key_exchange')
            self.s2c.set_preferred('server_key')
            self.set_key_exchange()
            self.debug.write(
                debug.DEBUG_3,
                'key exchange: sending proactive server kex packet')
            packet = self.c2s.key_exchange.get_initial_server_kex_packet()
            self.send_packet(packet)

        self.start_receive_thread()
        # Receive server kexinit
        self._process_kexinit()
        self.debug.write(debug.DEBUG_3, 'key exchange: got kexinit')
        self.debug.write(
            debug.DEBUG_3,
            'key exchange: self.server_key=%r' % (self.server_key, ))
        if not self.self2remote.proactive_kex:
            self.debug.write(
                debug.DEBUG_3,
                'key exchange: sending initial server kex packet')
            packet = self.key_exchange.get_initial_server_kex_packet()
            if packet:
                # It is possible for a key exchange algorithm to not have
                # an initial packet to send on the client side.
                self.send_packet(packet)

        message_type, packet = self.receive_message(
            (SSH_MSG_SERVICE_REQUEST, ))
        msg, service_name = ssh_packet.unpack_payload(
            ssh_packet.PAYLOAD_MSG_SERVICE_REQUEST, packet)
        self.debug.write(debug.DEBUG_1,
                         'service_request: %r' % (service_name, ))
        # XXX consider other possibilities
        if service_name != 'ssh-userauth':
            self.send_disconnect(SSH_DISCONNECT_SERVICE_NOT_AVAILABLE,
                                 "not today, zurg")
        else:
            self.send_packet(
                ssh_packet.pack_payload(
                    ssh_packet.PAYLOAD_MSG_SERVICE_ACCEPT, (
                        ssh_transport.SSH_MSG_SERVICE_ACCEPT,
                        'ssh-userauth',
                    )))
            authenticator.authenticate(service_name)
Пример #54
0
 def get_private_key_blob(self):
     p, q, g, y, x = self.private_key
     return packet.pack_payload(DSS_PRIVATE_KEY_PAYLOAD,
                     ('ssh-dss',
                      p, q, g, y, x))
Пример #55
0
 def get_private_key_blob(self):
     n, e, d, p, q = self.public_key
     return packet.pack_payload(RSA_PRIVATE_KEY_PAYLOAD,
                                ('ssh-rsa',
                                 n, e, d, p, q))
Пример #56
0
 def send (self, format, values):
     self.send_packet (ssh_packet.pack_payload (format, values))
Пример #57
0
 def send (self, format, values):
     self.transport.send_packet (pack_payload (format, values))
Пример #58
0
 def send(self, format, values):
     self.send_packet(ssh_packet.pack_payload(format, values))
Пример #59
0
 def get_public_key_blob(self):
     e, n = self.public_key
     return packet.pack_payload(RSA_PUBLIC_KEY_PAYLOAD,
                                ('ssh-rsa',
                                 e, n))
Пример #60
0
 def send_newkeys(self):
     self.debug.write(ssh_debug.DEBUG_3, 'send_newkeys()')
     packet = ssh_packet.pack_payload(ssh_packet.PAYLOAD_MSG_NEWKEYS, (SSH_MSG_NEWKEYS,))
     self.send_packet(packet)