简体   繁体   中英

paramiko allows sftp connection without key

I was running the demo_sftp.py file from the demo folder in the paramiko github . I was stepping through it in PyDev and expected to get an error because I didn't have a key to the server I was trying to connect to but I got the print statement saying that the script couldn't open the host key file and then it went ahead and did the get and put.

Here's a code snippet.

try:
    host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
except IOError:
    try:
        # try ~/ssh/ too, because windows can't have a folder named ~/.ssh/
        host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/ssh/known_hosts'))
    except IOError:
        print '*** Unable to open host keys file'
        host_keys = {}

if host_keys.has_key(hostname):
    hostkeytype = host_keys[hostname].keys()[0]
    hostkey = host_keys[hostname][hostkeytype]
    print 'Using host key of type %s' % hostkeytype


# now, connect and use paramiko Transport to negotiate SSH2 across the connection
try:
    t = paramiko.Transport((hostname, port))
    t.connect(username=username, password=password, hostkey=hostkey)
    sftp = paramiko.SFTPClient.from_transport(t)

    # dirlist on remote host
    dirlist = sftp.listdir('.')
    print "Dirlist:", dirlist

I really expected it to go to the except on the t.connect line because hostkey is NoneType.

When I open an ssh connection with

    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    try:
        ssh.connect('.'.join([self.name, self.domain]),
                    username=self.username, password=self.password)
        stdin, stdout, stderr = ssh.exec_command("ps aux | grep Xvnc | wc -l")

I have to have the AutoAddPolicy() line or it fails. So what's the difference? Obviously I'm just learning this but I thought that sftp would be just as strict as ssh.

It looks like this is an acceptable practice.

Comment from Transport.connect

'''
Negotiate an SSH2 session, and optionally verify the server's host key
and authenticate using a password or private key.  This is a shortcut
for L{start_client}, L{get_remote_server_key}, and
L{Transport.auth_password} or L{Transport.auth_publickey}.  Use those
methods if you want more control.

You can use this method immediately after creating a Transport to
negotiate encryption with a server.  If it fails, an exception will be
thrown.  On success, the method will return cleanly, and an encrypted
session exists.  You may immediately call L{open_channel} or
L{open_session} to get a L{Channel} object, which is used for data
transfer.

@note: If you fail to supply a password or private key, this method may
succeed, but a subsequent L{open_channel} or L{open_session} call may
fail because you haven't authenticated yet.
'''

Comment from SSHClient.connect

'''
Connect to an SSH server and authenticate to it.  The server's host key
is checked against the system host keys (see L{load_system_host_keys})
and any local host keys (L{load_host_keys}).  If the server's hostname
is not found in either set of host keys, the missing host key policy
is used (see L{set_missing_host_key_policy}).  The default policy is
to reject the key and raise an L{SSHException}.
'''

Maybe it is due to the fact that sftp can only transport data while ssh can run terminal commands. I do find it interesting that a man-in-the-middle attack doesn't seem to be a concern.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM