Exemplo n.º 1
0
 def _read_private_key(self, tag, f, password=None):
     lines = f.readlines()
     start = 0
     while (start < len(lines)) and (lines[start].strip() != '-----BEGIN ' + tag + ' PRIVATE KEY-----'):
         start += 1
     if start >= len(lines):
         raise SSHException('not a valid ' + tag + ' private key file')
     # parse any headers first
     headers = {}
     start += 1
     while start < len(lines):
         l = lines[start].split(': ')
         if len(l) == 1:
             break
         headers[l[0].lower()] = l[1].strip()
         start += 1
     # find end
     end = start
     while (lines[end].strip() != '-----END ' + tag + ' PRIVATE KEY-----') and (end < len(lines)):
         end += 1
     # if we trudged to the end of the file, just try to cope.
     try:
         data = base64.decodestring(''.join(lines[start:end]))
     except base64.binascii.Error, e:
         raise SSHException('base64 decoding error: ' + str(e))
Exemplo n.º 2
0
 def __init__(self, msg=None, data=None, filename=None, password=None, vals=None, file_obj=None):
     self.p = None
     self.q = None
     self.g = None
     self.y = None
     self.x = None
     if file_obj is not None:
         self._from_private_key(file_obj, password)
         return
     if filename is not None:
         self._from_private_key_file(filename, password)
         return
     if (msg is None) and (data is not None):
         msg = Message(data)
     if vals is not None:
         self.p, self.q, self.g, self.y = vals
     else:
         if msg is None:
             raise SSHException('Key object may not be empty')
         if msg.get_string() != 'ssh-dss':
             raise SSHException('Invalid key')
         self.p = msg.get_mpint()
         self.q = msg.get_mpint()
         self.g = msg.get_mpint()
         self.y = msg.get_mpint()
     self.size = util.bit_length(self.p)
Exemplo n.º 3
0
    def __init__(self,
                 msg=None,
                 data=None,
                 filename=None,
                 password=None,
                 vals=None,
                 file_obj=None,
                 validate_point=True):
        self.verifying_key = None
        self.signing_key = None
        self.public_blob = None
        if file_obj is not None:
            self._from_private_key(file_obj, password)
            return
        if filename is not None:
            self._from_private_key_file(filename, password)
            return
        if (msg is None) and (data is not None):
            msg = Message(data)
        if vals is not None:
            self.signing_key, self.verifying_key = vals
            c_class = self.signing_key.curve.__class__
            self.ecdsa_curve = self._ECDSA_CURVES.get_by_curve_class(c_class)
        else:
            # Must set ecdsa_curve first; subroutines called herein may need to
            # spit out our get_name(), which relies on this.
            key_type = msg.get_text()
            # But this also means we need to hand it a real key/curve
            # identifier, so strip out any cert business. (NOTE: could push
            # that into _ECDSACurveSet.get_by_key_format_identifier(), but it
            # feels more correct to do it here?)
            suffix = '*****@*****.**'
            if key_type.endswith(suffix):
                key_type = key_type[:-len(suffix)]
            self.ecdsa_curve = self._ECDSA_CURVES.get_by_key_format_identifier(
                key_type)
            key_types = self._ECDSA_CURVES.get_key_format_identifier_list()
            cert_types = [
                '{}[email protected]'.format(x) for x in key_types
            ]
            self._check_type_and_load_cert(
                msg=msg,
                key_type=key_types,
                cert_type=cert_types,
            )
            curvename = msg.get_text()
            if curvename != self.ecdsa_curve.nist_name:
                raise SSHException(
                    "Can't handle curve of type {}".format(curvename))

            pointinfo = msg.get_binary()
            try:
                numbers = ec.EllipticCurvePublicNumbers.from_encoded_point(
                    self.ecdsa_curve.curve_class(), pointinfo)
            except ValueError:
                raise SSHException("Invalid public key")
            self.verifying_key = numbers.public_key(backend=default_backend())
