Skip to content

Commit 5d073d5

Browse files
author
Dave Berenbaum
authored
handle missing password (#369)
1 parent 4abb42d commit 5d073d5

File tree

2 files changed

+76
-8
lines changed

2 files changed

+76
-8
lines changed

src/scmrepo/git/backend/dulwich/asyncssh_vendor.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ async def _run_command(
298298
host,
299299
port=port if port is not None else (),
300300
username=username if username is not None else (),
301-
password=password if password is not None else (),
301+
password=password,
302302
client_keys=[key_filename] if key_filename else (),
303303
ignore_encrypted=not key_filename,
304304
known_hosts=None,

tests/test_dulwich.py

+75-7
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,74 @@
1111
from pytest_mock import MockerFixture
1212
from pytest_test_utils.waiters import wait_until
1313

14+
from scmrepo.exceptions import AuthError
1415
from scmrepo.git.backend.dulwich.asyncssh_vendor import AsyncSSHVendor
1516

16-
from .vendor.test_paramiko_vendor import (
17-
CLIENT_KEY,
18-
PASSWORD,
19-
USER,
20-
Server,
21-
)
22-
2317
# pylint: disable=redefined-outer-name
2418

2519

20+
USER = "testuser"
21+
PASSWORD = "test"
22+
CLIENT_KEY = """-----BEGIN RSA PRIVATE KEY-----
23+
MIIEpAIBAAKCAQEAxvREKSElPOm/0z/nPO+j5rk2tjdgGcGc7We1QZ6TRXYLu7nN
24+
GeEFIL4p8N1i6dmB+Eydt7xqCU79MWD6Yy4prFe1+/K1wCDUxIbFMxqQcX5zjJzd
25+
i8j8PbcaUlVhP/OkjtkSxrXaGDO1BzfdV4iEBtTV/2l3zmLKJlt3jnOHLczP24CB
26+
DTQKp3rKshbRefzot9Y+wnaK692RsYgsyo9YEP0GyWKG9topCHk13r46J6vGLeuj
27+
ryUKqmbLJkzbJbIcEqwTDo5iHaCVqaMr5Hrb8BdMucSseqZQJsXSd+9tdRcIblUQ
28+
38kZjmFMm4SFbruJcpZCNM2wNSZPIRX+3eiwNwIDAQABAoIBAHSacOBSJsr+jIi5
29+
KUOTh9IPtzswVUiDKwARCjB9Sf8p4lKR4N1L/n9kNJyQhApeikgGT2GCMftmqgoo
30+
tlculQoHFgemBlOmak0MV8NNzF5YKEy/GzF0CDH7gJfEpoyetVFrdA+2QS5yD6U9
31+
XqKQxiBi2VEqdScmyyeT8AwzNYTnPeH/DOEcnbdRjqiy/CD79F49CQ1lX1Fuqm0K
32+
I7BivBH1xo/rVnUP4F+IzocDqoga+Pjdj0LTXIgJlHQDSbhsQqWujWQDDuKb+MAw
33+
sNK4Zf8ErV3j1PyA7f/M5LLq6zgstkW4qikDHo4SpZX8kFOO8tjqb7kujj7XqeaB
34+
CxqrOTECgYEA73uWkrohcmDJ4KqbuL3tbExSCOUiaIV+sT1eGPNi7GCmXD4eW5Z4
35+
75v2IHymW83lORSu/DrQ6sKr1nkuRpqr2iBzRmQpl/H+wahIhBXlnJ25uUjDsuPO
36+
1Pq2LcmyD+jTxVnmbSe/q7O09gZQw3I6H4+BMHmpbf8tC97lqimzpJ0CgYEA1K0W
37+
ZL70Xtn9quyHvbtae/BW07NZnxvUg4UaVIAL9Zu34JyplJzyzbIjrmlDbv6aRogH
38+
/KtuG9tfbf55K/jjqNORiuRtzt1hUN1ye4dyW7tHx2/7lXdlqtyK40rQl8P0kqf8
39+
zaS6BqjnobgSdSpg32rWoL/pcBHPdJCJEgQ8zeMCgYEA0/PK8TOhNIzrP1dgGSKn
40+
hkkJ9etuB5nW5mEM7gJDFDf6JPupfJ/xiwe6z0fjKK9S57EhqgUYMB55XYnE5iIw
41+
ZQ6BV9SAZ4V7VsRs4dJLdNC3tn/rDGHJBgCaym2PlbsX6rvFT+h1IC8dwv0V79Ui
42+
Ehq9WTzkMoE8yhvNokvkPZUCgYEAgBAFxv5xGdh79ftdtXLmhnDvZ6S8l6Fjcxqo
43+
Ay/jg66Tp43OU226iv/0mmZKM8Dd1xC8dnon4GBVc19jSYYiWBulrRPlx0Xo/o+K
44+
CzZBN1lrXH1i6dqufpc0jq8TMf/N+q1q/c1uMupsKCY1/xVYpc+ok71b7J7c49zQ
45+
nOeuUW8CgYA9Infooy65FTgbzca0c9kbCUBmcAPQ2ItH3JcPKWPQTDuV62HcT00o
46+
fZdIV47Nez1W5Clk191RMy8TXuqI54kocciUWpThc6j44hz49oUueb8U4bLcEHzA
47+
WxtWBWHwxfSmqgTXilEA3ALJp0kNolLnEttnhENwJpZHlqtes0ZA4w==
48+
-----END RSA PRIVATE KEY-----"""
49+
50+
51+
class Server(paramiko.ServerInterface):
52+
"""http://docs.paramiko.org/en/2.4/api/server.html."""
53+
54+
def __init__(self, commands, *args, **kwargs) -> None:
55+
super().__init__(*args, **kwargs)
56+
self.commands = commands
57+
58+
def check_channel_exec_request(self, channel, command):
59+
self.commands.append(command)
60+
return True
61+
62+
def check_auth_password(self, username, password):
63+
if username == USER and password == PASSWORD:
64+
return paramiko.AUTH_SUCCESSFUL
65+
return paramiko.AUTH_FAILED
66+
67+
def check_auth_publickey(self, username, key):
68+
pubkey = paramiko.RSAKey.from_private_key(StringIO(CLIENT_KEY))
69+
if username == USER and key == pubkey:
70+
return paramiko.AUTH_SUCCESSFUL
71+
return paramiko.AUTH_FAILED
72+
73+
def check_channel_request(self, kind, chanid):
74+
if kind == "session":
75+
return paramiko.OPEN_SUCCEEDED
76+
return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
77+
78+
def get_allowed_auths(self, username):
79+
return "password,publickey"
80+
81+
2682
@pytest.fixture
2783
def ssh_conn(request: pytest.FixtureRequest) -> dict[str, Any]:
2884
server = Server([])
@@ -77,6 +133,18 @@ def test_run_command_password(server: Server, ssh_port: int):
77133
assert b"test_run_command_password" in server.commands
78134

79135

136+
def test_run_command_no_password(server: Server, ssh_port: int):
137+
vendor = AsyncSSHVendor()
138+
with pytest.raises(AuthError):
139+
vendor.run_command(
140+
"127.0.0.1",
141+
"test_run_command_password",
142+
username=USER,
143+
port=ssh_port,
144+
password=None,
145+
)
146+
147+
80148
def test_run_command_with_privkey(server: Server, ssh_port: int):
81149
key = asyncssh.import_private_key(CLIENT_KEY)
82150

0 commit comments

Comments
 (0)