mercurial/sshpeer.py
branchstable
changeset 48796 c00d3ce4e94b
parent 48526 04688c51f81f
child 48875 6000f5b25c9b
equal deleted inserted replaced
48776:b84ff512b645 48796:c00d3ce4e94b
    14 from .pycompat import getattr
    14 from .pycompat import getattr
    15 from . import (
    15 from . import (
    16     error,
    16     error,
    17     pycompat,
    17     pycompat,
    18     util,
    18     util,
    19     wireprotoserver,
       
    20     wireprototypes,
    19     wireprototypes,
    21     wireprotov1peer,
    20     wireprotov1peer,
    22     wireprotov1server,
    21     wireprotov1server,
    23 )
    22 )
    24 from .utils import (
    23 from .utils import (
   286     requestlog = ui.configbool(b'devel', b'debug.peer-request')
   285     requestlog = ui.configbool(b'devel', b'debug.peer-request')
   287 
   286 
   288     # Generate a random token to help identify responses to version 2
   287     # Generate a random token to help identify responses to version 2
   289     # upgrade request.
   288     # upgrade request.
   290     token = pycompat.sysbytes(str(uuid.uuid4()))
   289     token = pycompat.sysbytes(str(uuid.uuid4()))
   291     upgradecaps = [
       
   292         (b'proto', wireprotoserver.SSHV2),
       
   293     ]
       
   294     upgradecaps = util.urlreq.urlencode(upgradecaps)
       
   295 
   290 
   296     try:
   291     try:
   297         pairsarg = b'%s-%s' % (b'0' * 40, b'0' * 40)
   292         pairsarg = b'%s-%s' % (b'0' * 40, b'0' * 40)
   298         handshake = [
   293         handshake = [
   299             b'hello\n',
   294             b'hello\n',
   300             b'between\n',
   295             b'between\n',
   301             b'pairs %d\n' % len(pairsarg),
   296             b'pairs %d\n' % len(pairsarg),
   302             pairsarg,
   297             pairsarg,
   303         ]
   298         ]
   304 
       
   305         # Request upgrade to version 2 if configured.
       
   306         if ui.configbool(b'experimental', b'sshpeer.advertise-v2'):
       
   307             ui.debug(b'sending upgrade request: %s %s\n' % (token, upgradecaps))
       
   308             handshake.insert(0, b'upgrade %s %s\n' % (token, upgradecaps))
       
   309 
   299 
   310         if requestlog:
   300         if requestlog:
   311             ui.debug(b'devel-peer-request: hello+between\n')
   301             ui.debug(b'devel-peer-request: hello+between\n')
   312             ui.debug(b'devel-peer-request:   pairs: %d bytes\n' % len(pairsarg))
   302             ui.debug(b'devel-peer-request:   pairs: %d bytes\n' % len(pairsarg))
   313         ui.debug(b'sending hello command\n')
   303         ui.debug(b'sending hello command\n')
   363             # Look for response to ``hello`` command. Scan from the back so
   353             # Look for response to ``hello`` command. Scan from the back so
   364             # we don't misinterpret banner output as the command reply.
   354             # we don't misinterpret banner output as the command reply.
   365             if l.startswith(b'capabilities:'):
   355             if l.startswith(b'capabilities:'):
   366                 caps.update(l[:-1].split(b':')[1].split())
   356                 caps.update(l[:-1].split(b':')[1].split())
   367                 break
   357                 break
   368     elif protoname == wireprotoserver.SSHV2:
       
   369         # We see a line with number of bytes to follow and then a value
       
   370         # looking like ``capabilities: *``.
       
   371         line = stdout.readline()
       
   372         try:
       
   373             valuelen = int(line)
       
   374         except ValueError:
       
   375             badresponse()
       
   376 
       
   377         capsline = stdout.read(valuelen)
       
   378         if not capsline.startswith(b'capabilities: '):
       
   379             badresponse()
       
   380 
       
   381         ui.debug(b'remote: %s\n' % capsline)
       
   382 
       
   383         caps.update(capsline.split(b':')[1].split())
       
   384         # Trailing newline.
       
   385         stdout.read(1)
       
   386 
   358 
   387     # Error if we couldn't find capabilities, this means:
   359     # Error if we couldn't find capabilities, this means:
   388     #
   360     #
   389     # 1. Remote isn't a Mercurial server
   361     # 1. Remote isn't a Mercurial server
   390     # 2. Remote is a <0.9.1 Mercurial server
   362     # 2. Remote is a <0.9.1 Mercurial server
   599             self._pipeo.flush()
   571             self._pipeo.flush()
   600         if self._autoreadstderr:
   572         if self._autoreadstderr:
   601             self._readerr()
   573             self._readerr()
   602 
   574 
   603 
   575 
   604 class sshv2peer(sshv1peer):
       
   605     """A peer that speakers version 2 of the transport protocol."""
       
   606 
       
   607     # Currently version 2 is identical to version 1 post handshake.
       
   608     # And handshake is performed before the peer is instantiated. So
       
   609     # we need no custom code.
       
   610 
       
   611 
       
   612 def makepeer(ui, path, proc, stdin, stdout, stderr, autoreadstderr=True):
   576 def makepeer(ui, path, proc, stdin, stdout, stderr, autoreadstderr=True):
   613     """Make a peer instance from existing pipes.
   577     """Make a peer instance from existing pipes.
   614 
   578 
   615     ``path`` and ``proc`` are stored on the eventual peer instance and may
   579     ``path`` and ``proc`` are stored on the eventual peer instance and may
   616     not be used for anything meaningful.
   580     not be used for anything meaningful.
   629         _cleanuppipes(ui, stdout, stdin, stderr, warn=None)
   593         _cleanuppipes(ui, stdout, stdin, stderr, warn=None)
   630         raise
   594         raise
   631 
   595 
   632     if protoname == wireprototypes.SSHV1:
   596     if protoname == wireprototypes.SSHV1:
   633         return sshv1peer(
   597         return sshv1peer(
   634             ui,
       
   635             path,
       
   636             proc,
       
   637             stdin,
       
   638             stdout,
       
   639             stderr,
       
   640             caps,
       
   641             autoreadstderr=autoreadstderr,
       
   642         )
       
   643     elif protoname == wireprototypes.SSHV2:
       
   644         return sshv2peer(
       
   645             ui,
   598             ui,
   646             path,
   599             path,
   647             proc,
   600             proc,
   648             stdin,
   601             stdin,
   649             stdout,
   602             stdout,