Exemplo n.º 4
0
 def _read_all(self, wanted):
     result = self._conn.recv(wanted)
     while len(result) < wanted:
         if len(result) == 0:
             raise SSHException('lost ssh-agent')
         extra = self._conn.recv(wanted - len(result))
         if len(extra) == 0:
             raise SSHException('lost ssh-agent')
         result += extra
     return result
Exemplo n.º 5
0
 def _encode_key(self):
     if self.x is None:
         raise SSHException('Not enough key information')
     keylist = [ 0, self.p, self.q, self.g, self.y, self.x ]
     try:
         b = BER()
         b.encode(keylist)
     except BERException:
         raise SSHException('Unable to create ber encoding of key')
     return str(b)
Exemplo n.º 6
0
 def _read_private_key(self, tag, f, password=None):
     lines = f.readlines()
     start = 0
     beginning_of_key = '-----BEGIN ' + tag + ' PRIVATE KEY-----'
     while start < len(lines) and lines[start].strip() != beginning_of_key:
         start += 1
     if start >= len(lines):
         raise SSHException('not a valid ' + tag + ' private key file')
     # parse any headers first
     headers = {}
     start += 1
     while start < len(lines):
         l = lines[start].split(': ')
         if len(l) == 1:
             break
         headers[l[0].lower()] = l[1].strip()
         start += 1
     # find end
     end = start
     ending_of_key = '-----END ' + tag + ' PRIVATE KEY-----'
     while end < len(lines) and lines[end].strip() != ending_of_key:
         end += 1
     # if we trudged to the end of the file, just try to cope.
     try:
         data = decodebytes(b(''.join(lines[start:end])))
     except base64.binascii.Error as e:
         raise SSHException('base64 decoding error: ' + str(e))
     if 'proc-type' not in headers:
         # unencryped: done
         return data
     # encrypted keyfile: will need a password
     proc_type = headers['proc-type']
     if proc_type != '4,ENCRYPTED':
         raise SSHException(
             'Unknown private key structure "{}"'.format(proc_type))
     try:
         encryption_type, saltstr = headers['dek-info'].split(',')
     except:
         raise SSHException("Can't parse DEK-info in private key file")
     if encryption_type not in self._CIPHER_TABLE:
         raise SSHException(
             'Unknown private key cipher "{}"'.format(encryption_type))
     # if no password was passed in,
     # raise an exception pointing out that we need one
     if password is None:
         raise PasswordRequiredException('Private key file is encrypted')
     cipher = self._CIPHER_TABLE[encryption_type]['cipher']
     keysize = self._CIPHER_TABLE[encryption_type]['keysize']
     mode = self._CIPHER_TABLE[encryption_type]['mode']
     salt = unhexlify(b(saltstr))
     key = util.generate_key_bytes(md5, salt, password, keysize)
     decryptor = Cipher(cipher(key), mode(salt),
                        backend=default_backend()).decryptor()
     return decryptor.update(data) + decryptor.finalize()
Exemplo n.º 7
0
def unpad(data):
    # At the moment, this is only used for unpadding private keys on disk. This
    # really ought to be made constant time (possibly by upstreaming this logic
    # into pyca/cryptography).
    padding_length = six.indexbytes(data, -1)
    if padding_length > 16:
        raise SSHException("Invalid key")
    for i in range(1, padding_length + 1):
        if six.indexbytes(data, -i) != (padding_length - i + 1):
            raise SSHException("Invalid key")
    return data[:-padding_length]
Exemplo n.º 8
0
 def _encode_key(self):
     if (self.p is None) or (self.q is None):
         raise SSHException('Not enough key info to write private key file')
     keylist = [
         0, self.n, self.e, self.d, self.p, self.q, self.d % (self.p - 1),
         self.d % (self.q - 1),
         util.mod_inverse(self.q, self.p)
     ]
     try:
         b = BER()
         b.encode(keylist)
     except BERException:
         raise SSHException('Unable to create ber encoding of key')
     return str(b)
