X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/blobdiff_plain/e955d3480bd67cef2c634c8ad011ee58e9ff7a78..b8e3173d5169da33af5b41fa3b8e5b482bfdc6dc:/ssh.c diff --git a/ssh.c b/ssh.c index 7936fd0e..1e228446 100644 --- a/ssh.c +++ b/ssh.c @@ -3459,9 +3459,10 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, break; /* go and try something else */ } else if (ret == -1) { c_write_str(ssh, "Wrong passphrase.\r\n"); /* FIXME */ - s->tried_publickey = 0; got_passphrase = FALSE; /* and try again */ + } else { + assert(0 && "unexpected return from loadrsakey()"); } } @@ -3476,7 +3477,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, crWaitUntil(pktin); if (pktin->type == SSH1_SMSG_FAILURE) { c_write_str(ssh, "Server refused our public key.\r\n"); - continue; /* go and try password */ + continue; /* go and try something else */ } if (pktin->type != SSH1_SMSG_AUTH_RSA_CHALLENGE) { bombout(("Bizarre response to offer of public key")); @@ -3516,7 +3517,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, if (flags & FLAG_VERBOSE) c_write_str(ssh, "Failed to authenticate with" " our public key.\r\n"); - continue; /* go and try password */ + continue; /* go and try something else */ } else if (pktin->type != SSH1_SMSG_SUCCESS) { bombout(("Bizarre response to RSA authentication response")); crStop(0); @@ -7152,9 +7153,6 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, /* * Keyboard-interactive authentication. */ - char *name, *inst, *lang; - int name_len, inst_len, lang_len; - int i; s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE; @@ -7174,7 +7172,9 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, crWaitUntilV(pktin); if (pktin->type != SSH2_MSG_USERAUTH_INFO_REQUEST) { /* Server is not willing to do keyboard-interactive - * at all. Give up on it entirely. */ + * at all (or, bizarrely but legally, accepts the + * user without actually issuing any prompts). + * Give up on it entirely. */ s->gotit = TRUE; if (pktin->type == SSH2_MSG_USERAUTH_FAILURE) logevent("Keyboard-interactive authentication refused"); @@ -7184,89 +7184,113 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, } /* - * We've got a fresh USERAUTH_INFO_REQUEST. - * Get the preamble and start building a prompt. + * Loop while the server continues to send INFO_REQUESTs. */ - ssh_pkt_getstring(pktin, &name, &name_len); - ssh_pkt_getstring(pktin, &inst, &inst_len); - ssh_pkt_getstring(pktin, &lang, &lang_len); - s->cur_prompt = new_prompts(ssh->frontend); - s->cur_prompt->to_server = TRUE; - if (name_len) { - /* FIXME: better prefix to distinguish from - * local prompts? */ - s->cur_prompt->name = dupprintf("SSH server: %.*s", - name_len, name); - s->cur_prompt->name_reqd = TRUE; - } else { - s->cur_prompt->name = dupstr("SSH server authentication"); - s->cur_prompt->name_reqd = FALSE; - } - s->cur_prompt->instruction = - dupprintf("Using keyboard-interactive authentication.%s%.*s", - inst_len ? "\n" : "", inst_len, inst); - s->cur_prompt->instr_reqd = TRUE; + while (pktin->type == SSH2_MSG_USERAUTH_INFO_REQUEST) { - /* - * Get the prompts from the packet. - */ - s->num_prompts = ssh_pkt_getuint32(pktin); - for (i = 0; i < s->num_prompts; i++) { - char *prompt; - int prompt_len; - int echo; - static char noprompt[] = - ": "; + char *name, *inst, *lang; + int name_len, inst_len, lang_len; + int i; - ssh_pkt_getstring(pktin, &prompt, &prompt_len); - echo = ssh2_pkt_getbool(pktin); - if (!prompt_len) { - prompt = noprompt; - prompt_len = lenof(noprompt)-1; + /* + * We've got a fresh USERAUTH_INFO_REQUEST. + * Get the preamble and start building a prompt. + */ + ssh_pkt_getstring(pktin, &name, &name_len); + ssh_pkt_getstring(pktin, &inst, &inst_len); + ssh_pkt_getstring(pktin, &lang, &lang_len); + s->cur_prompt = new_prompts(ssh->frontend); + s->cur_prompt->to_server = TRUE; + if (name_len) { + /* FIXME: better prefix to distinguish from + * local prompts? */ + s->cur_prompt->name = + dupprintf("SSH server: %.*s", name_len, name); + s->cur_prompt->name_reqd = TRUE; + } else { + s->cur_prompt->name = + dupstr("SSH server authentication"); + s->cur_prompt->name_reqd = FALSE; } - add_prompt(s->cur_prompt, - dupprintf("%.*s", prompt_len, prompt), - echo, SSH_MAX_PASSWORD_LEN); - } + /* FIXME: ugly to print "Using..." in prompt _every_ + * time round. Can this be done more subtly? */ + s->cur_prompt->instruction = + dupprintf("Using keyboard-interactive authentication.%s%.*s", + inst_len ? "\n" : "", inst_len, inst); + s->cur_prompt->instr_reqd = TRUE; - /* - * Get the user's responses. - */ - if (s->num_prompts) { - int ret; /* not live over crReturn */ - ret = get_userpass_input(s->cur_prompt, NULL, 0); - while (ret < 0) { - ssh->send_ok = 1; - crWaitUntilV(!pktin); - ret = get_userpass_input(s->cur_prompt, in, inlen); - ssh->send_ok = 0; + /* + * Get the prompts from the packet. + */ + s->num_prompts = ssh_pkt_getuint32(pktin); + for (i = 0; i < s->num_prompts; i++) { + char *prompt; + int prompt_len; + int echo; + static char noprompt[] = + ": "; + + ssh_pkt_getstring(pktin, &prompt, &prompt_len); + echo = ssh2_pkt_getbool(pktin); + if (!prompt_len) { + prompt = noprompt; + prompt_len = lenof(noprompt)-1; + } + add_prompt(s->cur_prompt, + dupprintf("%.*s", prompt_len, prompt), + echo, SSH_MAX_PASSWORD_LEN); } - if (!ret) { - /* - * Failed to get responses. Terminate. - */ - free_prompts(s->cur_prompt); - ssh_disconnect(ssh, NULL, "Unable to authenticate", - SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER, - TRUE); - crStopV; + + /* + * Get the user's responses. + */ + if (s->num_prompts) { + int ret; /* not live over crReturn */ + ret = get_userpass_input(s->cur_prompt, NULL, 0); + while (ret < 0) { + ssh->send_ok = 1; + crWaitUntilV(!pktin); + ret = get_userpass_input(s->cur_prompt, in, inlen); + ssh->send_ok = 0; + } + if (!ret) { + /* + * Failed to get responses. Terminate. + */ + free_prompts(s->cur_prompt); + ssh_disconnect(ssh, NULL, "Unable to authenticate", + SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER, + TRUE); + crStopV; + } } + + /* + * Send the responses to the server. + */ + s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_INFO_RESPONSE); + s->pktout->forcepad = 256; + ssh2_pkt_adduint32(s->pktout, s->num_prompts); + for (i=0; i < s->num_prompts; i++) { + dont_log_password(ssh, s->pktout, PKTLOG_BLANK); + ssh2_pkt_addstring(s->pktout, + s->cur_prompt->prompts[i]->result); + end_log_omission(ssh, s->pktout); + } + ssh2_pkt_send(ssh, s->pktout); + + /* + * Get the next packet in case it's another + * INFO_REQUEST. + */ + crWaitUntilV(pktin); + } /* - * Send the responses to the server. + * We should have SUCCESS or FAILURE now. */ - s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_INFO_RESPONSE); - s->pktout->forcepad = 256; - ssh2_pkt_adduint32(s->pktout, s->num_prompts); - for (i=0; i < s->num_prompts; i++) { - dont_log_password(ssh, s->pktout, PKTLOG_BLANK); - ssh2_pkt_addstring(s->pktout, - s->cur_prompt->prompts[i]->result); - end_log_omission(ssh, s->pktout); - } - ssh2_pkt_send(ssh, s->pktout); - s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE; + s->gotit = TRUE; } else if (s->can_passwd) {