From ef8994d21ecdc1f9f6265657dd1dc0fa7aa6d071 Mon Sep 17 00:00:00 2001 From: Ryo Nakamura Date: Sat, 8 Nov 2025 18:37:43 +0900 Subject: [PATCH] cache auth_bit_mask after the first none auth attempt This fixes #36, password auth does not occur. --- src/ssh.c | 22 ++++++++++++++++------ test/test_e2e.py | 13 +++++++++---- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/ssh.c b/src/ssh.c index 5430ece..b74a162 100644 --- a/src/ssh.c +++ b/src/ssh.c @@ -114,15 +114,25 @@ static int ssh_set_opts(ssh_session ssh, struct mscp_ssh_opts *opts) static int ssh_authenticate(ssh_session ssh, struct mscp_ssh_opts *opts) { - int auth_bit_mask; + static int auth_bit_mask; int ret; - /* try publickey auth first */ - char *p = opts->passphrase ? opts->passphrase : NULL; - if (ssh_userauth_publickey_auto(ssh, NULL, p) == SSH_AUTH_SUCCESS) - return 0; + if (auth_bit_mask == 0) { + /* the first authentication attempt. try none auth to + * get available auth methods. */ + if (ssh_userauth_none(ssh, NULL) == SSH_AUTH_SUCCESS) + return 0; + + /* save auth_bit_mask for further authentications */ + auth_bit_mask = ssh_userauth_list(ssh, NULL); + } + + if (auth_bit_mask & SSH_AUTH_METHOD_PUBLICKEY) { + char *p = opts->passphrase ? opts->passphrase : NULL; + if (ssh_userauth_publickey_auto(ssh, NULL, p) == SSH_AUTH_SUCCESS) + return 0; + } - auth_bit_mask = ssh_userauth_list(ssh, NULL); if (auth_bit_mask & SSH_AUTH_METHOD_PASSWORD) { if (!opts->password) { char buf[128] = {}; diff --git a/test/test_e2e.py b/test/test_e2e.py index 8d64f8b..6cc3a08 100644 --- a/test/test_e2e.py +++ b/test/test_e2e.py @@ -49,6 +49,8 @@ def cleanup_files(): "{}/src".format(os.environ["HOME"]), "{}/dst".format(os.environ["HOME"]), "/tmp/mscp_test_ssh_config", + "/home/test/dst", + "/home/test/src", "checkpoint", ] @@ -657,11 +659,14 @@ def move_pubkey_temporally(): def test_passwordauth_without_pubkey(move_pubkey_temporally, mscp, src_prefix, dst_prefix): """ - make sure password auth works (by removing publick keys) + make sure password auth works (by removing public keys) """ - src = File("src", size = 10 * 1024 * 1024).make() - dst = File("dst") - run2ok([mscp, "-vvv", src_prefix + src.path, dst_prefix + dst.path]) + src = File(os.getcwd() + "/src", size = 1024).make() + dst = File("/home/test/dst") + env = os.environ + env["MSCP_SSH_AUTH_PASSWORD"] = "userpassword" + run2ok([mscp, "-vvv", "-l", "test", + src.path, "localhost:" + dst.path], env = env) assert check_same_md5sum(src, dst)