Exemplo n.º 9
0
 def _parse_service_accept(self, m):
     service = m.get_string()
     if service == 'ssh-userauth':
         self.transport._log(DEBUG, 'userauth is OK')
         m = Message()
         m.add_byte(chr(MSG_USERAUTH_REQUEST))
         m.add_string(self.username)
         m.add_string('ssh-connection')
         m.add_string(self.auth_method)
         if self.auth_method == 'password':
             m.add_boolean(False)
             password = self.password
             if isinstance(password, unicode):
                 password = password.encode('UTF-8')
             m.add_string(password)
         elif self.auth_method == 'publickey':
             m.add_boolean(True)
             m.add_string(self.private_key.get_name())
             m.add_string(str(self.private_key))
             blob = self._get_session_blob(self.private_key,
                                           'ssh-connection', self.username)
             sig = self.private_key.sign_ssh_data(self.transport.rng, blob)
             m.add_string(str(sig))
         elif self.auth_method == 'keyboard-interactive':
             m.add_string('')
             m.add_string(self.submethods)
         elif self.auth_method == 'none':
             pass
         else:
             raise SSHException('Unknown auth method "%s"' %
                                self.auth_method)
         self.transport._send_message(m)
     else:
         self.transport._log(DEBUG,
                             'Service request "%s" accepted (?)' % service)
Exemplo n.º 10
0
    def exec_command(self, command):
        """
        Execute a command on the server.  If the server allows it, the channel
        will then be directly connected to the stdin, stdout, and stderr of
        the command being executed.
        
        When the command finishes executing, the channel will be closed and
        can't be reused.  You must open a new channel if you wish to execute
        another command.

        @param command: a shell command to execute.
        @type command: str

        @raise SSHException: if the request was rejected or the channel was
            closed
        """
        if self.closed or self.eof_received or self.eof_sent or not self.active:
            raise SSHException('Channel is not open')
        m = Message()
        m.add_byte(chr(MSG_CHANNEL_REQUEST))
        m.add_int(self.remote_chanid)
        m.add_string('exec')
        m.add_boolean(True)
        m.add_string(command)
        self._event_pending()
        self.transport._send_user_message(m)
        self._wait_for_event()
Exemplo n.º 11
0
 def _decode_key(self, data):
     # private key file contains:
     # DSAPrivateKey = { version = 0, p, q, g, y, x }
     try:
         keylist = BER(data).decode()
     except BERException as e:
         raise SSHException('Unable to parse key file: ' + str(e))
     if (type(keylist) is not list or len(keylist) < 6 or keylist[0] != 0):
         raise SSHException(
             'not a valid DSA private key file (bad ber encoding)')
     self.p = keylist[1]
     self.q = keylist[2]
     self.g = keylist[3]
     self.y = keylist[4]
     self.x = keylist[5]
     self.size = util.bit_length(self.p)
Exemplo n.º 12
0
 def parse_next(self, ptype, m):
     if self.transport.server_mode and (ptype == _MSG_KEXECDH_INIT):
         return self._parse_kexecdh_init(m)
     elif not self.transport.server_mode and (ptype == _MSG_KEXECDH_REPLY):
         return self._parse_kexecdh_reply(m)
     raise SSHException(
         'KexECDH asked to handle packet type {:d}'.format(ptype))
Exemplo n.º 13
0
    def __init__(self, sock):
        """
        Create an SFTP client from an existing L{Channel}.  The channel
        should already have requested the C{"sftp"} subsystem.

        An alternate way to create an SFTP client context is by using
        L{from_transport}.

        @param sock: an open L{Channel} using the C{"sftp"} subsystem
        @type sock: L{Channel}

        @raise SSHException: if there's an exception while negotiating
            sftp
        """
        BaseSFTP.__init__(self)
        self.sock = sock
        self.ultra_debug = False
        self.request_number = 1
        # lock for request_number
        self._lock = threading.Lock()
        self._cwd = None
        # request # -> SFTPFile
        self._expecting = weakref.WeakValueDictionary()
        if type(sock) is Channel:
            # override default logger
            transport = self.sock.get_transport()
            self.logger = util.get_logger(transport.get_log_channel() +
                                          '.sftp')
            self.ultra_debug = transport.get_hexdump()
        try:
            server_version = self._send_version()
        except EOFError, x:
            raise SSHException('EOF during negotiation')
