Beispiel #1
0
 def authenticate (self, service_name):
     session_id = self.transport.key_exchange.session_id
     tries = self.max_tries
     while tries:
         # this is relatively stateless, because the RFC says the client can send requests without bothering
         #  to see if the server even wants them.
         # XXX allow each method to be tried, then removed from the list of
         # possibles? [think about combinations of service/user/etc... though]
         message_type, packet = self.transport.receive_message ((SSH_MSG_USERAUTH_REQUEST,))
         msg, username, service, method = unpack_payload (PAYLOAD_MSG_USERAUTH_REQUEST, packet)
         if method == 'none':
             self.send_failure()
         elif method == 'publickey':
             mprobe = self.by_name.get ('publickey')
             if not mprobe:
                 self.send_failure()
             else:
                 (_, _, _, _, btest, alg, blob) = unpack_payload (PAYLOAD_MSG_USERAUTH_REQUEST_PK_TEST, packet)
                 if not btest:
                     # XXX: ask method if it's ok with serv+user+alg+blob
                     self.send (PAYLOAD_MSG_USERAUTH_PK_OK, (SSH_MSG_USERAUTH_PK_OK, alg, blob))
                 else:
                     (_, _, _, _, _, _, key, sig) = unpack_payload (PAYLOAD_MSG_USERAUTH_REQUEST_PK, packet)
                     self.transport.debug.write (
                         ssh_debug.DEBUG_1, 'Trying Public Key Authentication: %r' % ((service, username, alg),))
                     if mprobe.authenticate (session_id, service, username, alg, key, sig):
                         self.send (PAYLOAD_MSG_USERAUTH_SUCCESS, (SSH_MSG_USERAUTH_SUCCESS,))
                         return True
                     else:
                         tries -= 1
                         coro.sleep_relative (self.sleep_time)
                         self.send_failure()
         elif method == 'password':
             mprobe = self.by_name.get ('password')
             if not mprobe:
                 self.send_failure()
             else:
                 (_, _, _, _, btest, password) = unpack_payload (PAYLOAD_MSG_USERAUTH_REQUEST_PASSWORD, packet)
                 self.transport.debug.write (
                     ssh_debug.DEBUG_1, 'Trying Password Authentication: %r' % ((service, username,),))
                 if btest:
                     self.transport.debug.write (
                         ssh_debug.DEBUG_1, 'Client side trying to change password: Not Yet Implemented')
                     return send_failure()
                 elif mprobe.authenticate (service, username, password):
                     self.send (PAYLOAD_MSG_USERAUTH_SUCCESS, (SSH_MSG_USERAUTH_SUCCESS,))
                     return True
                 else:
                     tries -= 1
                     coro.sleep_relative (self.sleep_time)
                     self.send_failure()
         else:
             tries -= 1
             coro.sleep_relative (self.sleep_time)
             self.send_failure()
Beispiel #2
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)
Beispiel #3
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)
Beispiel #4
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)
Beispiel #5
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)
 def handle_x11_request(self, want_reply, type_specific_packet_data):
     single_connection, auth_protocol, auth_cookie, screen_number = ssh_packet.unpack_payload(
         X11_CHANNEL_REQUEST_PAYLOAD, type_specific_packet_data
     )
     # XXX fantasize about doing X11 forwarding here?  I think not.
     if want_reply:
         self.send_channel_request_failure()
Beispiel #7
0
 def handle_pty_request(self, want_reply, type_specific_packet_data):
     self.pty = PTY (ssh_packet.unpack_payload(PTY_CHANNEL_REQUEST_PAYLOAD, type_specific_packet_data))
     if want_reply:
         if self.accept_pty:
             self.send_channel_request_success()
         else:
             self.send_channel_request_failure()
