diff options
author | Matt Johnston <matt@ucc.asn.au> | 2005-09-20 17:35:21 +0000 |
---|---|---|
committer | Matt Johnston <matt@ucc.asn.au> | 2005-09-20 17:35:21 +0000 |
commit | 876b7081d8f073edd4717ccdb7091fe3a6975ef6 (patch) | |
tree | a1e75c7c67acfa982b9f0098591d9f3e8c86662d /cli-auth.c | |
parent | cb2cb15916497f790c1d420ccff858446772780c (diff) |
added keyboard-interactive client support
--HG--
extra : convert_revision : 3df738e42f4fc8b7f0f3ff9ca767386f54edb1ea
Diffstat (limited to 'cli-auth.c')
-rw-r--r-- | cli-auth.c | 78 |
1 files changed, 73 insertions, 5 deletions
@@ -32,7 +32,6 @@ #include "packet.h" #include "runopts.h" - void cli_authinitialise() { memset(&ses.authstate, 0, sizeof(ses.authstate)); @@ -99,6 +98,40 @@ out: TRACE(("leave recv_msg_userauth_banner")) } +/* This handles the message-specific types which + * all have a value of 60. These are + * SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, + * SSH_MSG_USERAUTH_PK_OK, & + * SSH_MSG_USERAUTH_INFO_REQUEST. */ +void recv_msg_userauth_specific_60() { + +#ifdef ENABLE_CLI_PUBKEY_AUTH + if (cli_ses.lastauthtype == AUTH_TYPE_PUBKEY) { + recv_msg_userauth_pk_ok(); + return; + } +#endif + +#ifdef ENABLE_CLI_INTERACT_AUTH + if (cli_ses.lastauthtype == AUTH_TYPE_INTERACT) { + recv_msg_userauth_info_request(); + return; + } +#endif + +#ifdef ENABLE_CLI_PASSWORD_AUTH + if (cli_ses.lastauthtype == AUTH_TYPE_PASSWORD) { + /* Eventually there could be proper password-changing + * support. However currently few servers seem to + * implement it, and password auth is last-resort + * regardless - keyboard-interactive is more likely + * to be used anyway. */ + dropbear_close("Your password has expired."); + } +#endif + + dropbear_exit("Unexpected userauth packet"); +} void recv_msg_userauth_failure() { @@ -113,8 +146,7 @@ void recv_msg_userauth_failure() { if (cli_ses.state != USERAUTH_REQ_SENT) { /* Perhaps we should be more fatal? */ - TRACE(("But we didn't send a userauth request!!!!!!")) - return; + dropbear_exit("Unexpected userauth failure"); } #ifdef ENABLE_CLI_PUBKEY_AUTH @@ -125,6 +157,19 @@ void recv_msg_userauth_failure() { } #endif +#ifdef ENABLE_CLI_INTERACT_AUTH + /* If we get a failure message for keyboard interactive without + * receiving any request info packet, then we don't bother trying + * keyboard interactive again */ + if (cli_ses.lastauthtype == AUTH_TYPE_INTERACT + && !cli_ses.interact_request_received) { + TRACE(("setting auth_interact_failed = 1")) + cli_ses.auth_interact_failed = 1; + } +#endif + + cli_ses.lastauthtype = AUTH_TYPE_NONE; + methods = buf_getstring(ses.payload, &methlen); partial = buf_getbool(ses.payload); @@ -157,6 +202,12 @@ void recv_msg_userauth_failure() { ses.authstate.authtypes |= AUTH_TYPE_PUBKEY; } #endif +#ifdef ENABLE_CLI_INTERACT_AUTH + if (strncmp(AUTH_METHOD_INTERACT, tok, + AUTH_METHOD_INTERACT_LEN) == 0) { + ses.authstate.authtypes |= AUTH_TYPE_INTERACT; + } +#endif #ifdef ENABLE_CLI_PASSWORD_AUTH if (strncmp(AUTH_METHOD_PASSWORD, tok, AUTH_METHOD_PASSWORD_LEN) == 0) { @@ -180,6 +231,7 @@ void recv_msg_userauth_success() { TRACE(("received msg_userauth_success")) ses.authstate.authdone = 1; cli_ses.state = USERAUTH_SUCCESS_RCVD; + cli_ses.lastauthtype = AUTH_TYPE_NONE; } void cli_auth_try() { @@ -189,7 +241,8 @@ void cli_auth_try() { CHECKCLEARTOWRITE(); - /* XXX We hardcode that we try a pubkey first */ + /* Order to try is pubkey, interactive, password. + * As soon as "finished" is set for one, we don't do any more. */ #ifdef ENABLE_CLI_PUBKEY_AUTH if (ses.authstate.authtypes & AUTH_TYPE_PUBKEY) { finished = cli_auth_pubkey(); @@ -197,13 +250,28 @@ void cli_auth_try() { } #endif +#ifdef ENABLE_CLI_INTERACT_AUTH + if (!finished && ses.authstate.authtypes & AUTH_TYPE_INTERACT) { + if (cli_ses.auth_interact_failed) { + finished = 0; + } else { + cli_auth_interactive(); + cli_ses.lastauthtype = AUTH_TYPE_INTERACT; + finished = 1; + } + } +#endif + #ifdef ENABLE_CLI_PASSWORD_AUTH if (!finished && ses.authstate.authtypes & AUTH_TYPE_PASSWORD) { - finished = cli_auth_password(); + cli_auth_password(); + finished = 1; cli_ses.lastauthtype = AUTH_TYPE_PASSWORD; } #endif + TRACE(("cli_auth_try lastauthtype %d", cli_ses.lastauthtype)) + if (!finished) { dropbear_exit("No auth methods could be used."); } |