Exemplo n.º 14
0
 def get_modulus(self, min, prefer, max):
     bitsizes = sorted(self.pack.keys())
     if len(bitsizes) == 0:
         raise SSHException('no moduli available')
     good = -1
     # find nearest bitsize >= preferred
     for b in bitsizes:
         if (b >= prefer) and (b <= max) and (b < good or good == -1):
             good = b
     # if that failed, find greatest bitsize >= min
     if good == -1:
         for b in bitsizes:
             if (b >= min) and (b <= max) and (b > good):
                 good = b
     if good == -1:
         # their entire (min, max) range has no intersection with our range.
         # if their range is below ours, pick the smallest.  otherwise pick
         # the largest.  it'll be out of their range requirement either way,
         # but we'll be sending them the closest one we have.
         good = bitsizes[0]
         if min > good:
             good = bitsizes[-1]
     # now pick a random modulus of this bitsize
     n = _roll_random(len(self.pack[good]))
     return self.pack[good][n]
Exemplo n.º 15
0
 def _parse_kexdh_gex_request(self, m):
     minbits = m.get_int()
     preferredbits = m.get_int()
     maxbits = m.get_int()
     # smoosh the user's preferred size into our own limits
     if preferredbits > self.max_bits:
         preferredbits = self.max_bits
     if preferredbits < self.min_bits:
         preferredbits = self.min_bits
     # fix min/max if they're inconsistent.  technically, we could just pout
     # and hang up, but there's no harm in giving them the benefit of the
     # doubt and just picking a bitsize for them.
     if minbits > preferredbits:
         minbits = preferredbits
     if maxbits < preferredbits:
         maxbits = preferredbits
     # now save a copy
     self.min_bits = minbits
     self.preferred_bits = preferredbits
     self.max_bits = maxbits
     # generate prime
     pack = self.transport._get_modulus_pack()
     if pack is None:
         raise SSHException(
             'Can\'t do server-side gex with no modulus pack')
     self.transport._log(
         DEBUG, 'Picking p (%d <= %d <= %d bits)' %
         (minbits, preferredbits, maxbits))
     self.g, self.p = pack.get_modulus(minbits, preferredbits, maxbits)
     m = Message()
     m.add_byte(chr(_MSG_KEXDH_GEX_GROUP))
     m.add_mpint(self.p)
     m.add_mpint(self.g)
     self.transport._send_message(m)
     self.transport._expect_packet(_MSG_KEXDH_GEX_INIT)
Exemplo n.º 16
0
 def _decode_key(self, data):
     # private key file contains:
     # DSAPrivateKey = { version = 0, p, q, g, y, x }
     try:
         keylist = BER(data).decode()
     except BERException, x:
         raise SSHException('Unable to parse key file: ' + str(x))
Exemplo n.º 17
0
    def resize_pty(self, width=80, height=24, width_pixels=0, height_pixels=0):
        """
        Resize the pseudo-terminal.  This can be used to change the width and
        height of the terminal emulation created in a previous L{get_pty} call.

        @param width: new width (in characters) of the terminal screen
        @type width: int
        @param height: new height (in characters) of the terminal screen
        @type height: int
        @param width_pixels: new width (in pixels) of the terminal screen
        @type width_pixels: int
        @param height_pixels: new height (in pixels) of the terminal screen
        @type height_pixels: int

        @raise SSHException: if the request was rejected or the channel was
            closed
        """
        if self.closed or self.eof_received or self.eof_sent or not self.active:
            raise SSHException('Channel is not open')
        m = Message()
        m.add_byte(chr(MSG_CHANNEL_REQUEST))
        m.add_int(self.remote_chanid)
        m.add_string('window-change')
        m.add_boolean(False)
        m.add_int(width)
        m.add_int(height)
        m.add_int(width_pixels)
        m.add_int(height_pixels)
        self.transport._send_user_message(m)