Beispiel #8
0
 def msg_userauth_failure(self, packet):
     self.transport.debug.write(ssh_debug.DEBUG_1, '%s Auth: Userauth failure.', (self.name,))
     msg, auths_that_can_continue, partial_success = unpack_payload(PAYLOAD_MSG_USERAUTH_FAILURE, packet)
     # XXX: How to handle partial_success?
     if self.name not in auths_that_can_continue:
         self.transport.debug.write(ssh_debug.DEBUG_1, '%s Auth: Not in the list of auths that can continue', (self.name,))
         raise Userauth_Method_Not_Allowed_Error(auths_that_can_continue)
Beispiel #9
0
 def msg_channel_window_adjust(self, pkt):
     msg, channel_id, bytes_to_add = ssh_packet.unpack_payload(SSH_MSG_CHANNEL_WINDOW_ADJUST_PAYLOAD, pkt)
     channel = self.local_channels[channel_id]
     channel.remote_channel.window_data_left += bytes_to_add
     self.transport.debug.write(ssh_debug.DEBUG_3, 'channel %i window increased by %i to %i',
                                (channel.remote_channel.channel_id, bytes_to_add,
                                 channel.remote_channel.window_data_left))
     channel.window_data_added_cv.wake_all()
Beispiel #10
0
 def msg_channel_extended_data(self, pkt):
     msg, channel_id, data_type_code, data = ssh_packet.unpack_payload(SSH_MSG_CHANNEL_EXTENDED_DATA_PAYLOAD, pkt)
     channel = self.local_channels[channel_id]
     if len(data) > channel.window_data_left:
         self.transport.debug.write(ssh_debug.WARNING, 'channel %i %i bytes overflowed window of %i', (channel.channel_id, len(data), channel.remote_channel.window_data_left))
         # Data is ignored.
     else:
         channel.window_data_left -= len(data)
         channel.append_extended_data_received(data_type_code, data)
Beispiel #11
0
 def verify(self, message, signature):
     e, n = self.public_key
     rsa, blob = packet.unpack_payload(RSA_SIG_PAYLOAD, signature)
     if rsa != 'ssh-rsa':
         raise ValueError(rsa)
     s = number.bytes_to_long(blob)
     rsa_obj = RSA.construct((n, e))
     modulus_n_length_in_octets = rsa_obj.size() / 8
     encoded_message = self.emsa_pkcs1_v1_5_encode(message, modulus_n_length_in_octets)
     return rsa_obj.verify(encoded_message, (s,))
Beispiel #12
0
 def msg_channel_data(self, pkt):
     msg, channel_id, data = ssh_packet.unpack_payload(SSH_MSG_CHANNEL_DATA_PAYLOAD, pkt)
     channel = self.local_channels[channel_id]
     # XXX: In theory, we should verify that len(data) <= channel.max_packet_size
     if len(data) > channel.window_data_left:
         self.transport.debug.write(ssh_debug.WARNING, 'channel %i %i bytes overflowed window of %i', (channel.channel_id, len(data), channel.remote_channel.window_data_left))
         # Data is ignored.
     else:
         channel.window_data_left -= len(data)
         channel.append_data_received(data)
Beispiel #13
0
 def msg_channel_extended_data(self, pkt):
     msg, channel_id, data_type_code, data = ssh_packet.unpack_payload(SSH_MSG_CHANNEL_EXTENDED_DATA_PAYLOAD, pkt)
     channel = self.local_channels[channel_id]
     if len(data) > channel.window_data_left:
         self.transport.debug.write(ssh_debug.WARNING, 'channel %i %i bytes overflowed window of %i',
                                    (channel.channel_id, len(data), channel.remote_channel.window_data_left))
         # Data is ignored.
     else:
         channel.window_data_left -= len(data)
         channel.append_extended_data_received(data_type_code, data)
Beispiel #14
0
 def msg_channel_data(self, pkt):
     msg, channel_id, data = ssh_packet.unpack_payload(SSH_MSG_CHANNEL_DATA_PAYLOAD, pkt)
     channel = self.local_channels[channel_id]
     # XXX: In theory, we should verify that len(data) <= channel.max_packet_size
     if len(data) > channel.window_data_left:
         self.transport.debug.write(ssh_debug.WARNING, 'channel %i %i bytes overflowed window of %i',
                                    (channel.channel_id, len(data), channel.remote_channel.window_data_left))
         # Data is ignored.
     else:
         channel.window_data_left -= len(data)
         channel.append_data_received(data)
