From 9f6958accf6e67a5a71a706443829a3aa328378f Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Mon, 26 Aug 2024 16:26:07 -0400 Subject: [PATCH 1/2] GUACAMOLE-1290: Add public key parameter for SFTP connections in RDP and VNC protocols. --- src/protocols/rdp/rdp.c | 27 +++++++++++++++++++++++++++ src/protocols/rdp/settings.c | 15 ++++++++++++++- src/protocols/rdp/settings.h | 5 +++++ src/protocols/vnc/settings.c | 13 +++++++++++++ src/protocols/vnc/settings.h | 6 ++++++ src/protocols/vnc/vnc.c | 27 +++++++++++++++++++++++++++ 6 files changed, 92 insertions(+), 1 deletion(-) diff --git a/src/protocols/rdp/rdp.c b/src/protocols/rdp/rdp.c index b29c7c631..4cf8e5f4f 100644 --- a/src/protocols/rdp/rdp.c +++ b/src/protocols/rdp/rdp.c @@ -800,6 +800,33 @@ void* guac_rdp_client_thread(void* data) { return NULL; } + /* Import the public key, if that is specified. */ + if (settings->sftp_public_key != NULL) { + + guac_client_log(client, GUAC_LOG_DEBUG, + "Attempting public key import"); + + /* Attempt to read public key */ + if (guac_common_ssh_user_import_public_key(rdp_client->sftp_user, + settings->sftp_public_key)) { + + /* Public key import fails. */ + guac_client_abort(client, + GUAC_PROTOCOL_STATUS_CLIENT_UNAUTHORIZED, + "Failed to import public key: %s", + guac_common_ssh_key_error()); + + guac_common_ssh_destroy_user(rdp_client->sftp_user); + return NULL; + + } + + /* Success */ + guac_client_log(client, GUAC_LOG_INFO, + "Public key successfully imported."); + + } + } /* Otherwise, use specified password */ diff --git a/src/protocols/rdp/settings.c b/src/protocols/rdp/settings.c index 548345cc7..d8567a732 100644 --- a/src/protocols/rdp/settings.c +++ b/src/protocols/rdp/settings.c @@ -111,6 +111,7 @@ const char* GUAC_RDP_CLIENT_ARGS[] = { "sftp-password", "sftp-private-key", "sftp-passphrase", + "sftp-public-key", "sftp-directory", "sftp-root-directory", "sftp-server-alive-interval", @@ -492,6 +493,12 @@ enum RDP_ARGS_IDX { */ IDX_SFTP_PASSPHRASE, + /** + * The base64-encoded public key to use when authenticating with the SSH + * server for SFTP. + */ + IDX_SFTP_PUBLIC_KEY, + /** * The default location for file uploads within the SSH server. This will * apply only to uploads which do not use the filesystem guac_object (where @@ -1126,11 +1133,16 @@ guac_rdp_settings* guac_rdp_parse_args(guac_user* user, guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_SFTP_PRIVATE_KEY, NULL); - /* Passphrase for decrypting the SFTP private key (if applicable */ + /* Passphrase for decrypting the SFTP private key (if applicable) */ settings->sftp_passphrase = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_SFTP_PASSPHRASE, ""); + /* Public key for authenticating to SFTP server, if applicable. */ + settings->sftp_public_key = + guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, + IDX_SFTP_PUBLIC_KEY, NULL); + /* Default upload directory */ settings->sftp_directory = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, @@ -1397,6 +1409,7 @@ void guac_rdp_settings_free(guac_rdp_settings* settings) { guac_mem_free(settings->sftp_password); guac_mem_free(settings->sftp_port); guac_mem_free(settings->sftp_private_key); + guac_mem_free(settings->sftp_public_key); guac_mem_free(settings->sftp_username); #endif diff --git a/src/protocols/rdp/settings.h b/src/protocols/rdp/settings.h index cedbee950..2f4d6ef94 100644 --- a/src/protocols/rdp/settings.h +++ b/src/protocols/rdp/settings.h @@ -497,6 +497,11 @@ typedef struct guac_rdp_settings { */ char* sftp_passphrase; + /** + * The public key to use when connecting to the SFTP server, if applicable. + */ + char* sftp_public_key; + /** * The default location for file uploads within the SSH server. This will * apply only to uploads which do not use the filesystem guac_object (where diff --git a/src/protocols/vnc/settings.c b/src/protocols/vnc/settings.c index bfdcbf82e..5b7df0bac 100644 --- a/src/protocols/vnc/settings.c +++ b/src/protocols/vnc/settings.c @@ -73,6 +73,7 @@ const char* GUAC_VNC_CLIENT_ARGS[] = { "sftp-password", "sftp-private-key", "sftp-passphrase", + "sftp-public-key", "sftp-directory", "sftp-root-directory", "sftp-server-alive-interval", @@ -272,6 +273,12 @@ enum VNC_ARGS_IDX { */ IDX_SFTP_PASSPHRASE, + /** + * The base64-encode public key to use when authentication with the SSH + * server for SFTP using key-based authentication. + */ + IDX_SFTP_PUBLIC_KEY, + /** * The default location for file uploads within the SSH server. This will * apply only to uploads which do not use the filesystem guac_object (where @@ -608,6 +615,11 @@ guac_vnc_settings* guac_vnc_parse_args(guac_user* user, guac_user_parse_args_string(user, GUAC_VNC_CLIENT_ARGS, argv, IDX_SFTP_PASSPHRASE, ""); + /* Public key for SFTP using key-based authentication. */ + settings->sftp_public_key = + guac_user_parse_args_string(user, GUAC_VNC_CLIENT_ARGS, argv, + IDX_SFTP_PUBLIC_KEY, NULL); + /* Default upload directory */ settings->sftp_directory = guac_user_parse_args_string(user, GUAC_VNC_CLIENT_ARGS, argv, @@ -743,6 +755,7 @@ void guac_vnc_settings_free(guac_vnc_settings* settings) { guac_mem_free(settings->sftp_password); guac_mem_free(settings->sftp_port); guac_mem_free(settings->sftp_private_key); + guac_mem_free(settings->sftp_public_key); guac_mem_free(settings->sftp_username); #endif diff --git a/src/protocols/vnc/settings.h b/src/protocols/vnc/settings.h index 9b27463b6..f433df9bf 100644 --- a/src/protocols/vnc/settings.h +++ b/src/protocols/vnc/settings.h @@ -222,6 +222,12 @@ typedef struct guac_vnc_settings { */ char* sftp_passphrase; + /** + * The base64-encoded public key to use when authenticating with the SSH + * server for SFTP using key-based authentication. + */ + char* sftp_public_key; + /** * The default location for file uploads within the SSH server. This will * apply only to uploads which do not use the filesystem guac_object (where diff --git a/src/protocols/vnc/vnc.c b/src/protocols/vnc/vnc.c index 517237da7..d244dcb9f 100644 --- a/src/protocols/vnc/vnc.c +++ b/src/protocols/vnc/vnc.c @@ -397,6 +397,33 @@ void* guac_vnc_client_thread(void* data) { return NULL; } + /* Import the public key, if that is specified. */ + if (settings->sftp_public_key != NULL) { + + guac_client_log(client, GUAC_LOG_DEBUG, + "Attempting public key import"); + + /* Attempt to read public key */ + if (guac_common_ssh_user_import_public_key(vnc_client->sftp_user, + settings->sftp_public_key)) { + + /* Public key import fails. */ + guac_client_abort(client, + GUAC_PROTOCOL_STATUS_CLIENT_UNAUTHORIZED, + "Failed to import public key: %s", + guac_common_ssh_key_error()); + + guac_common_ssh_destroy_user(vnc_client->sftp_user); + return NULL; + + } + + /* Success */ + guac_client_log(client, GUAC_LOG_INFO, + "Public key successfully imported."); + + } + } /* Otherwise, use specified password */ From 5e0ce1db8fe7c0c761c62f42b7cea0b0f3c9608c Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Mon, 26 Aug 2024 16:28:32 -0400 Subject: [PATCH 2/2] GUACAMOLE-1290: Move public key import in SSH connection code. --- src/protocols/ssh/ssh.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/protocols/ssh/ssh.c b/src/protocols/ssh/ssh.c index 5a0a7e742..199064de6 100644 --- a/src/protocols/ssh/ssh.c +++ b/src/protocols/ssh/ssh.c @@ -134,33 +134,34 @@ static guac_common_ssh_user* guac_ssh_get_user(guac_client* client) { guac_client_log(client, GUAC_LOG_INFO, "Auth key successfully imported."); - } /* end if key given */ + /* Import public key, if available. */ + if (settings->public_key_base64 != NULL) { - if (settings->public_key_base64 != NULL) { + guac_client_log(client, GUAC_LOG_DEBUG, + "Attempting public key import"); - guac_client_log(client, GUAC_LOG_DEBUG, - "Attempting public key import"); + /* Attempt to read public key */ + if (guac_common_ssh_user_import_public_key(user, + settings->public_key_base64)) { - /* Attempt to read public key */ - if (guac_common_ssh_user_import_public_key(user, - settings->public_key_base64)) { + /* Public key import fails. */ + guac_client_abort(client, + GUAC_PROTOCOL_STATUS_CLIENT_UNAUTHORIZED, + "Auth public key import failed: %s", + guac_common_ssh_key_error()); - /* If failing*/ - guac_client_abort(client, - GUAC_PROTOCOL_STATUS_CLIENT_UNAUTHORIZED, - "Auth public key import failed: %s", - guac_common_ssh_key_error()); + guac_common_ssh_destroy_user(user); + return NULL; - guac_common_ssh_destroy_user(user); - return NULL; + } - } + /* Success */ + guac_client_log(client, GUAC_LOG_INFO, + "Auth public key successfully imported."); - /* Success */ - guac_client_log(client, GUAC_LOG_INFO, - "Auth public key successfully imported."); + } - } + } /* end if key given */ /* If available, get password from settings */ else if (settings->password != NULL) {