예제 #1
0
def sftp_ctx():
    """
    Context manager that provides an SFTP client object
    (an SFTP session across an open SSH Transport)
    """
    transport = paramiko.Transport((current_app.config['SFTP_HOSTNAME'],
                                    int(current_app.config['SFTP_PORT'])))
    authentication_kwarg = {}
    if current_app.config['SFTP_PASSWORD']:
        authentication_kwarg['password'] = current_app.config['SFTP_PASSWORD']
    elif current_app.config['SFTP_RSA_KEY_FILE']:
        authentication_kwarg['pkey'] = paramiko.RSAKey(
            filename=current_app.config['SFTP_RSA_KEY_FILE'])
    else:
        raise SFTPCredentialsException

    transport.connect(username=current_app.config['SFTP_USERNAME'],
                      **authentication_kwarg)
    sftp = paramiko.SFTPClient.from_transport(transport)
    try:
        yield sftp
    except Exception as e:
        sentry.captureException()
        raise paramiko.SFTPError("Exception occurred with SFTP: {}".format(e))
    finally:
        sftp.close()
        transport.close()
예제 #2
0
    def test_exists_paramiko_error(self, mock_ssh):
        """ Test run RemoteHost.exists """

        remote = remote_host.RemoteHost("53.1.1.1", "ssh_user", "ssh_key_file")
        exists = remote.remote_exists("true_path")

        self.assertTrue(exists, "expected true")
        remote.ftp.stat.assert_called_with("true_path")

        remote.ftp = mock_ssh
        mock_ssh.stat.side_effect = paramiko.SFTPError("paramiko.SFTPError")
        exists = remote.remote_exists("paramiko_exception_path")

        self.assertFalse(exists, "expected False")
        remote.ftp.stat.assert_called_with("paramiko_exception_path")
예제 #3
0
    def __init__(self,
                 name: str,
                 mode: str = 'r',
                 bufsize: int = -1,
                 hostname: str = None,
                 port: int = 22,
                 username: str = None,
                 password: str = None,
                 keyfile: str = None,
                 root: str = None,
                 mkdir: bool = True,
                 *args,
                 **kwargs):
        """Open/create a file over a SSH connection.

        Args:
            name: Name of file.
            mode: Open mode.
            bufsize: Size of buffer size for SFTP connection.
            hostname: Name of host to connect to.
            port: Port on host to connect to.
            username: Username to log in on host.
            password: Password for username.
            keyfile: Path to SSH key on local machine.
            root: Root directory on host.
            mkdir: Whether or not to automatically create directories.
        """

        # no root given?
        if root is None:
            raise ValueError('No root directory given.')

        # filename is not allowed to start with a / or contain ..
        if name.startswith('/') or '..' in name:
            raise ValueError('Only files within root directory are allowed.')

        # build filename
        self.filename = name
        full_path = os.path.join(root, name)

        # connect
        self._ssh = paramiko.SSHClient()
        self._ssh.load_system_host_keys()
        self._ssh.connect(hostname,
                          port=port,
                          username=username,
                          password=password,
                          key_filename=keyfile)
        self._sftp = self._ssh.open_sftp()

        # need to create directory?
        path = os.path.dirname(full_path)
        try:
            self._sftp.chdir(path)
        except IOError:
            if mkdir:
                self._sftp.mkdir(path)
            else:
                raise ValueError(
                    'Cannot write into sub-directory with disabled mkdir option.'
                )

        # just the code from paramiko.SFTPClient.open
        imode = 0
        if ('r' in mode) or ('+' in mode):
            imode |= paramiko.sftp.SFTP_FLAG_READ
        if ('w' in mode) or ('+' in mode) or ('a' in mode):
            imode |= paramiko.sftp.SFTP_FLAG_WRITE
        if 'w' in mode:
            imode |= paramiko.sftp.SFTP_FLAG_CREATE | paramiko.sftp.SFTP_FLAG_TRUNC
        if 'a' in mode:
            imode |= paramiko.sftp.SFTP_FLAG_CREATE | paramiko.sftp.SFTP_FLAG_APPEND
        if 'x' in mode:
            imode |= paramiko.sftp.SFTP_FLAG_CREATE | paramiko.sftp.SFTP_FLAG_EXCL
        attrblock = paramiko.SFTPAttributes()
        t, msg = self._sftp._request(paramiko.sftp.CMD_OPEN, full_path, imode,
                                     attrblock)
        if t != paramiko.sftp.CMD_HANDLE:
            raise paramiko.SFTPError('Expected handle')
        handle = msg.get_binary()

        # init FileIO
        paramiko.SFTPFile.__init__(self, self._sftp, handle, mode, bufsize)
예제 #4
0
 def open(self, filename: Union[Text, bytes], mode: Text = 'r', bufsize: int = -1) -> SFTPFile:
     if self._sftp is None:
         raise paramiko.SFTPError("Expected handle")
     return self._sftp.open(filename, mode, bufsize)