Beispiel #15
0
 def msg_channel_close(self, pkt):
     msg, channel_id = ssh_packet.unpack_payload(SSH_MSG_CHANNEL_CLOSE_PAYLOAD, pkt)
     channel = self.local_channels[channel_id]
     del self.local_channels[channel_id]
     del self.remote_channels[channel.remote_channel.channel_id]
     # assert it is not already closed?
     channel.closed = 1
     if not channel.remote_channel.closed:
         # Close the other side.
         channel.close()
     channel.set_eof()
Beispiel #16
0
 def msg_channel_close(self, pkt):
     msg, channel_id = ssh_packet.unpack_payload(SSH_MSG_CHANNEL_CLOSE_PAYLOAD, pkt)
     channel = self.local_channels[channel_id]
     del self.local_channels[channel_id]
     del self.remote_channels[channel.remote_channel.channel_id]
     # assert it is not already closed?
     channel.closed = 1
     if not channel.remote_channel.closed:
         # Close the other side.
         channel.close()
     channel.set_eof()
Beispiel #17
0
 def verify(self, message, signature):
     e, n = self.public_key
     rsa, blob = packet.unpack_payload(RSA_SIG_PAYLOAD, signature)
     if rsa != 'ssh-rsa':
         raise ValueError(rsa)
     s = number.bytes_to_long(blob)
     rsa_obj = RSA.construct((n, e))
     modulus_n_length_in_octets = rsa_obj.size() / 8
     encoded_message = self.emsa_pkcs1_v1_5_encode(
         message, modulus_n_length_in_octets)
     return rsa_obj.verify(encoded_message, (s, ))
Beispiel #18
0
 def msg_userauth_failure(self, packet):
     self.transport.debug.write(ssh_debug.DEBUG_1,
                                '%s Auth: Userauth failure.', (self.name, ))
     msg, auths_that_can_continue, partial_success = unpack_payload(
         PAYLOAD_MSG_USERAUTH_FAILURE, packet)
     # XXX: How to handle partial_success?
     if self.name not in auths_that_can_continue:
         self.transport.debug.write(
             ssh_debug.DEBUG_1,
             '%s Auth: Not in the list of auths that can continue',
             (self.name, ))
         raise Userauth_Method_Not_Allowed_Error(auths_that_can_continue)
Beispiel #19
0
 def verify(self, message, signature):
     p, q, g, y = self.public_key
     dss, blob = packet.unpack_payload(DSS_SIG_PAYLOAD, signature)
     if dss != 'ssh-dss':
         raise ValueError(dss)
     # blob is the concatenation of r and s
     # r and s are 160-bit (20-byte) integers in network-byte-order
     assert(len(blob) == 40)
     r = number.bytes_to_long(blob[:20])
     s = number.bytes_to_long(blob[20:])
     dsa_obj = DSA.construct((y, g, p, q))
     hash_of_message = hashlib.sha1(message).digest()
     return dsa_obj.verify(hash_of_message, (r, s))
Beispiel #20
0
 def verify(self, message, signature):
     p, q, g, y = self.public_key
     dss, blob = packet.unpack_payload(DSS_SIG_PAYLOAD, signature)
     if dss != 'ssh-dss':
         raise ValueError, dss
     # blob is the concatenation of r and s
     # r and s are 160-bit (20-byte) integers in network-byte-order
     assert( len(blob) == 40 )
     r = number.bytes_to_long(blob[:20])
     s = number.bytes_to_long(blob[20:])
     dsa_obj = DSA.construct( (y, g, p, q) )
     hash_of_message = hashlib.sha1(message).digest()
     return dsa_obj.verify(hash_of_message, (r, s))
