Mercurial > public > mercurial-scm > hg
comparison mercurial/sshpeer.py @ 35978:59e4a7781a36
sshpeer: implement peer for version 2 of wire protocol
Since the protocol is now negotiated before we construct a
peer instance, we can return the negotiated protocol from the
handshake function and instantiate an appropriate peer class
for the protocol.
Version 2 of the SSH protocol is currently identical to version
1 post handshake. So our sshv2peer class just inherits from
sshv1peer for the time being. This will obviously change
over time.
Differential Revision: https://phab.mercurial-scm.org/D2063
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Tue, 06 Feb 2018 11:31:25 -0800 |
parents | 625038cb4b1d |
children | 223ed0b53f08 |
comparison
equal
deleted
inserted
replaced
35977:625038cb4b1d | 35978:59e4a7781a36 |
---|---|
324 # 3. Remote is a future Mercurial server that dropped ``hello`` | 324 # 3. Remote is a future Mercurial server that dropped ``hello`` |
325 # and other attempted handshake mechanisms. | 325 # and other attempted handshake mechanisms. |
326 if not caps: | 326 if not caps: |
327 badresponse() | 327 badresponse() |
328 | 328 |
329 return caps | 329 return protoname, caps |
330 | 330 |
331 class sshv1peer(wireproto.wirepeer): | 331 class sshv1peer(wireproto.wirepeer): |
332 def __init__(self, ui, url, proc, stdin, stdout, stderr, caps): | 332 def __init__(self, ui, url, proc, stdin, stdout, stderr, caps): |
333 """Create a peer from an existing SSH connection. | 333 """Create a peer from an existing SSH connection. |
334 | 334 |
495 self._pipeo.write(data) | 495 self._pipeo.write(data) |
496 if flush: | 496 if flush: |
497 self._pipeo.flush() | 497 self._pipeo.flush() |
498 self._readerr() | 498 self._readerr() |
499 | 499 |
500 class sshv2peer(sshv1peer): | |
501 """A peer that speakers version 2 of the transport protocol.""" | |
502 # Currently version 2 is identical to version 1 post handshake. | |
503 # And handshake is performed before the peer is instantiated. So | |
504 # we need no custom code. | |
505 | |
500 def instance(ui, path, create): | 506 def instance(ui, path, create): |
501 """Create an SSH peer. | 507 """Create an SSH peer. |
502 | 508 |
503 The returned object conforms to the ``wireproto.wirepeer`` interface. | 509 The returned object conforms to the ``wireproto.wirepeer`` interface. |
504 """ | 510 """ |
530 | 536 |
531 proc, stdin, stdout, stderr = _makeconnection(ui, sshcmd, args, remotecmd, | 537 proc, stdin, stdout, stderr = _makeconnection(ui, sshcmd, args, remotecmd, |
532 remotepath, sshenv) | 538 remotepath, sshenv) |
533 | 539 |
534 try: | 540 try: |
535 caps = _performhandshake(ui, stdin, stdout, stderr) | 541 protoname, caps = _performhandshake(ui, stdin, stdout, stderr) |
536 except Exception: | 542 except Exception: |
537 _cleanuppipes(ui, stdout, stdin, stderr) | 543 _cleanuppipes(ui, stdout, stdin, stderr) |
538 raise | 544 raise |
539 | 545 |
540 return sshv1peer(ui, path, proc, stdin, stdout, stderr, caps) | 546 if protoname == wireprotoserver.SSHV1: |
547 return sshv1peer(ui, path, proc, stdin, stdout, stderr, caps) | |
548 elif protoname == wireprotoserver.SSHV2: | |
549 return sshv2peer(ui, path, proc, stdin, stdout, stderr, caps) | |
550 else: | |
551 _cleanuppipes(ui, stdout, stdin, stderr) | |
552 raise error.RepoError(_('unknown version of SSH protocol: %s') % | |
553 protoname) |