diff --git a/src/protocols/ssh/ssh.c b/src/protocols/ssh/ssh.c index 9881c304..ace5d6fa 100644 --- a/src/protocols/ssh/ssh.c +++ b/src/protocols/ssh/ssh.c @@ -192,7 +192,6 @@ void* ssh_client_thread(void* data) { return NULL; } - /* Initialize a ttymode array */ const int num_tty_opcodes = 1; char ssh_ttymodes[(GUAC_SSH_TTY_OPCODE_SIZE * num_tty_opcodes) + 1]; @@ -302,13 +301,15 @@ void* ssh_client_thread(void* data) { } /* Set up the ttymode array prior to requesting the PTY */ - if (guac_ssh_ttymodes_init(ssh_ttymodes, sizeof(ssh_ttymodes), - num_tty_opcodes, (guac_ssh_ttymode){ GUAC_SSH_TTY_OP_VERASE, settings->backspace})) - guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Error configuring TTY mode encoding."); + int ttymodeBytes = guac_ssh_ttymodes_init(ssh_ttymodes, sizeof(ssh_ttymodes), + GUAC_SSH_TTY_OP_VERASE, settings->backspace, GUAC_SSH_TTY_OP_END); + if (ttymodeBytes < 1) + guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Error storing TTY mode encoding \ + opcodes and values in array."); /* Request PTY */ if (libssh2_channel_request_pty_ex(ssh_client->term_channel, "linux", sizeof("linux")-1, - ssh_ttymodes, sizeof(ssh_ttymodes), ssh_client->term->term_width, + ssh_ttymodes, ttymodeBytes, ssh_client->term->term_width, ssh_client->term->term_height, 0, 0)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to allocate PTY."); return NULL; diff --git a/src/protocols/ssh/ttymode.c b/src/protocols/ssh/ttymode.c index 4526cc1f..9f60859d 100644 --- a/src/protocols/ssh/ttymode.c +++ b/src/protocols/ssh/ttymode.c @@ -21,38 +21,49 @@ #include "ttymode.h" #include +#include #include #include int guac_ssh_ttymodes_init(char opcode_array[], const int array_size, - const int num_opcodes, ...) { + ...) { /* Initialize the variable argument list. */ va_list args; - va_start(args, num_opcodes); - - /* Check to make sure the array has enough space. - We need one extra byte at the end for the ending opcode. */ - if ((num_opcodes * GUAC_SSH_TTY_OPCODE_SIZE) >= (array_size)) - return 1; + va_start(args, array_size); + /* Initialize array pointer and byte counter. */ char *current = opcode_array; - for (int i = 0; i < num_opcodes; i++) { + int bytes = 0; - /* Get the next argument to this function */ - guac_ssh_ttymode* ttymode = va_arg(args, guac_ssh_ttymode*); + /* Loop through variable argument list. */ + while (true) { + + /* Check to make sure we don't overrun array. */ + if (bytes >= array_size) + return -1; - /* Place opcode and value in array */ - *(current++) = ttymode->opcode; - *(current++) = (ttymode->value >> 24) & 0xFF; - *(current++) = (ttymode->value >> 16) & 0xFF; - *(current++) = (ttymode->value >> 8) & 0xFF; - *(current++) = ttymode->value & 0xFF; + /* Next argument should be an opcode. */ + char opcode = (char)va_arg(args, int); + *(current++) = opcode; + bytes += sizeof(char); + + /* If it's the end opcode, we're done. */ + if (opcode == GUAC_SSH_TTY_OP_END) + break; + + /* Next argument should be 4-byte value. */ + uint32_t value = va_arg(args, uint32_t); + *(current++) = (value >> 24) & 0xFF; + *(current++) = (value >> 16) & 0xFF; + *(current++) = (value >> 8) & 0xFF; + *(current++) = value & 0xFF; + bytes += sizeof(uint32_t); } - /* Put the end opcode in the last opcode space */ - *(current) = GUAC_SSH_TTY_OP_END; + /* We're done processing arguments. */ + va_end(args); - return 0; + return bytes; } diff --git a/src/protocols/ssh/ttymode.h b/src/protocols/ssh/ttymode.h index 59c5415d..96bf0b49 100644 --- a/src/protocols/ssh/ttymode.h +++ b/src/protocols/ssh/ttymode.h @@ -76,9 +76,9 @@ typedef struct guac_ssh_ttymode { * in a single array, beginning with the opcode and followed * by a four byte value, repeating until the end opcode is * encountered. This function takes the array, the array - * size, expected number of opcodes, and that number of - * guac_ssh_ttymode arguments and puts them in the array - * exepcted by the SSH connection. + * size, and a variable number of opcode and value pair + * arguments and puts them in the array expected by the + * SSH connection. * * @param opcode_array * Pointer to the opcode array that will ultimately @@ -87,18 +87,15 @@ typedef struct guac_ssh_ttymode { * @param array_size * Size, in bytes, of the array. * - * @param num_opcodes - * Number of opcodes to expect. - * * @params ... - * A variable number of guac_ssh_ttymodes + * A variable number of opcode and value pairs * to place in the array. * * @return - * Zero of the function is successful, non-zero + * Number of bytes written to the array, or zero * if a failure occurs. */ int guac_ssh_ttymodes_init(char opcode_array[], const int array_size, - const int num_opcodes, ...); + ...); #endif