Beispiel #21
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.')
Beispiel #22
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()
Beispiel #23
0
 def msg_channel_open_confirmation(self, pkt):
     data, offset = ssh_packet.unpack_payload_get_offset(SSH_MSG_CHANNEL_OPEN_CONFIRMATION_PAYLOAD, pkt)
     msg, recipient_channel, sender_channel, window_size, max_packet_size = data
     self.transport.debug.write(ssh_debug.DEBUG_1, 'channel %i open confirmation sender_channel=%i window_size=%i max_packet_size=%i', (recipient_channel, sender_channel, window_size, max_packet_size))
     channel = self.local_channels[recipient_channel]
     # XXX: Assert that the channel is not already open?
     channel.closed = 0
     channel.eof = 0
     channel.remote_channel.closed = 0
     channel.remote_channel.channel_id = sender_channel
     assert not self.remote_channels.has_key(sender_channel)
     self.remote_channels[sender_channel] = channel.remote_channel
     channel.remote_channel.window_size = window_size
     channel.remote_channel.window_data_left = window_size
     channel.remote_channel.max_packet_size = max_packet_size
     additional_data = ssh_packet.unpack_payload(channel.additional_packet_data_types, pkt, offset)
     channel.channel_open_success(additional_data)
Beispiel #24
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)
Beispiel #25
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)
Beispiel #26
0
 def msg_channel_open (self, pkt):
     _, channel_type, remote_id, initial_window, max_packet_size = ssh_packet.unpack_payload (SSH_MSG_CHANNEL_OPEN_PAYLOAD, pkt)
     channel = self.new_channel_class (self)
     self.register_channel (channel)
     channel.remote_channel.closed = 0
     self.transport.send (
         SSH_MSG_CHANNEL_OPEN_CONFIRMATION_PAYLOAD, (
             SSH_MSG_CHANNEL_OPEN_CONFIRMATION,
             remote_id,
             channel.channel_id,
             initial_window,
             max_packet_size,
             )
         )
     self.transport.debug.write (
         ssh_debug.DEBUG_1,
         'channel %i open confirmation sender_channel=%i window_size=%i max_packet_size=%i', (
             remote_id, channel.channel_id, initial_window, max_packet_size
             )
         )
Beispiel #27
0
 def msg_channel_open_confirmation(self, pkt):
     data, offset = ssh_packet.unpack_payload_get_offset(SSH_MSG_CHANNEL_OPEN_CONFIRMATION_PAYLOAD, pkt)
     msg, recipient_channel, sender_channel, window_size, max_packet_size = data
     self.transport.debug.write(
         ssh_debug.DEBUG_1,
         'channel %i open confirmation sender_channel=%i window_size=%i max_packet_size=%i',
         (recipient_channel, sender_channel, window_size, max_packet_size))
     channel = self.local_channels[recipient_channel]
     # XXX: Assert that the channel is not already open?
     channel.closed = 0
     channel.eof = 0
     channel.remote_channel.closed = 0
     channel.remote_channel.channel_id = sender_channel
     assert sender_channel not in self.remote_channels
     self.remote_channels[sender_channel] = channel.remote_channel
     channel.remote_channel.window_size = window_size
     channel.remote_channel.window_data_left = window_size
     channel.remote_channel.max_packet_size = max_packet_size
     additional_data = ssh_packet.unpack_payload(channel.additional_packet_data_types, pkt, offset)
     channel.channel_open_success(additional_data)
Beispiel #28
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)
Beispiel #29
0
 def msg_channel_open (self, pkt):
     _, channel_type, remote_id, initial_window, max_packet_size = ssh_packet.unpack_payload (
         SSH_MSG_CHANNEL_OPEN_PAYLOAD, pkt)
     channel = self.new_channel_class (self)
     self.register_channel (channel)
     channel.remote_channel.closed = 0
     self.transport.send (
         SSH_MSG_CHANNEL_OPEN_CONFIRMATION_PAYLOAD, (
             SSH_MSG_CHANNEL_OPEN_CONFIRMATION,
             remote_id,
             channel.channel_id,
             initial_window,
             max_packet_size,
         )
     )
     self.transport.debug.write (
         ssh_debug.DEBUG_1,
         'channel %i open confirmation sender_channel=%i window_size=%i max_packet_size=%i', (
             remote_id, channel.channel_id, initial_window, max_packet_size
         )
     )
