To avoid a cycle between modules in an upcoming commit.
Details
Details
Diff Detail
Diff Detail
- Repository
- rHG Mercurial
- Lint
Automatic diff as part of commit; lint not applicable. - Unit
Automatic diff as part of commit; unit tests not applicable.
To avoid a cycle between modules in an upcoming commit.
| Automatic diff as part of commit; lint not applicable. |
| Automatic diff as part of commit; unit tests not applicable. |
| Path | Packages | |||
|---|---|---|---|---|
| M | mercurial/sshpeer.py (9 lines) | |||
| M | mercurial/wireprotoserver.py (11 lines) | |||
| M | mercurial/wireprototypes.py (6 lines) |
| Status | Author | Revision | |
|---|---|---|---|
| Abandoned | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Abandoned | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg | ||
| Closed | indygreg |
| from .i18n import _ | from .i18n import _ | ||||
| from . import ( | from . import ( | ||||
| error, | error, | ||||
| pycompat, | pycompat, | ||||
| util, | util, | ||||
| wireproto, | wireproto, | ||||
| wireprotoserver, | wireprotoserver, | ||||
| wireprototypes, | |||||
| ) | ) | ||||
| def _serverquote(s): | def _serverquote(s): | ||||
| """quote a string for the remote shell ... which we assume is sh""" | """quote a string for the remote shell ... which we assume is sh""" | ||||
| if not s: | if not s: | ||||
| return s | return s | ||||
| if re.match('[a-zA-Z0-9@%_+=:,./-]*$', s): | if re.match('[a-zA-Z0-9@%_+=:,./-]*$', s): | ||||
| return s | return s | ||||
| ui.debug('sending between command\n') | ui.debug('sending between command\n') | ||||
| stdin.write(''.join(handshake)) | stdin.write(''.join(handshake)) | ||||
| stdin.flush() | stdin.flush() | ||||
| except IOError: | except IOError: | ||||
| badresponse() | badresponse() | ||||
| # Assume version 1 of wire protocol by default. | # Assume version 1 of wire protocol by default. | ||||
| protoname = wireprotoserver.SSHV1 | protoname = wireprototypes.SSHV1 | ||||
| reupgraded = re.compile(b'^upgraded %s (.*)$' % re.escape(token)) | reupgraded = re.compile(b'^upgraded %s (.*)$' % re.escape(token)) | ||||
| lines = ['', 'dummy'] | lines = ['', 'dummy'] | ||||
| max_noise = 500 | max_noise = 500 | ||||
| while lines[-1] and max_noise: | while lines[-1] and max_noise: | ||||
| try: | try: | ||||
| l = stdout.readline() | l = stdout.readline() | ||||
| _forwardoutput(ui, stderr) | _forwardoutput(ui, stderr) | ||||
| badresponse() | badresponse() | ||||
| else: | else: | ||||
| badresponse() | badresponse() | ||||
| caps = set() | caps = set() | ||||
| # For version 1, we should see a ``capabilities`` line in response to the | # For version 1, we should see a ``capabilities`` line in response to the | ||||
| # ``hello`` command. | # ``hello`` command. | ||||
| if protoname == wireprotoserver.SSHV1: | if protoname == wireprototypes.SSHV1: | ||||
| for l in reversed(lines): | for l in reversed(lines): | ||||
| # Look for response to ``hello`` command. Scan from the back so | # Look for response to ``hello`` command. Scan from the back so | ||||
| # we don't misinterpret banner output as the command reply. | # we don't misinterpret banner output as the command reply. | ||||
| if l.startswith('capabilities:'): | if l.startswith('capabilities:'): | ||||
| caps.update(l[:-1].split(':')[1].split()) | caps.update(l[:-1].split(':')[1].split()) | ||||
| break | break | ||||
| elif protoname == wireprotoserver.SSHV2: | elif protoname == wireprotoserver.SSHV2: | ||||
| # We see a line with number of bytes to follow and then a value | # We see a line with number of bytes to follow and then a value | ||||
| testing. | testing. | ||||
| """ | """ | ||||
| try: | try: | ||||
| protoname, caps = _performhandshake(ui, stdin, stdout, stderr) | protoname, caps = _performhandshake(ui, stdin, stdout, stderr) | ||||
| except Exception: | except Exception: | ||||
| _cleanuppipes(ui, stdout, stdin, stderr) | _cleanuppipes(ui, stdout, stdin, stderr) | ||||
| raise | raise | ||||
| if protoname == wireprotoserver.SSHV1: | if protoname == wireprototypes.SSHV1: | ||||
| return sshv1peer(ui, path, proc, stdin, stdout, stderr, caps, | return sshv1peer(ui, path, proc, stdin, stdout, stderr, caps, | ||||
| autoreadstderr=autoreadstderr) | autoreadstderr=autoreadstderr) | ||||
| elif protoname == wireprotoserver.SSHV2: | elif protoname == wireprototypes.SSHV2: | ||||
| return sshv2peer(ui, path, proc, stdin, stdout, stderr, caps, | return sshv2peer(ui, path, proc, stdin, stdout, stderr, caps, | ||||
| autoreadstderr=autoreadstderr) | autoreadstderr=autoreadstderr) | ||||
| else: | else: | ||||
| _cleanuppipes(ui, stdout, stdin, stderr) | _cleanuppipes(ui, stdout, stdin, stderr) | ||||
| raise error.RepoError(_('unknown version of SSH protocol: %s') % | raise error.RepoError(_('unknown version of SSH protocol: %s') % | ||||
| protoname) | protoname) | ||||
| def instance(ui, path, create): | def instance(ui, path, create): | ||||
| urlreq = util.urlreq | urlreq = util.urlreq | ||||
| HTTP_OK = 200 | HTTP_OK = 200 | ||||
| HGTYPE = 'application/mercurial-0.1' | HGTYPE = 'application/mercurial-0.1' | ||||
| HGTYPE2 = 'application/mercurial-0.2' | HGTYPE2 = 'application/mercurial-0.2' | ||||
| HGERRTYPE = 'application/hg-error' | HGERRTYPE = 'application/hg-error' | ||||
| # Names of the SSH protocol implementations. | SSHV1 = wireprototypes.SSHV1 | ||||
| SSHV1 = 'ssh-v1' | SSHV2 = wireprototypes.SSHV2 | ||||
| # This is advertised over the wire. Incremental the counter at the end | |||||
| # to reflect BC breakages. | |||||
| SSHV2 = 'exp-ssh-v2-0001' | |||||
| def decodevaluefromheaders(req, headerprefix): | def decodevaluefromheaders(req, headerprefix): | ||||
| """Decode a long value from multiple HTTP request headers. | """Decode a long value from multiple HTTP request headers. | ||||
| Returns the value as a bytes, not a str. | Returns the value as a bytes, not a str. | ||||
| """ | """ | ||||
| chunks = [] | chunks = [] | ||||
| i = 1 | i = 1 | ||||
| """Handler for requests services via version 1 of SSH protocol.""" | """Handler for requests services via version 1 of SSH protocol.""" | ||||
| def __init__(self, ui, fin, fout): | def __init__(self, ui, fin, fout): | ||||
| self._ui = ui | self._ui = ui | ||||
| self._fin = fin | self._fin = fin | ||||
| self._fout = fout | self._fout = fout | ||||
| @property | @property | ||||
| def name(self): | def name(self): | ||||
| return SSHV1 | return wireprototypes.SSHV1 | ||||
| def getargs(self, args): | def getargs(self, args): | ||||
| data = {} | data = {} | ||||
| keys = args.split() | keys = args.split() | ||||
| for n in xrange(len(keys)): | for n in xrange(len(keys)): | ||||
| argline = self._fin.readline()[:-1] | argline = self._fin.readline()[:-1] | ||||
| arg, l = argline.split() | arg, l = argline.split() | ||||
| if arg not in keys: | if arg not in keys: | ||||
| elif state == 'protov2-serving': | elif state == 'protov2-serving': | ||||
| state = 'protov1-serving' | state = 'protov1-serving' | ||||
| continue | continue | ||||
| elif state == 'upgrade-initial': | elif state == 'upgrade-initial': | ||||
| # We should never transition into this state if we've switched | # We should never transition into this state if we've switched | ||||
| # protocols. | # protocols. | ||||
| assert not protoswitched | assert not protoswitched | ||||
| assert proto.name == SSHV1 | assert proto.name == wireprototypes.SSHV1 | ||||
| # Expected: upgrade <token> <capabilities> | # Expected: upgrade <token> <capabilities> | ||||
| # If we get something else, the request is malformed. It could be | # If we get something else, the request is malformed. It could be | ||||
| # from a future client that has altered the upgrade line content. | # from a future client that has altered the upgrade line content. | ||||
| # We treat this as an unknown command. | # We treat this as an unknown command. | ||||
| try: | try: | ||||
| token, caps = request.split(b' ')[1:] | token, caps = request.split(b' ')[1:] | ||||
| except ValueError: | except ValueError: | ||||
| # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com> | # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com> | ||||
| # | # | ||||
| # This software may be used and distributed according to the terms of the | # This software may be used and distributed according to the terms of the | ||||
| # GNU General Public License version 2 or any later version. | # GNU General Public License version 2 or any later version. | ||||
| from __future__ import absolute_import | from __future__ import absolute_import | ||||
| import abc | import abc | ||||
| # Names of the SSH protocol implementations. | |||||
| SSHV1 = 'ssh-v1' | |||||
| # This is advertised over the wire. Incremental the counter at the end | |||||
| # to reflect BC breakages. | |||||
| SSHV2 = 'exp-ssh-v2-0001' | |||||
| class bytesresponse(object): | class bytesresponse(object): | ||||
| """A wire protocol response consisting of raw bytes.""" | """A wire protocol response consisting of raw bytes.""" | ||||
| def __init__(self, data): | def __init__(self, data): | ||||
| self.data = data | self.data = data | ||||
| class ooberror(object): | class ooberror(object): | ||||
| """wireproto reply: failure of a batch of operation | """wireproto reply: failure of a batch of operation | ||||