~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/ssh.py

  • Committer: John Arbash Meinel
  • Date: 2008-09-09 15:09:12 UTC
  • mto: This revision was merged to the branch mainline in revision 3699.
  • Revision ID: john@arbash-meinel.com-20080909150912-wyttm8he1zsls2ck
Use the right timing function on win32

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
#
14
14
# You should have received a copy of the GNU General Public License
15
15
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
17
 
18
18
"""Foundation SSH support for SFTP and smart server."""
19
19
 
20
20
import errno
21
21
import getpass
22
 
import logging
23
22
import os
24
23
import socket
25
24
import subprocess
123
122
        elif 'SSH Secure Shell' in version:
124
123
            trace.mutter('ssh implementation is SSH Corp.')
125
124
            vendor = SSHCorpSubprocessVendor()
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()
 
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()
135
131
        return vendor
136
132
 
137
133
    def _get_vendor_by_inspection(self):
184
180
 
185
181
    def get_name(self):
186
182
        return "bzr SocketAsChannelAdapter"
187
 
 
 
183
    
188
184
    def send(self, data):
189
185
        return self.__socket.send(data)
190
186
 
215
211
 
216
212
    def connect_sftp(self, username, password, host, port):
217
213
        """Make an SSH connection, and return an SFTPClient.
218
 
 
 
214
        
219
215
        :param username: an ascii string
220
216
        :param password: an ascii string
221
217
        :param host: a host name as an ascii string
230
226
 
231
227
    def connect_ssh(self, username, password, host, port, command):
232
228
        """Make an SSH connection.
233
 
 
 
229
        
234
230
        :returns: something with a `close` method, and a `get_filelike_channels`
235
231
            method that returns a pair of (read, write) filelike objects.
236
232
        """
395
391
    def _get_vendor_specific_argv(self, username, host, port, subsystem=None,
396
392
                                  command=None):
397
393
        """Returns the argument list to run the subprocess with.
398
 
 
 
394
        
399
395
        Exactly one of 'subsystem' and 'command' must be specified.
400
396
        """
401
397
        raise NotImplementedError(self._get_vendor_specific_argv)
462
458
 
463
459
 
464
460
def _paramiko_auth(username, password, host, port, paramiko_transport):
 
461
    # paramiko requires a username, but it might be none if nothing was supplied
 
462
    # use the local username, just in case.
 
463
    # We don't override username, because if we aren't using paramiko,
 
464
    # the username might be specified in ~/.ssh/config and we don't want to
 
465
    # force it to something else
 
466
    # Also, it would mess up the self.relpath() functionality
465
467
    auth = config.AuthenticationConfig()
466
 
    # paramiko requires a username, but it might be none if nothing was
467
 
    # supplied.  If so, use the local username.
468
468
    if username is None:
469
 
        username = auth.get_user('ssh', host, port=port,
470
 
                                 default=getpass.getuser())
 
469
        username = auth.get_user('ssh', host, port=port)
 
470
        if username is None:
 
471
            # Default to local user
 
472
            username = getpass.getuser()
 
473
 
471
474
    if _use_ssh_agent:
472
475
        agent = paramiko.Agent()
473
476
        for key in agent.get_keys():
485
488
    if _try_pkey_auth(paramiko_transport, paramiko.DSSKey, username, 'id_dsa'):
486
489
        return
487
490
 
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
 
 
512
491
    if password:
513
492
        try:
514
493
            paramiko_transport.auth_password(username, password)
518
497
 
519
498
    # give up and ask for a password
520
499
    password = auth.get_password('ssh', host, username, port=port)
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))
 
500
    try:
 
501
        paramiko_transport.auth_password(username, password)
 
502
    except paramiko.SSHException, e:
 
503
        raise errors.ConnectionError(
 
504
            'Unable to authenticate to SSH host as %s@%s' % (username, host), e)
532
505
 
533
506
 
534
507
def _try_pkey_auth(paramiko_transport, pkey_class, username, filename):
596
569
def os_specific_subprocess_params():
597
570
    """Get O/S specific subprocess parameters."""
598
571
    if sys.platform == 'win32':
599
 
        # setting the process group and closing fds is not supported on
 
572
        # setting the process group and closing fds is not supported on 
600
573
        # win32
601
574
        return {}
602
575
    else:
603
 
        # We close fds other than the pipes as the child process does not need
 
576
        # We close fds other than the pipes as the child process does not need 
604
577
        # them to be open.
605
578
        #
606
579
        # We also set the child process to ignore SIGINT.  Normally the signal
608
581
        # this causes it to be seen only by bzr and not by ssh.  Python will
609
582
        # generate a KeyboardInterrupt in bzr, and we will then have a chance
610
583
        # to release locks or do other cleanup over ssh before the connection
611
 
        # goes away.
 
584
        # goes away.  
612
585
        # <https://launchpad.net/products/bzr/+bug/5987>
613
586
        #
614
587
        # Running it in a separate process group is not good because then it