Beispiel #30
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)
Beispiel #31
0
 def set_private_key(self, private_key):
     rsa, n, e, d, p, q = packet.unpack_payload(RSA_PRIVATE_KEY_PAYLOAD, private_key)
     if rsa != 'ssh-rsa':
         raise ValueError(rsa)
     self.public_key = (n, e, d, p, q)
Beispiel #32
0
 def msg_channel_success(self, pkt):
     msg, channel_id = ssh_packet.unpack_payload(SSH_MSG_CHANNEL_SUCCESS_PAYLOAD, pkt)
     channel = self.local_channels[channel_id]
     channel.channel_request_success()
Beispiel #33
0
 def msg_channel_failure(self, pkt):
     msg, channel_id = ssh_packet.unpack_payload(SSH_MSG_CHANNEL_FAILURE_PAYLOAD, pkt)
     channel = self.local_channels[channel_id]
     channel.channel_request_failure()
Beispiel #34
0
 def set_private_key(self, private_key):
     dss, p, q, g, y, x = packet.unpack_payload(DSS_PRIVATE_KEY_PAYLOAD, private_key)
     if dss != 'ssh-dss':
         raise ValueError, dss
     self.private_key = (p, q, g, y, x)
Beispiel #35
0
 def msg_debug(self, packet):
     msg, always_display, message, language = ssh_packet.unpack_payload(ssh_packet.PAYLOAD_MSG_DEBUG, packet)
     self.debug.write(ssh_debug.DEBUG_1, 'SSH_MSG_DEBUG: %s', message)
Beispiel #36
0
    def msg_kexinit(self, packet):
        self.remote2self.kexinit_packet = packet
        msg, cookie, kex_algorithms, server_host_key_algorithms, encryption_algorithms_c2s, \
            encryption_algorithms_s2c, mac_algorithms_c2s, mac_algorithms_s2c, \
            compression_algorithms_c2s, compression_algorithms_s2c, \
            languages_c2s, languages_s2c, first_kex_packet_follows, pad = ssh_packet.unpack_payload(
                ssh_packet.PAYLOAD_MSG_KEXINIT, packet)

        self.remote2self.proactive_kex = first_kex_packet_follows

        self.c2s.set_supported( kex_algorithms,
                                server_host_key_algorithms,
                                encryption_algorithms_c2s,
                                mac_algorithms_c2s,
                                compression_algorithms_c2s,
                                languages_c2s,
                                1)  # Prefer client's list.
        self.s2c.set_supported( kex_algorithms,
                                server_host_key_algorithms,
                                encryption_algorithms_s2c,
                                mac_algorithms_s2c,
                                compression_algorithms_s2c,
                                languages_s2c,
                                0)  # Prefer client's list.

        # The algorithm that we use is the first item that is on the client's
        # list that is also on the server's list.
        self._matchup_kex_and_key()
        self._matchup('cipher')
        self._matchup('mac')
        self._matchup('compression')
        # XXX: lang not supported

        # See if we guessed the kex properly.
        if self.remote2self.proactive_kex and \
            self.remote2self.key_exchange.name != self.key_exchange.name:
            # Remote side sent an incorrect initial kex packet...ignore it.
            self.ignore_first_packet = True

        if self.self2remote.proactive_kex and \
            self.self2remote.key_exchange.name != self.key_exchange.name:
            # We sent an invalid initial kex packet.
            # Resend proper kex packet.
            self.debug.write(ssh_debug.DEBUG_1, 'msg_kexinit: Resending initial kex packet due to incorrect guess')
            if self.is_server:
                packet = self.key_exchange.get_initial_server_kex_packet()
            else:
                packet = self.key_exchange.get_initial_client_kex_packet()
            # packet should never be None because if proactive_kex is set,
            # then that means we sent the first packet.
            assert (packet is not None)
            self.send_packet(packet)

        # Sync up.
        self.remote2self.key_exchange = self.key_exchange
        self.self2remote.key_exchange = self.key_exchange
        self.remote2self.server_key = self.server_key
        self.self2remote.server_key = self.server_key

        # Make sure kex algorithm has the information it needs.
        self.key_exchange.set_info(self.c2s.version_string, self.s2c.version_string, self.c2s.kexinit_packet, self.s2c.kexinit_packet, self.s2c.supported_server_keys)
