From be17dc9d31e805c03372b690dde67838b3bfc12d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 24 May 2023 16:34:11 +0200 Subject: [PATCH] libssh: when keyboard-interactive auth fails, try password MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The state machine had a mistake in that it would not carry on to that next step. This also adds a verbose output what methods that are available from the server and renames the macros that change to the next auth methods to try. Reported-by: 左潇峰 Fixes #11196 Closes #11197 --- lib/vssh/libssh.c | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c index 7ebe613214..1cecb649cb 100644 --- a/lib/vssh/libssh.c +++ b/lib/vssh/libssh.c @@ -576,7 +576,7 @@ cleanup: rc = SSH_ERROR; \ } while(0) -#define MOVE_TO_LAST_AUTH do { \ +#define MOVE_TO_PASSWD_AUTH do { \ if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \ rc = SSH_OK; \ state(data, SSH_AUTH_PASS_INIT); \ @@ -586,23 +586,23 @@ cleanup: } \ } while(0) -#define MOVE_TO_TERTIARY_AUTH do { \ +#define MOVE_TO_KEY_AUTH do { \ if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \ rc = SSH_OK; \ state(data, SSH_AUTH_KEY_INIT); \ } \ else { \ - MOVE_TO_LAST_AUTH; \ + MOVE_TO_PASSWD_AUTH; \ } \ } while(0) -#define MOVE_TO_SECONDARY_AUTH do { \ +#define MOVE_TO_GSSAPI_AUTH do { \ if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \ rc = SSH_OK; \ state(data, SSH_AUTH_GSSAPI); \ } \ else { \ - MOVE_TO_TERTIARY_AUTH; \ + MOVE_TO_KEY_AUTH; \ } \ } while(0) @@ -753,6 +753,16 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL); + if(sshc->auth_methods) + infof(data, "SSH authentication methods available: %s%s%s%s", + sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY ? + "public key, ": "", + sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC ? + "GSSAPI, " : "", + sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE ? + "keyboard-interactive, " : "", + sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD ? + "password": ""); if(sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) { state(data, SSH_AUTH_PKEY_INIT); infof(data, "Authentication using SSH public key file"); @@ -775,7 +785,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } case SSH_AUTH_PKEY_INIT: if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY)) { - MOVE_TO_SECONDARY_AUTH; + MOVE_TO_GSSAPI_AUTH; break; } @@ -791,7 +801,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } if(rc != SSH_OK) { - MOVE_TO_SECONDARY_AUTH; + MOVE_TO_GSSAPI_AUTH; break; } } @@ -826,7 +836,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) break; } - MOVE_TO_SECONDARY_AUTH; + MOVE_TO_GSSAPI_AUTH; } break; case SSH_AUTH_PKEY: @@ -844,13 +854,13 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } else { infof(data, "Failed public key authentication (rc: %d)", rc); - MOVE_TO_SECONDARY_AUTH; + MOVE_TO_GSSAPI_AUTH; } break; case SSH_AUTH_GSSAPI: if(!(data->set.ssh_auth_types & CURLSSH_AUTH_GSSAPI)) { - MOVE_TO_TERTIARY_AUTH; + MOVE_TO_KEY_AUTH; break; } @@ -868,7 +878,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) break; } - MOVE_TO_TERTIARY_AUTH; + MOVE_TO_KEY_AUTH; break; case SSH_AUTH_KEY_INIT: @@ -876,13 +886,12 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) state(data, SSH_AUTH_KEY); } else { - MOVE_TO_LAST_AUTH; + MOVE_TO_PASSWD_AUTH; } break; case SSH_AUTH_KEY: - - /* Authentication failed. Continue with keyboard-interactive now. */ + /* keyboard-interactive authentication */ rc = myssh_auth_interactive(conn); if(rc == SSH_AGAIN) { break; @@ -890,13 +899,15 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == SSH_OK) { sshc->authed = TRUE; infof(data, "completed keyboard interactive authentication"); + state(data, SSH_AUTH_DONE); + } + else { + MOVE_TO_PASSWD_AUTH; } - state(data, SSH_AUTH_DONE); break; case SSH_AUTH_PASS_INIT: if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD)) { - /* Host key authentication is intentionally not implemented */ MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); break; }