Retrieve scp errors
Yannik opened this issue · comments
I'm trying to use this lib with paramiko to push a config file to a fortigate. The fortigate has some validation logic to check if the config is valid or not.
Using openssh scp
, that looks like this:
$ scp -O config admin@fortigate:fgt-restore-config
admin@fortigate's password:
config 100% 293KB 1.4MB/s 00:00
500-Invalid config file
...and with -vvv
(shortened to the relevant parts):
Sending file modes: C0644 300109 config
config 0% 0 0.0KB/s --:-- ETA
scp: debug2: fd 6 setting O_NONBLOCK
scp: debug1: fd 6 clearing O_NONBLOCK
debug2: channel 0: rcvd adjust 98321
debug2: channel 0: rcvd adjust 131072
config 100% 293KB 1.5MB/s 00:00
debug2: channel 0: read<=0 rfd 4 len 0
debug2: channel 0: read failed
debug2: chan_shutdown_read: channel 0: (i0 o0 sock -1 wfd 4 efd 6 [write])
debug2: channel 0: input open -> drain
debug2: channel 0: ibuf empty
debug2: channel 0: send eof
debug2: channel 0: input drain -> closed
debug2: channel 0: rcvd ext data 24
500-Invalid config file
I need to read the 500-Invalid config file
output to validate whether the config push was successful or not.
I tried playing around with reading from self.channel.makefile()
and self.channel.makefile_stderr()
and with self.channel.recv()
, but had no success at all.
@remram44 Do you have any idea how I could achieve this?
scp is supposed to show those, see _recv_confirm()
. Do you get a different error?
@remram44 I get no errors at all, unfortunately.
Printing the msg
in _recv_confirm()
like this:
def _recv_confirm(self):
# read scp response
msg = b''
try:
msg = self.channel.recv(512)
print(msg)
shows
b'\x00'
b'\x00'
b'\x00'
You mean that the transfer succeeds either way (scp returns 0) but it prints this message?
You can try scp.channel.recv_stderr()
openssh scp indeed has an 0 exit code. (even though the error message is printed)
Calling scp.channel.recv_stderr()
where scp
is a SCPClient
results in an AttributeError: 'NoneType' object has no attribute 'recv_stderr'
, presumably because putting a file closes the channel.
Modifying putfo
directly to call print(scp.channel.recv_stderr(512))
after the self._send_file(fl, remote_path, mode, size=size)
line results in a timeout error.
@remram44 the same (TimeoutError) occurs when calling self.channel.recv(512)
instead of scp.channel.recv_stderr(512)
.
I have tried to sleep for a few seconds before calling these to make sure the other side had time to send the message, but that did not result in any change either.
Ok I don't know how this message is sent then, sorry.