Beispiel #37
0
 def msg_disconnect(self, packet):
     msg, reason_code, description, language = ssh_packet.unpack_payload(
         ssh_packet.PAYLOAD_MSG_DISCONNECT, packet)
     self.disconnect()
     raise SSH_Protocol_Error(reason_code, description)
Beispiel #38
0
 def msg_debug(self, packet):
     msg, always_display, message, language = ssh_packet.unpack_payload(
         ssh_packet.PAYLOAD_MSG_DEBUG, packet)
     self.debug.write(ssh_debug.DEBUG_1, 'SSH_MSG_DEBUG: %s', message)
Beispiel #39
0
 def msg_channel_success(self, pkt):
     msg, channel_id = ssh_packet.unpack_payload(SSH_MSG_CHANNEL_SUCCESS_PAYLOAD, pkt)
     channel = self.local_channels[channel_id]
     channel.channel_request_success()
Beispiel #40
0
 def set_private_key(self, private_key):
     rsa, n, e, d, p, q = packet.unpack_payload(RSA_PRIVATE_KEY_PAYLOAD,
                                                private_key)
     if rsa != 'ssh-rsa':
         raise ValueError(rsa)
     self.public_key = (n, e, d, p, q)
Beispiel #41
0
 def msg_channel_open_failure(self, pkt):
     msg, channel_id, reason_code, reason_text, language = ssh_packet.unpack_payload(SSH_MSG_CHANNEL_OPEN_FAILURE_PAYLOAD, pkt)
     channel = self.local_channels[channel_id]
     # XXX: Assert that the channel is not already open?
     channel.channel_open_failure(reason_code, reason_text, language)
Beispiel #42
0
 def msg_channel_eof(self, pkt):
     msg, channel_id = ssh_packet.unpack_payload(SSH_MSG_CHANNEL_EOF_PAYLOAD, pkt)
     channel = self.local_channels[channel_id]
     # assert it is not already closed?
     channel.set_eof()
Beispiel #43
0
 def msg_userauth_banner(self, packet):
     msg, message, language = unpack_payload(PAYLOAD_MSG_USERAUTH_BANNER,
                                             packet)
     print safe_string(message)
Beispiel #44
0
 def set_private_key(self, private_key):
     dss, p, q, g, y, x = packet.unpack_payload(DSS_PRIVATE_KEY_PAYLOAD, private_key)
     if dss != 'ssh-dss':
         raise ValueError(dss)
     self.private_key = (p, q, g, y, x)
Beispiel #45
0
 def msg_unimplemented(self, packet):
     msg, seq_number = ssh_packet.unpack_payload(
         ssh_packet.PAYLOAD_MSG_UNIMPLEMENTED, packet)
     self.debug.write(ssh_debug.DEBUG_1, 'SSH_MSG_UNIMPLEMENTED: %i',
                      seq_number)
Beispiel #46
0
 def msg_disconnect(self, packet):
     msg, reason_code, description, language = ssh_packet.unpack_payload (ssh_packet.PAYLOAD_MSG_DISCONNECT, packet)
     self.disconnect()
     raise SSH_Protocol_Error, (reason_code, description)
