~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/ssh.py

merge 2.0 branch rev 4647

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 
20
20
import errno
21
21
import getpass
 
22
import logging
22
23
import os
23
24
import socket
24
25
import subprocess
122
123
        elif 'SSH Secure Shell' in version:
123
124
            trace.mutter('ssh implementation is SSH Corp.')
124
125
            vendor = SSHCorpSubprocessVendor()
125
 
        elif 'plink' in version and args[0] == 'plink':
126
 
            # Checking if "plink" was the executed argument as Windows
127
 
            # sometimes reports 'ssh -V' incorrectly with 'plink' in it's
128
 
            # version.  See https://bugs.launchpad.net/bzr/+bug/107155
129
 
            trace.mutter("ssh implementation is Putty's plink.")
130
 
            vendor = PLinkSubprocessVendor()
 
126
        # Auto-detect of plink vendor disabled, on Windows recommended
 
127
        # default ssh-client is paramiko
 
128
        # see https://bugs.launchpad.net/bugs/414743
 
129
        #~elif 'plink' in version and args[0] == 'plink':
 
130
        #~    # Checking if "plink" was the executed argument as Windows
 
131
        #~    # sometimes reports 'ssh -V' incorrectly with 'plink' in it's
 
132
        #~    # version.  See https://bugs.launchpad.net/bzr/+bug/107155
 
133
        #~    trace.mutter("ssh implementation is Putty's plink.")
 
134
        #~    vendor = PLinkSubprocessVendor()
131
135
        return vendor
132
136
 
133
137
    def _get_vendor_by_inspection(self):
481
485
    if _try_pkey_auth(paramiko_transport, paramiko.DSSKey, username, 'id_dsa'):
482
486
        return
483
487
 
 
488
    # If we have gotten this far, we are about to try for passwords, do an
 
489
    # auth_none check to see if it is even supported.
 
490
    supported_auth_types = []
 
491
    try:
 
492
        # Note that with paramiko <1.7.5 this logs an INFO message:
 
493
        #    Authentication type (none) not permitted.
 
494
        # So we explicitly disable the logging level for this action
 
495
        old_level = paramiko_transport.logger.level
 
496
        paramiko_transport.logger.setLevel(logging.WARNING)
 
497
        try:
 
498
            paramiko_transport.auth_none(username)
 
499
        finally:
 
500
            paramiko_transport.logger.setLevel(old_level)
 
501
    except paramiko.BadAuthenticationType, e:
 
502
        # Supported methods are in the exception
 
503
        supported_auth_types = e.allowed_types
 
504
    except paramiko.SSHException, e:
 
505
        # Don't know what happened, but just ignore it
 
506
        pass
 
507
    if 'password' not in supported_auth_types:
 
508
        raise errors.ConnectionError('Unable to authenticate to SSH host as'
 
509
            '\n  %s@%s\nsupported auth types: %s'
 
510
            % (username, host, supported_auth_types))
 
511
 
484
512
    if password:
485
513
        try:
486
514
            paramiko_transport.auth_password(username, password)
490
518
 
491
519
    # give up and ask for a password
492
520
    password = auth.get_password('ssh', host, username, port=port)
493
 
    try:
494
 
        paramiko_transport.auth_password(username, password)
495
 
    except paramiko.SSHException, e:
496
 
        raise errors.ConnectionError(
497
 
            'Unable to authenticate to SSH host as %s@%s' % (username, host), e)
 
521
    # get_password can still return None, which means we should not prompt
 
522
    if password is not None:
 
523
        try:
 
524
            paramiko_transport.auth_password(username, password)
 
525
        except paramiko.SSHException, e:
 
526
            raise errors.ConnectionError(
 
527
                'Unable to authenticate to SSH host as'
 
528
                '\n  %s@%s\n' % (username, host), e)
 
529
    else:
 
530
        raise errors.ConnectionError('Unable to authenticate to SSH host as'
 
531
                                     '  %s@%s' % (username, host))
498
532
 
499
533
 
500
534
def _try_pkey_auth(paramiko_transport, pkey_class, username, filename):