Exemplo n.º 18
0
    def invoke_subsystem(self, subsystem):
        """
        Request a subsystem on the server (for example, C{sftp}).  If the
        server allows it, the channel will then be directly connected to the
        requested subsystem.
        
        When the subsystem finishes, the channel will be closed and can't be
        reused.

        @param subsystem: name of the subsystem being requested.
        @type subsystem: str

        @raise SSHException: if the request was rejected or the channel was
            closed
        """
        if self.closed or self.eof_received or self.eof_sent or not self.active:
            raise SSHException('Channel is not open')
        m = Message()
        m.add_byte(chr(MSG_CHANNEL_REQUEST))
        m.add_int(self.remote_chanid)
        m.add_string('subsystem')
        m.add_boolean(True)
        m.add_string(subsystem)
        self._event_pending()
        self.transport._send_user_message(m)
        self._wait_for_event()
Exemplo n.º 19
0
 def _parse_kexdh_gex_request_old(self, m):
     # same as above, but without min_bits or max_bits (used by older
     # clients like putty)
     self.preferred_bits = m.get_int()
     # smoosh the user's preferred size into our own limits
     if self.preferred_bits > self.max_bits:
         self.preferred_bits = self.max_bits
     if self.preferred_bits < self.min_bits:
         self.preferred_bits = self.min_bits
     # generate prime
     pack = self.transport._get_modulus_pack()
     if pack is None:
         raise SSHException(
             'Can\'t do server-side gex with no modulus pack')
     self.transport._log(
         DEBUG, 'Picking p (~ {} bits)'.format(self.preferred_bits))
     self.g, self.p = pack.get_modulus(self.min_bits, self.preferred_bits,
                                       self.max_bits)
     m = Message()
     m.add_byte(c_MSG_KEXDH_GEX_GROUP)
     m.add_mpint(self.p)
     m.add_mpint(self.g)
     self.transport._send_message(m)
     self.transport._expect_packet(_MSG_KEXDH_GEX_INIT)
     self.old_style = True
Exemplo n.º 20
0
 def _parse_kexdh_gex_reply(self, m):
     host_key = m.get_string()
     self.f = m.get_mpint()
     sig = m.get_string()
     if (self.f < 1) or (self.f > self.p - 1):
         raise SSHException('Server kex "f" is out of range')
     K = pow(self.f, self.x, self.p)
     # okay, build up the hash H of
     # (V_C || V_S || I_C || I_S || K_S || min || n || max || p || g || e || f || K)  # noqa
     hm = Message()
     hm.add(self.transport.local_version, self.transport.remote_version,
            self.transport.local_kex_init, self.transport.remote_kex_init,
            host_key)
     if not self.old_style:
         hm.add_int(self.min_bits)
     hm.add_int(self.preferred_bits)
     if not self.old_style:
         hm.add_int(self.max_bits)
     hm.add_mpint(self.p)
     hm.add_mpint(self.g)
     hm.add_mpint(self.e)
     hm.add_mpint(self.f)
     hm.add_mpint(K)
     self.transport._set_K_H(K, self.hash_algo(hm.asbytes()).digest())
     self.transport._verify_key(host_key, sig)
     self.transport._activate_outbound()
