diff --git a/src/protocols/ssh/ssh_client.c b/src/protocols/ssh/ssh_client.c index affce5df..7f60f781 100644 --- a/src/protocols/ssh/ssh_client.c +++ b/src/protocols/ssh/ssh_client.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #ifdef LIBSSH2_USES_GCRYPT @@ -351,7 +352,9 @@ void* ssh_client_thread(void* data) { CRYPTO_set_id_callback(__openssl_id_callback); CRYPTO_set_locking_callback(__openssl_locking_callback); + /* Init OpenSSL */ SSL_library_init(); + ERR_load_crypto_strings(); libssh2_init(0); /* Get username */ @@ -366,6 +369,9 @@ void* ssh_client_thread(void* data) { /* If key specified, import */ if (client_data->key_base64[0] != 0) { + guac_client_log(client, GUAC_LOG_DEBUG, + "Attempting private key import (WITHOUT passphrase)"); + /* Attempt to read key without passphrase */ client_data->key = ssh_key_alloc(client_data->key_base64, strlen(client_data->key_base64), ""); @@ -373,6 +379,13 @@ void* ssh_client_thread(void* data) { /* On failure, attempt with passphrase */ if (client_data->key == NULL) { + /* Log failure of initial attempt */ + guac_client_log(client, GUAC_LOG_DEBUG, + "Initial import failed: %s", ssh_key_error()); + + guac_client_log(client, GUAC_LOG_DEBUG, + "Re-attempting private key import (WITH passphrase)"); + /* Prompt for passphrase if missing */ if (client_data->key_passphrase[0] == 0) guac_terminal_prompt(client_data->term, "Key passphrase: ", @@ -385,7 +398,9 @@ void* ssh_client_thread(void* data) { /* If still failing, give up */ if (client_data->key == NULL) { - guac_client_log(client, GUAC_LOG_ERROR, "Auth key import failed."); + guac_client_abort(client, + GUAC_PROTOCOL_STATUS_CLIENT_UNAUTHORIZED, + "Auth key import failed: %s", ssh_key_error()); return NULL; } diff --git a/src/protocols/ssh/ssh_key.c b/src/protocols/ssh/ssh_key.c index 0097f980..4e532af8 100644 --- a/src/protocols/ssh/ssh_key.c +++ b/src/protocols/ssh/ssh_key.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -133,6 +134,13 @@ ssh_key* ssh_key_alloc(char* data, int length, char* passphrase) { } +const char* ssh_key_error() { + + /* Return static error string */ + return ERR_reason_error_string(ERR_get_error()); + +} + void ssh_key_free(ssh_key* key) { /* Free key-specific data */ diff --git a/src/protocols/ssh/ssh_key.h b/src/protocols/ssh/ssh_key.h index 6291aa11..1e7e7970 100644 --- a/src/protocols/ssh/ssh_key.h +++ b/src/protocols/ssh/ssh_key.h @@ -113,6 +113,15 @@ typedef struct ssh_key { */ ssh_key* ssh_key_alloc(char* data, int length, char* passphrase); +/** + * Returns a statically-allocated string describing the most recent SSH key + * error. + * + * @return + * A statically-allocated string describing the most recent SSH key error. + */ +const char* ssh_key_error(); + /** * Frees all memory associated with the given key. */