diff --git a/ssh.c b/ssh.c index fc68bf95..808327d0 100644 --- a/ssh.c +++ b/ssh.c @@ -7497,6 +7497,21 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, s->cur_prompt->instruction = dupprintf("%.*s", prompt_len, prompt); s->cur_prompt->instr_reqd = TRUE; + /* + * There's no explicit requirement in the protocol + * for the "old" passwords in the original and + * password-change messages to be the same, and + * apparently some Cisco kit supports password change + * by the user entering a blank password originally + * and the real password subsequently, so, + * reluctantly, we prompt for the old password again. + * + * (On the other hand, some servers don't even bother + * to check this field.) + */ + add_prompt(s->cur_prompt, + dupstr("Current password (blank for previously entered password): "), + FALSE, SSH_MAX_PASSWORD_LEN); add_prompt(s->cur_prompt, dupstr("Enter new password: "), FALSE, SSH_MAX_PASSWORD_LEN); add_prompt(s->cur_prompt, dupstr("Confirm new password: "), @@ -7530,10 +7545,25 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, } /* - * Check the two passwords match. + * If the user specified a new original password + * (IYSWIM), overwrite any previously specified + * one. + * (A side effect is that the user doesn't have to + * re-enter it if they louse up the new password.) */ - got_new = (strcmp(s->cur_prompt->prompts[0]->result, - s->cur_prompt->prompts[1]->result) + if (s->cur_prompt->prompts[0]->result[0]) { + memset(s->password, 0, strlen(s->password)); + /* burn the evidence */ + sfree(s->password); + s->password = + dupstr(s->cur_prompt->prompts[0]->result); + } + + /* + * Check the two new passwords match. + */ + got_new = (strcmp(s->cur_prompt->prompts[1]->result, + s->cur_prompt->prompts[2]->result) == 0); if (!got_new) /* They don't. Silly user. */ @@ -7555,7 +7585,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, dont_log_password(ssh, s->pktout, PKTLOG_BLANK); ssh2_pkt_addstring(s->pktout, s->password); ssh2_pkt_addstring(s->pktout, - s->cur_prompt->prompts[0]->result); + s->cur_prompt->prompts[1]->result); free_prompts(s->cur_prompt); end_log_omission(ssh, s->pktout); ssh2_pkt_send(ssh, s->pktout);