From 98dbf15d0b2127854cca340a0255b94aeb342705 Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Wed, 1 Jul 2020 17:33:22 -0400 Subject: [PATCH] GUACAMOLE-221: Fix up SSH terminal prompt fallback. --- src/common-ssh/common-ssh/ssh.h | 7 +++++- src/common-ssh/ssh.c | 9 +++++-- src/protocols/ssh/ssh.c | 44 +++++++++++++++++++-------------- 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/src/common-ssh/common-ssh/ssh.h b/src/common-ssh/common-ssh/ssh.h index 609e1a1e..e354cf1a 100644 --- a/src/common-ssh/common-ssh/ssh.h +++ b/src/common-ssh/common-ssh/ssh.h @@ -34,8 +34,13 @@ * * @param cred_name * The connection parameter that is being requested from the client. + * + * @return + * A newly-allocated string containing the credentials request from the + * client, or NULL if the credentials will be updated via the required + * instruction. */ -typedef void guac_ssh_credential_handler(guac_client* client, char* cred_name); +typedef char* guac_ssh_credential_handler(guac_client* client, char* cred_name); /** * An SSH session, backed by libssh2 and associated with a particular diff --git a/src/common-ssh/ssh.c b/src/common-ssh/ssh.c index 07188d98..32f8d550 100644 --- a/src/common-ssh/ssh.c +++ b/src/common-ssh/ssh.c @@ -360,8 +360,13 @@ static int guac_common_ssh_authenticate(guac_common_ssh_session* common_session) } /* Attempt authentication with username + password. */ - if (user->password == NULL && common_session->credential_handler) - common_session->credential_handler(client, GUAC_SSH_PARAMETER_NAME_PASSWORD); + if (user->password == NULL && common_session->credential_handler) { + + char* password = common_session->credential_handler(client, GUAC_SSH_PARAMETER_NAME_PASSWORD); + if (password != NULL) + user->password = password; + + } /* Authenticate with password, if provided */ if (user->password != NULL) { diff --git a/src/protocols/ssh/ssh.c b/src/protocols/ssh/ssh.c index 57effd54..4b69b8ed 100644 --- a/src/protocols/ssh/ssh.c +++ b/src/protocols/ssh/ssh.c @@ -99,10 +99,26 @@ guac_ssh_credential_prompt_map ssh_credential_prompt_map[] = { * @param cred_name * The name of the parameter to prompt for in the client. */ -static void guac_ssh_get_credential(guac_client *client, char* cred_name) { +static char* guac_ssh_get_credential(guac_client *client, char* cred_name) { guac_ssh_client* ssh_client = (guac_ssh_client*) client->data; + /* If client owner does not support required, use terminal prompt. */ + if (!guac_client_owner_supports_required(client)) { + + /* Loop to find correct prompt for credential name. */ + guac_ssh_credential_prompt_map* current = ssh_credential_prompt_map; + while (current->name != NULL) { + if (strcmp(current->name, cred_name) == 0) + return guac_terminal_prompt(ssh_client->term, + current->prompt, true); + current++; + } + + /* No matching credential was found, so return NULL. */ + return NULL; + } + /* Lock the terminal thread while prompting for the credential. */ pthread_mutex_lock(&(ssh_client->ssh_credential_lock)); @@ -113,6 +129,8 @@ static void guac_ssh_get_credential(guac_client *client, char* cred_name) { pthread_cond_wait(&(ssh_client->ssh_credential_cond), &(ssh_client->ssh_credential_lock)); pthread_mutex_unlock(&(ssh_client->ssh_credential_lock)); + return NULL; + } /** @@ -137,16 +155,9 @@ static guac_common_ssh_user* guac_ssh_get_user(guac_client* client) { /* Get username */ while (settings->username == NULL) { - /* Client owner supports required instruction, so send prompt(s) that way. */ - if (guac_client_owner_supports_required(client)) { - guac_ssh_get_credential(client, GUAC_SSH_PARAMETER_NAME_USERNAME); - } - - /* Fall back to terminal prompting. */ - else { - settings->username = guac_terminal_prompt(ssh_client->term, - "Login as: ", true); - } + char* username = guac_ssh_get_credential(client, GUAC_SSH_PARAMETER_NAME_USERNAME); + if (username != NULL) + settings->username = username; } @@ -174,14 +185,9 @@ static guac_common_ssh_user* guac_ssh_get_user(guac_client* client) { /* Prompt for passphrase if missing */ while (settings->key_passphrase == NULL) { - /* Send prompt via required instruction, if supported */ - if (guac_client_owner_supports_required(client)) - guac_ssh_get_credential(client, GUAC_SSH_PARAMETER_NAME_PASSPHRASE); - - /* Fall back to terminal prompt */ - else - settings->key_passphrase = guac_terminal_prompt(ssh_client->term, - "Key passphrase: ", true); + char* passphrase = guac_ssh_get_credential(client, GUAC_SSH_PARAMETER_NAME_PASSPHRASE); + if (passphrase != NULL) + settings->key_passphrase = passphrase; }