Exemplo n.º 21
0
 def _parse_kexdh_init(self, m):
     # server mode
     self.e = m.get_mpint()
     if (self.e < 1) or (self.e > self.P - 1):
         raise SSHException('Client kex "e" is out of range')
     K = pow(self.e, self.x, self.P)
     key = self.transport.get_server_key().asbytes()
     # okay, build up the hash H of
     # (V_C || V_S || I_C || I_S || K_S || e || f || K)
     hm = Message()
     hm.add(self.transport.remote_version, self.transport.local_version,
            self.transport.remote_kex_init, self.transport.local_kex_init)
     hm.add_string(key)
     hm.add_mpint(self.e)
     hm.add_mpint(self.f)
     hm.add_mpint(K)
     H = sha1(hm.asbytes()).digest()
     self.transport._set_K_H(K, H)
     # sign it
     sig = self.transport.get_server_key().sign_ssh_data(H)
     # send reply
     m = Message()
     m.add_byte(c_MSG_KEXDH_REPLY)
     m.add_string(key)
     m.add_mpint(self.f)
     m.add_string(sig)
     self.transport._send_message(m)
     self.transport._activate_outbound()
Exemplo n.º 22
0
    def _parse_kexgss_group(self, m):
        """
        Parse the SSH2_MSG_KEXGSS_GROUP message (client mode).

        :param `Message` m: The content of the SSH2_MSG_KEXGSS_GROUP message
        """
        self.p = m.get_mpint()
        self.g = m.get_mpint()
        # reject if p's bit length < 1024 or > 8192
        bitlen = util.bit_length(self.p)
        if (bitlen < 1024) or (bitlen > 8192):
            raise SSHException(
                'Server-generated gex p (don\'t ask) is out of range '
                '({} bits)'.format(bitlen))
        self.transport._log(DEBUG,
                            'Got server p ({} bits)'.format(bitlen))  # noqa
        self._generate_x()
        # now compute e = g^x mod p
        self.e = pow(self.g, self.x, self.p)
        m = Message()
        m.add_byte(c_MSG_KEXGSS_INIT)
        m.add_string(self.kexgss.ssh_init_sec_context(target=self.gss_host))
        m.add_mpint(self.e)
        self.transport._send_message(m)
        self.transport._expect_packet(MSG_KEXGSS_HOSTKEY, MSG_KEXGSS_CONTINUE,
                                      MSG_KEXGSS_COMPLETE, MSG_KEXGSS_ERROR)
Exemplo n.º 23
0
 def parse_next(self, ptype, m):
     if self.transport.server_mode and (ptype == _MSG_KEXDH_INIT):
         return self._parse_kexdh_init(m)
     elif not self.transport.server_mode and (ptype == _MSG_KEXDH_REPLY):
         return self._parse_kexdh_reply(m)
     msg = "KexGroup1 asked to handle packet type {:d}"
     raise SSHException(msg.format(ptype))
Exemplo n.º 24
0
 def _read_response(self, waitfor=None):
     while True:
         try:
             t, data = self._read_packet()
         except EOFError, e:
             raise SSHException('Server connection dropped: %s' %
                                (str(e), ))
         msg = Message(data)
         num = msg.get_int()
         if num not in self._expecting:
             # might be response for a file that was closed before responses came back
             self._log(DEBUG, 'Unexpected response #%d' % (num, ))
             if waitfor is None:
                 # just doing a single check
                 break
             continue
         fileobj = self._expecting[num]
         del self._expecting[num]
         if num == waitfor:
             # synchronous
             if t == CMD_STATUS:
                 self._convert_status(msg)
             return t, msg
         if fileobj is not type(None):
             fileobj._async_response(t, msg)
         if waitfor is None:
             # just doing a single check
             break
Exemplo n.º 25
0
 def invoke_shell(self):
     """
     Request an interactive shell session on this channel.  If the server
     allows it, the channel will then be directly connected to the stdin,
     stdout, and stderr of the shell.
     
     Normally you would call L{get_pty} before this, in which case the
     shell will operate through the pty, and the channel will be connected
     to the stdin and stdout of the pty.
     
     When the shell exits, the channel will be closed and can't be reused.
     You must open a new channel if you wish to open another shell.
     
     @raise SSHException: if the request was rejected or the channel was
         closed
     """
     if self.closed or self.eof_received or self.eof_sent or not self.active:
         raise SSHException('Channel is not open')
     m = Message()
     m.add_byte(chr(MSG_CHANNEL_REQUEST))
     m.add_int(self.remote_chanid)
     m.add_string('shell')
     m.add_boolean(1)
     self._event_pending()
     self.transport._send_user_message(m)
     self._wait_for_event()