Beispiel #47
0
    def msg_kexinit(self, packet):
        self.remote2self.kexinit_packet = packet
        msg, cookie, kex_algorithms, server_host_key_algorithms, encryption_algorithms_c2s, \
            encryption_algorithms_s2c, mac_algorithms_c2s, mac_algorithms_s2c, \
            compression_algorithms_c2s, compression_algorithms_s2c, \
            languages_c2s, languages_s2c, first_kex_packet_follows, pad = ssh_packet.unpack_payload(
                ssh_packet.PAYLOAD_MSG_KEXINIT, packet)

        self.remote2self.proactive_kex = first_kex_packet_follows

        self.c2s.set_supported(kex_algorithms, server_host_key_algorithms,
                               encryption_algorithms_c2s, mac_algorithms_c2s,
                               compression_algorithms_c2s, languages_c2s,
                               1)  # Prefer client's list.
        self.s2c.set_supported(kex_algorithms, server_host_key_algorithms,
                               encryption_algorithms_s2c, mac_algorithms_s2c,
                               compression_algorithms_s2c, languages_s2c,
                               0)  # Prefer client's list.

        # The algorithm that we use is the first item that is on the client's
        # list that is also on the server's list.
        self._matchup_kex_and_key()
        self._matchup('cipher')
        self._matchup('mac')
        self._matchup('compression')
        # XXX: lang not supported

        # See if we guessed the kex properly.
        if self.remote2self.proactive_kex and \
                self.remote2self.key_exchange.name != self.key_exchange.name:
            # Remote side sent an incorrect initial kex packet...ignore it.
            self.ignore_first_packet = True

        if self.self2remote.proactive_kex and \
                self.self2remote.key_exchange.name != self.key_exchange.name:
            # We sent an invalid initial kex packet.
            # Resend proper kex packet.
            self.debug.write(
                ssh_debug.DEBUG_1,
                'msg_kexinit: Resending initial kex packet due to incorrect guess'
            )
            if self.is_server:
                packet = self.key_exchange.get_initial_server_kex_packet()
            else:
                packet = self.key_exchange.get_initial_client_kex_packet()
            # packet should never be None because if proactive_kex is set,
            # then that means we sent the first packet.
            assert (packet is not None)
            self.send_packet(packet)

        # Sync up.
        self.remote2self.key_exchange = self.key_exchange
        self.self2remote.key_exchange = self.key_exchange
        self.remote2self.server_key = self.server_key
        self.self2remote.server_key = self.server_key

        # Make sure kex algorithm has the information it needs.
        self.key_exchange.set_info(self.c2s.version_string,
                                   self.s2c.version_string,
                                   self.c2s.kexinit_packet,
                                   self.s2c.kexinit_packet,
                                   self.s2c.supported_server_keys)
Beispiel #48
0
 def msg_unimplemented(self, packet):
     msg, seq_number = ssh_packet.unpack_payload(ssh_packet.PAYLOAD_MSG_UNIMPLEMENTED, packet)
     self.debug.write(ssh_debug.DEBUG_1, 'SSH_MSG_UNIMPLEMENTED: %i', seq_number)
Beispiel #49
0
 def msg_userauth_banner(self, packet):
     msg, message, language = unpack_payload(PAYLOAD_MSG_USERAUTH_BANNER, packet)
     print safe_string(message)
Beispiel #50
0
 def set_public_key(self, public_key):
     dss, p, q, g, y = packet.unpack_payload(DSS_PUBLIC_KEY_PAYLOAD, public_key)
     if dss != 'ssh-dss':
         raise ValueError(dss)
     self.public_key = (p, q, g, y)
Beispiel #51
0
 def msg_channel_open_failure(self, pkt):
     msg, channel_id, reason_code, reason_text, language = ssh_packet.unpack_payload(
         SSH_MSG_CHANNEL_OPEN_FAILURE_PAYLOAD, pkt)
     channel = self.local_channels[channel_id]
     # XXX: Assert that the channel is not already open?
     channel.channel_open_failure(reason_code, reason_text, language)
Beispiel #52
0
 def set_public_key(self, public_key):
     dss, p, q, g, y = packet.unpack_payload(DSS_PUBLIC_KEY_PAYLOAD, public_key)
     if dss != 'ssh-dss':
         raise ValueError, dss
     self.public_key = (p, q, g, y)
Beispiel #53
0
 def set_public_key(self, public_key):
     rsa, e, n = packet.unpack_payload(RSA_PUBLIC_KEY_PAYLOAD, public_key)
     if rsa != 'ssh-rsa':
         raise ValueError(rsa)
     self.public_key = (e, n)
