Skip to content

Commit 416db0e

Browse files
cjwatsonronf
authored andcommitted
Use bcrypt rather than crypt in simple_server example
`crypt` was removed from Python 3.13. `bcrypt` isn't ideal, but it has acceptable password hashing, is simple to use, and is already an optional dependency of asyncssh.
1 parent f1848c1 commit 416db0e

File tree

1 file changed

+10
-6
lines changed

1 file changed

+10
-6
lines changed

examples/simple_server.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@
2424
# private key in it to use as a server host key. An SSH host certificate
2525
# can optionally be provided in the file ``ssh_host_key-cert.pub``.
2626

27-
import asyncio, asyncssh, crypt, sys
27+
import asyncio, asyncssh, bcrypt, sys
2828
from typing import Optional
2929

30-
passwords = {'guest': '', # guest account with no password
31-
'user123': 'qV2iEadIGV2rw' # password of 'secretpw'
30+
passwords = {'guest': b'', # guest account with no password
31+
'user123': bcrypt.hashpw(b'secretpw', bcrypt.gensalt()),
3232
}
3333

3434
def handle_client(process: asyncssh.SSHServerProcess) -> None:
@@ -49,14 +49,18 @@ def connection_lost(self, exc: Optional[Exception]) -> None:
4949

5050
def begin_auth(self, username: str) -> bool:
5151
# If the user's password is the empty string, no auth is required
52-
return passwords.get(username) != ''
52+
return passwords.get(username) != b''
5353

5454
def password_auth_supported(self) -> bool:
5555
return True
5656

5757
def validate_password(self, username: str, password: str) -> bool:
58-
pw = passwords.get(username, '*')
59-
return crypt.crypt(password, pw) == pw
58+
if username not in passwords:
59+
return False
60+
pw = passwords[username]
61+
if not password and not pw:
62+
return True
63+
return bcrypt.checkpw(password.encode('utf-8'), pw)
6064

6165
async def start_server() -> None:
6266
await asyncssh.create_server(MySSHServer, '', 8022,

0 commit comments

Comments
 (0)