'Can you pass a file like object as a parameter to pysftp.CnOpts in Python [duplicate]
I have a Python script that uses pysftp to create an SFTP connection to a remote host as shown:
cnopts = pysftp.CnOpts(knownhosts='known_hosts') # REFERENCE A STATIC FILE
sftp = pysftp.Connection(host=parm0, username=parm1, password=parm2, cnopts=cnopts)
The file "known_hosts" lives in the same directory where the Python script lives. I would like to eliminate the static know_hosts file and pass a file like object to pysftp.CnOpts() like this:
remote_public_key = subprocess.getoutput('ssh-keyscan myRemoteSFTPServer.com')
key_buffer.write(remote_public_key)
key_buffer.seek(0)
cnopts = pysftp.CnOpts(knownhosts=key_buffer.read()) # REFERENCE A FILE LIKE OBJECT
sftp = pysftp.Connection(host=parm0, username=parm1, password=parm2, cnopts=cnopts)
However, this fails. Is it possible to pass a file like object as a parameter to pysftp.CnOpts, and if so, how do I do it?
Solution 1:[1]
Did you try
cnopts = pysftp.CnOpts(knownhosts=key_buffer)
to just pass in the file-like object? If you do key_buffer.read(), that'd be equivalent to
cnopts = pysftp.CnOpts(knownhosts="# 127.0.0.1:22 SSH-2.0-OpenSSH_8.1...")
or whatever is in the buffer, and pysftp would likely try to interpret that as a filename.
Failing that,
with tempfile.NamedTemporaryFile("wb") as key_buffer:
remote_public_key = subprocess.getoutput('ssh-keyscan myRemoteSFTPServer.com')
key_buffer.write(remote_public_key)
key_buffer.seek(0)
cnopts = pysftp.CnOpts(knownhosts=key_buffer.name)
sftp = pysftp.Connection(host=parm0, username=parm1, password=parm2, cnopts=cnopts)
(NamedTemporaryFiles are automagically deleted at the end of the with block.)
Solution 2:[2]
Thanks @AKX. I ended up rewriting my Python script to use Paramiko instead of pysftp and have a working solution. First I created a function called get_remote Server_key to generate an SSH key. Then I called the add_server_key(pkey) method of the Paramiko Transport object. This way I don't have to pass a file like object.
def get_remote_server_key(ip: str, port: int=22) -> paramiko.pkey.PKey:
# Returns PKey for given server
# :param ip: IP or Hostname
# :param port: Port
# :return: Returns PKey
my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
my_socket.settimeout(10)
my_socket.connect((ip, port))
my_transport = paramiko.Transport(my_socket)
my_transport.start_client()
ssh_key = my_transport.get_remote_server_key()
my_transport.close()
my_socket.close()
return ssh_key
def getSFTPConnection(server, port, uid, pw):
client = paramiko.SSHClient()
**pkey = get_remote_server_key(server,port)**
trans = paramiko.Transport((server, port))
**trans.add_server_key(pkey)**
trans.connect(username=uid, password=pw)
sftp = paramiko.SFTPClient.from_transport(trans)
return sftp
sftp=getSFTPConnection(server, port, uid, password)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | AKX |
| Solution 2 | CentennialJim |
