def start_subsystem(self, name, transport, channel):
     self.sock = channel
     self._log(DEBUG, 'Started sftp server on channel %s' % repr(channel))
     self._send_server_version()
     self.server.session_started()
     while True:
         try:
             t, data = self._read_packet()
         except EOFError:
             self._log(DEBUG, 'EOF -- end of session')
             return
         except Exception as e:
             self._log(DEBUG, 'Exception on channel: ' + str(e))
             self._log(DEBUG, util.tb_strings())
             return
         msg = Message(data)
         request_number = msg.get_int()
         try:
             self._process(t, request_number, msg)
         except Exception as e:
             self._log(DEBUG, 'Exception in server processing: ' + str(e))
             self._log(DEBUG, util.tb_strings())
             # send some kind of failure message, at least
             try:
                 self._send_status(request_number, SFTP_FAILURE)
             except:
                 pass
Beispiel #2
0
 def start_subsystem(self, name, transport, channel):
     self.sock = channel
     self._log(DEBUG, 'Started sftp server on channel %s' % repr(channel))
     self._send_server_version()
     self.server.session_started()
     while True:
         try:
             t, data = self._read_packet()
         except EOFError:
             self._log(DEBUG, 'EOF -- end of session')
             return
         except Exception as e:
             self._log(ERROR, 'Exception on channel: ' + str(e))
             return
         msg = Message(data)
         request_number = msg.get_int()
         try:
             self._process(t, request_number, msg)
         except Exception as e:
             self._log(ERROR, 'Exception in server processing: ' + str(e))
             # send some kind of failure message, at least
             try:
                 self._send_status(request_number, SFTP_FAILURE)
             except:
                 pass
Beispiel #3
0
    def _check_file(self, request_number, msg):
        # this extension actually comes from v6 protocol, but since it's an
        # extension, i feel like we can reasonably support it backported.
        # it's very useful for verifying uploaded files or checking for
        # rsync-like differences between local and remote files.
        handle = msg.get_binary()
        alg_list = msg.get_list()
        start = msg.get_int64()
        length = msg.get_int64()
        block_size = msg.get_int()
        if handle not in self.file_table:
            self._send_status(request_number, SFTP_BAD_MESSAGE, 'Invalid handle')
            return
        f = self.file_table[handle]
        for x in alg_list:
            if x in _hash_class:
                algname = x
                alg = _hash_class[x]
                break
        else:
            self._send_status(request_number, SFTP_FAILURE, 'No supported hash types found')
            return
        if length == 0:
            st = f.stat()
            if not issubclass(type(st), SFTPAttributes):
                self._send_status(request_number, st, 'Unable to stat file')
                return
            length = st.st_size - start
        if block_size == 0:
            block_size = length
        if block_size < 256:
            self._send_status(request_number, SFTP_FAILURE, 'Block size too small')
            return

        sum_out = bytes()
        offset = start
        while offset < start + length:
            blocklen = min(block_size, start + length - offset)
            # don't try to read more than about 64KB at a time
            chunklen = min(blocklen, 65536)
            count = 0
            hash_obj = alg.new()
            while count < blocklen:
                data = f.read(offset, chunklen)
                if not isinstance(data, bytes_types):
                    self._send_status(request_number, data, 'Unable to hash file')
                    return
                hash_obj.update(data)
                count += len(data)
                offset += count
            sum_out += hash_obj.digest()

        msg = Message()
        msg.add_int(request_number)
        msg.add_string('check-file')
        msg.add_string(algname)
        msg.add_bytes(sum_out)
        self._send_packet(CMD_EXTENDED_REPLY, msg)
Beispiel #4
0
    def _check_file(self, request_number, msg):
        # this extension actually comes from v6 protocol, but since it's an
        # extension, i feel like we can reasonably support it backported.
        # it's very useful for verifying uploaded files or checking for
        # rsync-like differences between local and remote files.
        handle = msg.get_binary()
        alg_list = msg.get_list()
        start = msg.get_int64()
        length = msg.get_int64()
        block_size = msg.get_int()
        if handle not in self.file_table:
            self._send_status(request_number, SFTP_BAD_MESSAGE, 'Invalid handle')
            return
        f = self.file_table[handle]
        for x in alg_list:
            if x in _hash_class:
                algname = x
                alg = _hash_class[x]
                break
        else:
            self._send_status(request_number, SFTP_FAILURE, 'No supported hash types found')
            return
        if length == 0:
            st = f.stat()
            if not issubclass(type(st), SFTPAttributes):
                self._send_status(request_number, st, 'Unable to stat file')
                return
            length = st.st_size - start
        if block_size == 0:
            block_size = length
        if block_size < 256:
            self._send_status(request_number, SFTP_FAILURE, 'Block size too small')
            return

        sum_out = bytes()
        offset = start
        while offset < start + length:
            blocklen = min(block_size, start + length - offset)
            # don't try to read more than about 64KB at a time
            chunklen = min(blocklen, 65536)
            count = 0
            hash_obj = alg()
            while count < blocklen:
                data = f.read(offset, chunklen)
                if not isinstance(data, bytes_types):
                    self._send_status(request_number, data, 'Unable to hash file')
                    return
                hash_obj.update(data)
                count += len(data)
                offset += count
            sum_out += hash_obj.digest()

        msg = Message()
        msg.add_int(request_number)
        msg.add_string('check-file')
        msg.add_string(algname)
        msg.add_bytes(sum_out)
        self._send_packet(CMD_EXTENDED_REPLY, msg)
 def _read_folder(self, request_number, folder):
     flist = folder._get_next_files()
     if len(flist) == 0:
         self._send_status(request_number, SFTP_EOF)
         return
     msg = Message()
     msg.add_int(request_number)
     msg.add_int(len(flist))
     for attr in flist:
         msg.add_string(attr.filename)
         msg.add_string(attr)
         attr._pack(msg)
     self._send_packet(CMD_NAME, msg)
Beispiel #6
0
 def _response(self, request_number, t, *arg):
     msg = Message()
     msg.add_int(request_number)
     for item in arg:
         if isinstance(item, long):
             msg.add_int64(item)
         elif isinstance(item, int):
             msg.add_int(item)
         elif isinstance(item, (string_types, bytes_types)):
             msg.add_string(item)
         elif type(item) is SFTPAttributes:
             item._pack(msg)
         else:
             raise Exception('unknown type for ' + repr(item) + ' type ' + repr(type(item)))
     self._send_packet(t, msg)
Beispiel #7
0
 def _read_folder(self, request_number, folder):
     flist = folder._get_next_files()
     if len(flist) == 0:
         self._send_status(request_number, SFTP_EOF)
         return
     msg = Message()
     msg.add_int(request_number)
     msg.add_int(len(flist))
     for attr in flist:
         msg.add_string(attr.filename)
         msg.add_string(attr)
         attr._pack(msg)
     self._send_packet(CMD_NAME, msg)
Beispiel #8
0
 def _response(self, request_number, t, *arg):
     msg = Message()
     msg.add_int(request_number)
     for item in arg:
         if isinstance(item, long):
             msg.add_int64(item)
         elif isinstance(item, int):
             msg.add_int(item)
         elif isinstance(item, (string_types, bytes_types)):
             msg.add_string(item)
         elif type(item) is SFTPAttributes:
             item._pack(msg)
         else:
             raise Exception('unknown type for ' + repr(item) + ' type ' + repr(type(item)))
     self._send_packet(t, msg)