-
Notifications
You must be signed in to change notification settings - Fork 138
Open
Labels
Description
Hi,
I added some logging, and to my understanding of the protocol, scp.py is sending an extra \x00 in _recv_all:
DEBUG:paramiko.transport:Secsh channel 0 opened.
DEBUG:paramiko.transport:[chan 0] [chan 0] Executing command: b'scp -f file'
DEBUG:paramiko.transport:[chan 0] Sesch channel 0 request ok
DEBUG:paramiko.transport:[chan 0] [chan 0] sendall: b'\x00' <= here
DEBUG:paramiko.transport:[chan 0] [chan 0] recv: b'C0644 1234 file\n'
DEBUG:paramiko.transport:[chan 0] [chan 0] send: b'\x00'
DEBUG:paramiko.transport:[chan 0] [chan 0] recv: b'file content'
DEBUG:paramiko.transport:[chan 0] [chan 0] recv: b'\x00'
DEBUG:paramiko.transport:[chan 0] [chan 0] sendall: b'\x00'
DEBUG:paramiko.transport:[chan 0] [chan 0] recv: b'\x00\x00\x00\x00'
The send_all call in _recv_all is sending an ack in response to the file metadata, then _recv_file resend this ack for the metadata, that'll be interpreted as an ack to the file reception.
I have not tested, but it seems to be one of the things fixed in #29.
Using this script:
import paramiko
import scp
import io
import logging
logging.basicConfig(level=logging.DEBUG)
client = paramiko.SSHClient()
client .set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(...)
channel = client.get_transport().open_session()
channel.exec_command('scp -v -f file')
# scp.py sends an extra \x00 here
# Read first response: C0644 1234 file\n
scp_cmd = channel.recv(1024)[:-1]
file_length = int(scp_cmd.strip().split(b' ', 2)[1])
# Ack command
channel.sendall(b'\x00')
# Read response (response + \x00)
file = io.BytesIO()
while file.tell() < file_length:
file.write(channel.recv(min(1024, file_length - file.tell())))
if channel.recv(1) != b'\x00':
raise Exception(channel.recv(512).decode('utf-8', 'replace'))
channel.sendall(b'\x00')I get:
DEBUG:paramiko.transport:[chan 0] [chan 0] Executing command: scp -v -f file
DEBUG:paramiko.transport:[chan 0] Sesch channel 0 request ok
DEBUG:paramiko.transport:[chan 0] [chan 0] recv: b'C0644 1234 file\n'
DEBUG:paramiko.transport:[chan 0] [chan 0] sendall: b'\x00'
DEBUG:paramiko.transport:[chan 0] [chan 0] recv: b'file content'
DEBUG:paramiko.transport:[chan 0] [chan 0] recv: b'\x00'
DEBUG:paramiko.transport:[chan 0] [chan 0] sendall: b'\x00'