From e8b98abfc46b6413a6449fcb713f116ff1f82cf5 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 19 Oct 2015 15:58:44 -0700 Subject: [PATCH] GUAC-1038: Add support for running specific commands via SSH (instead of a shell). --- src/protocols/ssh/client.c | 11 +++++++++++ src/protocols/ssh/client.h | 6 ++++++ src/protocols/ssh/guac_handlers.c | 3 +++ src/protocols/ssh/ssh_client.c | 16 +++++++++++++--- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/protocols/ssh/client.c b/src/protocols/ssh/client.c index 3183e22e..f294363d 100644 --- a/src/protocols/ssh/client.c +++ b/src/protocols/ssh/client.c @@ -57,6 +57,7 @@ const char* GUAC_CLIENT_ARGS[] = { "enable-agent", #endif "color-scheme", + "command", NULL }; @@ -122,6 +123,12 @@ enum __SSH_ARGS_IDX { */ IDX_COLOR_SCHEME, + /** + * The command to run instead if the default shell. If omitted, a normal + * shell session will be created. + */ + IDX_COMMAND, + SSH_ARGS_COUNT }; @@ -178,6 +185,10 @@ int guac_client_init(guac_client* client, int argc, char** argv) { else strcpy(client_data->port, GUAC_SSH_DEFAULT_PORT); + /* Read command, if any */ + if (argv[IDX_COMMAND][0] != 0) + client_data->command = strdup(argv[IDX_COMMAND]); + /* Create terminal */ client_data->term = guac_terminal_create(client, client_data->font_name, client_data->font_size, diff --git a/src/protocols/ssh/client.h b/src/protocols/ssh/client.h index 364fca2f..32e297c4 100644 --- a/src/protocols/ssh/client.h +++ b/src/protocols/ssh/client.h @@ -78,6 +78,12 @@ typedef struct ssh_guac_client_data { */ char key_passphrase[1024]; + /** + * The command to run instead of the default shell. If a normal shell + * session is desired, this will be NULL. + */ + char* command; + /** * The name of the font to use for display rendering. */ diff --git a/src/protocols/ssh/guac_handlers.c b/src/protocols/ssh/guac_handlers.c index e18c5d5d..3b1ce2ce 100644 --- a/src/protocols/ssh/guac_handlers.c +++ b/src/protocols/ssh/guac_handlers.c @@ -116,6 +116,9 @@ int ssh_guac_client_free_handler(guac_client* client) { if (guac_client_data->user != NULL) guac_common_ssh_destroy_user(guac_client_data->user); + /* Free copied settings */ + free(guac_client_data->command); + /* Free generic data struct */ free(client->data); diff --git a/src/protocols/ssh/ssh_client.c b/src/protocols/ssh/ssh_client.c index 6c089252..ffab21ac 100644 --- a/src/protocols/ssh/ssh_client.c +++ b/src/protocols/ssh/ssh_client.c @@ -264,9 +264,19 @@ void* ssh_client_thread(void* data) { return NULL; } - /* Request shell */ - if (libssh2_channel_shell(client_data->term_channel)) { - guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to associate shell with PTY."); + /* If a command is specified, run that instead of a shell */ + if (client_data->command != NULL) { + if (libssh2_channel_exec(client_data->term_channel, client_data->command)) { + guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, + "Unable to execute command."); + return NULL; + } + } + + /* Otherwise, request a shell */ + else if (libssh2_channel_shell(client_data->term_channel)) { + guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, + "Unable to associate shell with PTY."); return NULL; }