[PATCH 2/2] Support changing expired passwords in client

Joakim Tjernlund joakim.tjernlund at infinera.com
Mon Apr 25 16:26:59 AWST 2016


This adds support for handling expired passwords in the client.

Signed-off-by: Joakim Tjernlund <joakim.tjernlund at infinera.com>
---
 auth.h           |  1 +
 cli-auth.c       |  8 ++-----
 cli-authpasswd.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 74 insertions(+), 6 deletions(-)

diff --git a/auth.h b/auth.h
index a6bb3f1..a0aa3a4 100644
--- a/auth.h
+++ b/auth.h
@@ -39,6 +39,7 @@ void send_msg_userauth_success();
 void send_msg_userauth_chauthtok();
 void send_msg_userauth_banner(buffer *msg);
 void svr_auth_password();
+void cli_auth_new_password();
 void svr_auth_pubkey();
 void svr_auth_pam(const char * username, int createLocalUser);
 
diff --git a/cli-auth.c b/cli-auth.c
index da0d9d5..1eb93e7 100644
--- a/cli-auth.c
+++ b/cli-auth.c
@@ -137,12 +137,8 @@ void recv_msg_userauth_specific_60() {
 
 #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.");
+		cli_auth_new_password();
+		return;
 	}
 #endif
 
diff --git a/cli-authpasswd.c b/cli-authpasswd.c
index 3cf49a2..72e6f2e 100644
--- a/cli-authpasswd.c
+++ b/cli-authpasswd.c
@@ -158,4 +158,75 @@ void cli_auth_password() {
 
 	TRACE(("leave cli_auth_password"))
 }
+
+static char *ask_password(char* prompt)
+{
+	char* password = NULL;
+
+#ifdef ENABLE_CLI_ASKPASS_HELPER
+	if (want_askpass())
+	{
+		password = gui_getpass(prompt);
+		if (!password) {
+			dropbear_exit("No password");
+		}
+	} else
+#endif
+	{
+		password = getpass_or_cancel(prompt);
+	}
+	return password;
+}
+
+void cli_auth_new_password() {
+
+	char* password = NULL;
+	char* new_password = NULL;
+	char* new2_password = NULL;
+	char prompt[80];
+
+	TRACE(("enter cli_auth_password"))
+	CHECKCLEARTOWRITE();
+
+	snprintf(prompt, sizeof(prompt), "Enter %s@%s's old password: ",
+				cli_opts.username, cli_opts.remotehost);
+	password = strdup(ask_password(prompt));
+	do {
+		snprintf(prompt, sizeof(prompt), "Enter %s@%s's new password: ",
+			 cli_opts.username, cli_opts.remotehost);
+		new_password = strdup(ask_password(prompt));
+		snprintf(prompt, sizeof(prompt), "Retype %s@%s's new password: ",
+			 cli_opts.username, cli_opts.remotehost);
+		new2_password = strdup(ask_password(prompt));
+		if (strcmp(new_password, new2_password) == 0)
+			break; /* Both passworde match, continue with login */
+		fprintf(stderr, "Mismatch; try again, Ctrl-C to quit\n");
+	} while (1);
+	buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
+
+	buf_putstring(ses.writepayload, cli_opts.username,
+			strlen(cli_opts.username));
+
+	buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION,
+			SSH_SERVICE_CONNECTION_LEN);
+
+	buf_putstring(ses.writepayload, AUTH_METHOD_PASSWORD,
+			AUTH_METHOD_PASSWORD_LEN);
+
+	buf_putbyte(ses.writepayload, 1); /* TRUE */
+	buf_putstring(ses.writepayload, password, strlen(password));
+	buf_putstring(ses.writepayload, new_password, strlen(new_password));
+
+	encrypt_packet();
+	m_burn(password, strlen(password));
+	if (new_password)
+		m_burn(new_password, strlen(new_password));
+	if (new2_password)
+		m_burn(new2_password, strlen(new2_password));
+	free(password);
+	free(new_password);
+	free(new2_password);
+	TRACE(("leave cli_auth_password"))
+}
+
 #endif	/* ENABLE_CLI_PASSWORD_AUTH */
-- 
2.7.3



More information about the Dropbear mailing list