Beispiel #54
0
 def authenticate(self, service_name):
     session_id = self.transport.key_exchange.session_id
     tries = self.max_tries
     while tries:
         # this is relatively stateless, because the RFC says the client can send requests without bothering
         #  to see if the server even wants them.
         # XXX allow each method to be tried, then removed from the list of
         # possibles? [think about combinations of service/user/etc... though]
         message_type, packet = self.transport.receive_message(
             (SSH_MSG_USERAUTH_REQUEST, ))
         msg, username, service, method = unpack_payload(
             PAYLOAD_MSG_USERAUTH_REQUEST, packet)
         if method == 'none':
             self.send_failure()
         elif method == 'publickey':
             mprobe = self.by_name.get('publickey')
             if not mprobe:
                 self.send_failure()
             else:
                 (_, _, _, _, btest, alg, blob) = unpack_payload(
                     PAYLOAD_MSG_USERAUTH_REQUEST_PK_TEST, packet)
                 if not btest:
                     # XXX: ask method if it's ok with serv+user+alg+blob
                     self.send(PAYLOAD_MSG_USERAUTH_PK_OK,
                               (SSH_MSG_USERAUTH_PK_OK, alg, blob))
                 else:
                     (_, _, _, _, _, _, key,
                      sig) = unpack_payload(PAYLOAD_MSG_USERAUTH_REQUEST_PK,
                                            packet)
                     self.transport.debug.write(
                         ssh_debug.DEBUG_1,
                         'Trying Public Key Authentication: %r' %
                         ((service, username, alg), ))
                     if mprobe.authenticate(session_id, service, username,
                                            alg, key, sig):
                         self.send(PAYLOAD_MSG_USERAUTH_SUCCESS,
                                   (SSH_MSG_USERAUTH_SUCCESS, ))
                         return True
                     else:
                         tries -= 1
                         coro.sleep_relative(self.sleep_time)
                         self.send_failure()
         elif method == 'password':
             mprobe = self.by_name.get('password')
             if not mprobe:
                 self.send_failure()
             else:
                 (_, _, _, _, btest, password) = unpack_payload(
                     PAYLOAD_MSG_USERAUTH_REQUEST_PASSWORD, packet)
                 self.transport.debug.write(
                     ssh_debug.DEBUG_1,
                     'Trying Password Authentication: %r' % ((
                         service,
                         username,
                     ), ))
                 if btest:
                     self.transport.debug.write(
                         ssh_debug.DEBUG_1,
                         'Client side trying to change password: Not Yet Implemented'
                     )
                     return send_failure()
                 elif mprobe.authenticate(service, username, password):
                     self.send(PAYLOAD_MSG_USERAUTH_SUCCESS,
                               (SSH_MSG_USERAUTH_SUCCESS, ))
                     return True
                 else:
                     tries -= 1
                     coro.sleep_relative(self.sleep_time)
                     self.send_failure()
         else:
             tries -= 1
             coro.sleep_relative(self.sleep_time)
             self.send_failure()
Beispiel #55
0
 def set_public_key(self, public_key):
     rsa, e, n = packet.unpack_payload(RSA_PUBLIC_KEY_PAYLOAD, public_key)
     if rsa != 'ssh-rsa':
         raise ValueError(rsa)
     self.public_key = (e, n)
Beispiel #56
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)
Beispiel #57
0
 def get_key_algorithm(self, key):
     name = ssh_packet.unpack_payload((ssh_packet.STRING,), key)[0]
     for key_alg in self.supported_server_keys:
         if key_alg.name == name:
             return key_alg
     raise ValueError(name)
Beispiel #58
0
 def msg_channel_failure(self, pkt):
     msg, channel_id = ssh_packet.unpack_payload(SSH_MSG_CHANNEL_FAILURE_PAYLOAD, pkt)
     channel = self.local_channels[channel_id]
     channel.channel_request_failure()
Beispiel #59
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)