Exemplo n.º 26
0
    def _check_type_and_load_cert(self, msg, key_type, cert_type):
        """
        Perform message type-checking & optional certificate loading.

        This includes fast-forwarding cert ``msg`` objects past the nonce, so
        that the subsequent fields are the key numbers; thus the caller may
        expect to treat the message as key material afterwards either way.

        The obtained key type is returned for classes which need to know what
        it was (e.g. ECDSA.)
        """
        # Normalization; most classes have a single key type and give a string,
        # but eg ECDSA is a 1:N mapping.
        key_types = key_type
        cert_types = cert_type
        if isinstance(key_type, string_types):
            key_types = [key_types]
        if isinstance(cert_types, string_types):
            cert_types = [cert_types]
        # Can't do much with no message, that should've been handled elsewhere
        if msg is None:
            raise SSHException('Key object may not be empty')
        # First field is always key type, in either kind of object. (make sure
        # we rewind before grabbing it - sometimes caller had to do their own
        # introspection first!)
        msg.rewind()
        type_ = msg.get_text()
        # Regular public key - nothing special to do besides the implicit
        # type check.
        if type_ in key_types:
            pass
        # OpenSSH-compatible certificate - store full copy as .public_blob
        # (so signing works correctly) and then fast-forward past the
        # nonce.
        elif type_ in cert_types:
            # This seems the cleanest way to 'clone' an already-being-read
            # message; they're *IO objects at heart and their .getvalue()
            # always returns the full value regardless of pointer position.
            self.load_certificate(Message(msg.asbytes()))
            # Read out nonce as it comes before the public numbers.
            # TODO: usefully interpret it & other non-public-number fields
            # (requires going back into per-type subclasses.)
            msg.get_string()
        else:
            err = 'Invalid key (class: {}, data type: {}'
            raise SSHException(err.format(self.__class__.__name__, type_))
Exemplo n.º 27
0
 def _decode_key(self, data):
     # private key file contains:
     # RSAPrivateKey = { version = 0, n, e, d, p, q, d mod p-1, d mod q-1, q**-1 mod p }
     try:
         keylist = BER(data).decode()
     except BERException:
         raise SSHException('Unable to parse key file')
     if (type(keylist)
             is not list) or (len(keylist) < 4) or (keylist[0] != 0):
         raise SSHException(
             'Not a valid RSA private key file (bad ber encoding)')
     self.n = keylist[1]
     self.e = keylist[2]
     self.d = keylist[3]
     # not really needed
     self.p = keylist[4]
     self.q = keylist[5]
     self.size = util.bit_length(self.n)
Exemplo n.º 28
0
 def missing_host_key(self, client, hostname, key):
     client._log(
         DEBUG, 'Rejecting {} host key for {}: {}'.format(
             key.get_name(),
             hostname,
             hexlify(key.get_fingerprint()),
         ))
     raise SSHException(
         'Server {!r} not found in known_hosts'.format(hostname))
Exemplo n.º 29
0
 def _wait_for_event(self):
     self.event.wait()
     assert self.event.is_set()
     if self.event_ready:
         return
     e = self.transport.get_exception()
     if e is None:
         e = SSHException('Channel closed.')
     raise e
Exemplo n.º 30
0
    def _decode_key(self, data):
        try:
            key = serialization.load_der_private_key(
                data, password=None, backend=default_backend()
            )
        except ValueError as e:
            raise SSHException(str(e))

        assert isinstance(key, rsa.RSAPrivateKey)
        self.key = key