def _get_size(self, client: FtpClient, filename): if client.has_size_command(): text = client.execute("size {}".format(filename)).text.strip() parsed, value = try_parse_int(text) if parsed: return value return None
def _upload_port(self, client: FtpClient): data = self._get_data_to_upload() out_file_name = self._get_out_file_name() if data is None: return address = self._entry_port(client) if address is None: return if address == 'external': reply = client.execute( f'stor {out_file_name}', lambda x: self.environment.writer.write(x.text), timeout=None) self.environment.writer.write(reply.text) return server = address def upload(a): with server, server.accept() as con: uploader.upload(con, data, writer=self.environment.writer) reply = client.execute(f'stor {out_file_name}', upload, timeout=None) self.environment.writer.write(reply.text)
def __get_external_server(self, client: FtpClient): address = self.environment.reader.read_next_command('Enter receiver address (in FTP format): ') if not self.environment.is_ipv6_mode: reply = client.execute(f'port {address}') else: reply = client.execute(f'eprt {address}') if reply.status_code != StatusCode.COMMAND_OK.value: self.environment.writer.write(f'port command returned code {reply.status_code} with text {reply.text}', is_error=True) return None return 'external'
def execute(self, client: FtpClient): username = self.get_argument('user') if self.has_argument( 'user') else _get_user(self.environment) password = self.get_argument('password') if self.has_argument( 'password') else _get_password(self.environment) user_reply = client.execute('user {}'.format(username)) if user_reply.status_code != StatusCode.USER_OKAY_NEED_PASSWORD.value: self.environment.writer.write(user_reply.text) return password_reply = client.execute('pass {}'.format(password)) self.environment.writer.write(password_reply.text)
def get_client(timeout): address, is_ipv6, script = parse_args() factory = CommandFactory() environment = EnvironmentBuilder().build(factory.commands, is_ipv6, script) tcp_connection = TcpConnection(address, timeout) client = FtpClient(tcp_connection) return client, environment, factory
def __get_server_with_current_machine(self, client: FtpClient): if self.environment.is_under_nat: self.environment.writer.write('Cant create server on machine under nat', is_error=True) return None server = TcpServer(ipv6_mode=self.environment.is_ipv6_mode, timeout=15) addr = server.listen() ftp_addr = addr.with_host(self.environment.machine_address) if server.is_ipv4: reply = client.execute(f'port {ftp_addr.ftp_address}') else: reply = client.execute(f'eprt {ftp_addr.ftp_extendend_address}') if reply.status_code == StatusCode.COMMAND_OK.value: return server server.close() self.environment.writer.write(f'port command returned code {reply.status_code} with text {reply.text}', is_error=True) return None
def _entry_pasv_6(self, client: FtpClient): reply = client.execute("epsv") if reply.is_success_reply: port = extract_address_from_text_6(reply.text) addr = client.connection.peer_address.with_port(port) return addr self.environment.writer.write(reply.text) return None
def _entry_pasv(self, client: FtpClient): if self.environment.is_ipv6_mode: return self._entry_pasv_6(client) pasv_reply = client.execute('pasv') if pasv_reply.status_code == StatusCode.ENTERING_PASSIVE_MODE.value: return extract_address_from_text(pasv_reply.text) self.environment.writer.write(pasv_reply.text) return None
def execute(self, client: FtpClient): r = client.execute('type i') if not r.is_success_reply: self.environment.writer.write(r.text, is_error=True) return if self.environment.connection_mode == ConnectionMode.PASSIVE: self._execute_passive(client) else: self._execute_port(client)
def _pasv_download(self, connection: Connection, client: FtpClient, remote_name, local_name, start_offset=0, mode='I', cmd='retr'): set_type_reply = client.execute(f'type {mode}') if not set_type_reply.is_success_reply: self.environment.writer.write(set_type_reply.text, is_error=True) return if mode == 'I': self._pasv_download_binary(connection, client, remote_name, local_name, start_offset, cmd) return raise NotImplementedError(f'Downloading at mode {mode} are not supported')
def _download_from_connection(self, connection: Connection, client: FtpClient, remote_name, local_name, file_mode, size, offset, cmd): def download(a): try: with connection, open(local_name, mode=file_mode) as file: downloader.download(connection, size, part_callback=lambda x: file.write(x), start=offset, writer=self.environment.writer) except IOError as e: self.environment.writer.write("io error: {}".format(e.strerror), is_error=True) reply = client.execute(f'{cmd} {remote_name}', download) self.environment.writer.write(reply.text)
def _upload_passive(self, client: FtpClient): data = self._get_data_to_upload() out_file_name = self._get_out_file_name() if data is None: return address = self._entry_pasv(client) if address is None: return connection = TcpConnection(address, 15) def upload_file(a): with connection: uploader.upload(connection, data, writer=self.environment.writer) reply = client.execute("STOR {}".format(out_file_name), upload_file) self.environment.writer.write(reply.text)
def _try_rest(self, client: FtpClient, offset): reply = client.execute(f"rest {offset}") self.environment.writer.write(reply.text) return reply.status_code == StatusCode.REQUESTED_FILE_ACTION_PENDING_INFO.value
def execute(self, client: FtpClient): self.environment.closed = True self.environment.writer.write(client.execute('quit').text)
def execute(self, client: FtpClient): self.environment.writer.write(client.execute('pwd').text)
def get_client(text): send_buffer.clear() return FtpClient(FakeConnection(text))