Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 0 additions & 45 deletions src/scmrepo/git/backend/dulwich/asyncssh_vendor.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,45 +97,6 @@ async def _close(self) -> None:
close = sync_wrapper(_close)


# NOTE: Github's SSH server does not strictly comply with the SSH protocol.
# When validating a public key using the rsa-sha2-256 or rsa-sha2-512
# signature algorithms, RFC4252 + RFC8332 state that the server should respond
# with the same algorithm in SSH_MSG_USERAUTH_PK_OK. Github's server always
# returns "ssh-rsa" rather than the correct sha2 algorithm name (likely for
# backwards compatibility with old SSH client reasons). This behavior causes
# asyncssh to fail with a key-mismatch error (since asyncssh expects the server
# to behave properly).
#
# See also:
# https://www.ietf.org/rfc/rfc4252.txt
# https://www.ietf.org/rfc/rfc8332.txt
def _process_public_key_ok_gh(self, _pkttype, _pktid, packet):
from asyncssh.misc import ProtocolError

algorithm = packet.get_string()
key_data = packet.get_string()
packet.check_end()

# pylint: disable=protected-access
if (
(
algorithm == b"ssh-rsa"
and self._keypair.algorithm
not in (
b"ssh-rsa",
b"rsa-sha2-256",
b"rsa-sha2-512",
)
)
or (algorithm not in (b"ssh-rsa", self._keypair.algorithm))
or key_data != self._keypair.public_data
):
raise ProtocolError("Key mismatch")

self.create_task(self._send_signed_request())
return True


class InteractiveSSHClient(SSHClient):
_conn: Optional["SSHClientConnection"] = None
_keys_to_try: Optional[list["FilePath"]] = None
Expand Down Expand Up @@ -286,12 +247,6 @@ async def _run_command(
key_filename: Optional path to private keyfile
"""
import asyncssh
from asyncssh.auth import MSG_USERAUTH_PK_OK, _ClientPublicKeyAuth

# pylint: disable=protected-access
_ClientPublicKeyAuth._packet_handlers[MSG_USERAUTH_PK_OK] = (
_process_public_key_ok_gh
)

try:
conn = await asyncssh.connect(
Expand Down
22 changes: 0 additions & 22 deletions tests/test_dulwich.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,28 +212,6 @@ def test_run_command_partial_transfer(ssh_port: int, mocker: MockerFixture):
assert mock_stderr.call_count == 3


@pytest.mark.parametrize("algorithm", [b"ssh-rsa", b"rsa-sha2-256", b"rsa-sha2-512"])
def test_dulwich_github_compat(mocker: MockerFixture, algorithm: bytes):
from asyncssh.misc import ProtocolError

from scmrepo.git.backend.dulwich.asyncssh_vendor import _process_public_key_ok_gh

key_data = b"foo"
auth = mocker.Mock(
_keypair=mocker.Mock(algorithm=algorithm, public_data=key_data),
)
packet = mocker.Mock()

strings = iter((b"ed21556", key_data))
packet.get_string = lambda: next(strings)
with pytest.raises(ProtocolError):
_process_public_key_ok_gh(auth, None, None, packet)

strings = iter((b"ssh-rsa", key_data))
packet.get_string = lambda: next(strings)
_process_public_key_ok_gh(auth, None, None, packet)


@pytest.mark.skipif(os.name != "nt", reason="Windows only")
def test_git_bash_ssh_vendor(mocker):
from dulwich.client import SubprocessSSHVendor
Expand Down