GUACAMOLE-269: Remove all dynamic allocation and simplify implementation.
This commit is contained in:
parent
dd7522bd9f
commit
45b832bfdc
@ -193,7 +193,8 @@ void* ssh_client_thread(void* data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize a ttymode array */
|
/* Initialize a ttymode array */
|
||||||
guac_ssh_ttymodes* ssh_ttymodes = guac_ssh_ttymodes_init(1);
|
const int num_tty_opcodes = 1;
|
||||||
|
char ssh_ttymodes[(GUAC_SSH_TTY_OPCODE_SIZE * num_tty_opcodes) + 1];
|
||||||
|
|
||||||
/* Set up screen recording, if requested */
|
/* Set up screen recording, if requested */
|
||||||
if (settings->recording_path != NULL) {
|
if (settings->recording_path != NULL) {
|
||||||
@ -212,9 +213,6 @@ void* ssh_client_thread(void* data) {
|
|||||||
settings->resolution, settings->width, settings->height,
|
settings->resolution, settings->width, settings->height,
|
||||||
settings->color_scheme, settings->backspace);
|
settings->color_scheme, settings->backspace);
|
||||||
|
|
||||||
/* Add the backspace key to the ttymode array */
|
|
||||||
guac_ssh_ttymodes_add(ssh_ttymodes, GUAC_SSH_TTY_OP_VERASE, settings->backspace);
|
|
||||||
|
|
||||||
/* Fail if terminal init failed */
|
/* Fail if terminal init failed */
|
||||||
if (ssh_client->term == NULL) {
|
if (ssh_client->term == NULL) {
|
||||||
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
|
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
|
||||||
@ -303,22 +301,19 @@ void* ssh_client_thread(void* data) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get char pointer array for TTY Mode Encoding */
|
/* Set up the ttymode array prior to requesting the PTY */
|
||||||
int ttymode_size = guac_ssh_ttymodes_size(ssh_ttymodes);
|
if (guac_ssh_ttymodes_init(ssh_ttymodes, sizeof(ssh_ttymodes),
|
||||||
char* ttymode_array = guac_ssh_ttymodes_to_array(ssh_ttymodes, ttymode_size);
|
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.");
|
||||||
|
|
||||||
/* Request PTY */
|
/* Request PTY */
|
||||||
if (libssh2_channel_request_pty_ex(ssh_client->term_channel, "linux", sizeof("linux")-1,
|
if (libssh2_channel_request_pty_ex(ssh_client->term_channel, "linux", sizeof("linux")-1,
|
||||||
ttymode_array, ttymode_size, ssh_client->term->term_width,
|
ssh_ttymodes, sizeof(ssh_ttymodes), ssh_client->term->term_width,
|
||||||
ssh_client->term->term_height, 0, 0)) {
|
ssh_client->term->term_height, 0, 0)) {
|
||||||
guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to allocate PTY.");
|
guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to allocate PTY.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We're done with TTY Mode Encoding, so free structures. */
|
|
||||||
free(ttymode_array);
|
|
||||||
free(ssh_ttymodes);
|
|
||||||
|
|
||||||
/* If a command is specified, run that instead of a shell */
|
/* If a command is specified, run that instead of a shell */
|
||||||
if (settings->command != NULL) {
|
if (settings->command != NULL) {
|
||||||
if (libssh2_channel_exec(ssh_client->term_channel, settings->command)) {
|
if (libssh2_channel_exec(ssh_client->term_channel, settings->command)) {
|
||||||
|
@ -20,58 +20,40 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "ttymode.h"
|
#include "ttymode.h"
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
guac_ssh_ttymodes* guac_ssh_ttymodes_init(int max_opcodes) {
|
int guac_ssh_ttymodes_init(char opcode_array[], const int array_size,
|
||||||
/* Allocate enough space for the max opcodes */
|
const int num_opcodes, ...) {
|
||||||
guac_ssh_ttymode* ttymode_array = malloc(sizeof(guac_ssh_ttymode) * max_opcodes);
|
|
||||||
|
|
||||||
/* Set up the initial data structure. */
|
/* Initialize the variable argument list. */
|
||||||
guac_ssh_ttymodes* empty_modes = malloc(sizeof(guac_ssh_ttymodes));
|
va_list args;
|
||||||
empty_modes->ttymode_array = ttymode_array;
|
va_start(args, num_opcodes);
|
||||||
empty_modes->num_opcodes = 0;
|
|
||||||
|
|
||||||
return empty_modes;
|
/* 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;
|
||||||
|
|
||||||
void guac_ssh_ttymodes_add(guac_ssh_ttymodes *tty_modes, char opcode, uint32_t value) {
|
for (int i = 0; i < num_opcodes; i++) {
|
||||||
/* Increment number of opcodes */
|
/* Calculate offset in array */
|
||||||
tty_modes->num_opcodes++;
|
int offset = i * GUAC_SSH_TTY_OPCODE_SIZE;
|
||||||
|
|
||||||
/* Add new values */
|
/* Get the next argument to this function */
|
||||||
tty_modes->ttymode_array[tty_modes->num_opcodes - 1].opcode = opcode;
|
guac_ssh_ttymode ttymode = va_arg(args, guac_ssh_ttymode);
|
||||||
tty_modes->ttymode_array[tty_modes->num_opcodes - 1].value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
int guac_ssh_ttymodes_size(guac_ssh_ttymodes *tty_modes) {
|
/* Place opcode and value in array */
|
||||||
/* Each opcode pair is 5 bytes (1 opcode, 4 value)
|
opcode_array[offset] = ttymode.opcode;
|
||||||
Add one for the ending opcode */
|
opcode_array[offset + 1] = (ttymode.value >> 24) & 0xFF;
|
||||||
return (tty_modes->num_opcodes * 5) + 1;
|
opcode_array[offset + 2] = (ttymode.value >> 16) & 0xFF;
|
||||||
}
|
opcode_array[offset + 3] = (ttymode.value >> 8) & 0xFF;
|
||||||
|
opcode_array[offset + 4] = ttymode.value & 0xFF;
|
||||||
char* guac_ssh_ttymodes_to_array(guac_ssh_ttymodes *tty_modes, int data_size) {
|
|
||||||
|
|
||||||
char* temp = malloc(data_size);
|
|
||||||
|
|
||||||
/* Loop through the array based on number of tracked
|
|
||||||
opcodes and convert each one. */
|
|
||||||
for (int i = 0; i < tty_modes->num_opcodes; i++) {
|
|
||||||
int idx = i * 5;
|
|
||||||
uint32_t value = tty_modes->ttymode_array[i].value;
|
|
||||||
|
|
||||||
/* Opcode goes in first byte. */
|
|
||||||
temp[idx] = tty_modes->ttymode_array[i].opcode;
|
|
||||||
|
|
||||||
/* Convert 32-bit int to individual bytes. */
|
|
||||||
temp[idx+1] = (value >> 24) & 0xFF;
|
|
||||||
temp[idx+2] = (value >> 16) & 0xFF;
|
|
||||||
temp[idx+3] = (value >> 8) & 0xFF;
|
|
||||||
temp[idx+4] = value & 0xFF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the ending opcode */
|
/* Put the end opcode in the last opcode space */
|
||||||
temp[data_size - 1] = GUAC_SSH_TTY_OP_END;
|
opcode_array[num_opcodes * GUAC_SSH_TTY_OPCODE_SIZE] = GUAC_SSH_TTY_OP_END;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
return temp;
|
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,14 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The size of a TTY mode encoding opcode and
|
||||||
|
* value pair. As defined in the SSH RFC, this
|
||||||
|
* is 5 bytes - a single byte for the opcode, and
|
||||||
|
* 4 bytes for the value.
|
||||||
|
*/
|
||||||
|
#define GUAC_SSH_TTY_OPCODE_SIZE 5
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The SSH TTY mode encoding opcode that terminates
|
* The SSH TTY mode encoding opcode that terminates
|
||||||
* the list of TTY modes.
|
* the list of TTY modes.
|
||||||
@ -31,15 +39,15 @@
|
|||||||
#define GUAC_SSH_TTY_OP_END 0
|
#define GUAC_SSH_TTY_OP_END 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The SSH tty mode encoding opcode that configures
|
* The SSH TTY mode encoding opcode that configures
|
||||||
* the TTY erase code to configure the server
|
* the TTY erase code to configure the server
|
||||||
* backspace key.
|
* backspace key.
|
||||||
*/
|
*/
|
||||||
#define GUAC_SSH_TTY_OP_VERASE 3
|
#define GUAC_SSH_TTY_OP_VERASE 3
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A data type which holds a single opcode
|
* Simple structure that defines a opcode and
|
||||||
* and the value for that opcode.
|
* value pair.
|
||||||
*/
|
*/
|
||||||
typedef struct guac_ssh_ttymode {
|
typedef struct guac_ssh_ttymode {
|
||||||
char opcode;
|
char opcode;
|
||||||
@ -47,82 +55,26 @@ typedef struct guac_ssh_ttymode {
|
|||||||
} guac_ssh_ttymode;
|
} guac_ssh_ttymode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A data type which holds an array of
|
* Initialize an array with the specified opcode/value
|
||||||
* guac_ssh_ttymode data, along with the count of
|
* pairs, and return the size, in bytes, of the array.
|
||||||
* the number of opcodes currently in the array.
|
|
||||||
*/
|
|
||||||
typedef struct guac_ssh_ttymodes {
|
|
||||||
guac_ssh_ttymode* ttymode_array;
|
|
||||||
int num_opcodes;
|
|
||||||
} guac_ssh_ttymodes;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize an empty guac_ssh_ttymodes data structure,
|
|
||||||
* with a null array of guac_ssh_ttymode and opcodes
|
|
||||||
* set to zero.
|
|
||||||
*
|
*
|
||||||
* @param max_opcodes
|
* @param opcode_array
|
||||||
* The maximum number of opcodes that will be allocated.
|
* Pointer to the opcode array.
|
||||||
|
*
|
||||||
|
* @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
|
||||||
|
* to place in the array.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* The pointer array for the gauc_ssh_ttymodes data
|
* The size, in bytes, of the array.
|
||||||
* structure generated by the function.
|
|
||||||
*/
|
*/
|
||||||
guac_ssh_ttymodes* guac_ssh_ttymodes_init(int max_opcodes);
|
int guac_ssh_ttymodes_init(char opcode_array[], const int array_size,
|
||||||
|
const int num_opcodes, ...);
|
||||||
/**
|
|
||||||
* Add an item to the opcode array. This resizes the
|
|
||||||
* array, increments the number of opcodes, and adds
|
|
||||||
* the specified opcode and value pair to the data
|
|
||||||
* structure.
|
|
||||||
*
|
|
||||||
* @param tty_modes
|
|
||||||
* The pointer to the guac_ssh_ttymodes data structure
|
|
||||||
* to add the opcode to.
|
|
||||||
*
|
|
||||||
* @param opcode
|
|
||||||
* The single byte opcode as documented in section 8
|
|
||||||
* of the SSH RFC.
|
|
||||||
*
|
|
||||||
* @param value
|
|
||||||
* The four byte value of the opcodeto add to the
|
|
||||||
* guac_ssh_ttymodes data structure.
|
|
||||||
*/
|
|
||||||
void guac_ssh_ttymodes_add(guac_ssh_ttymodes *tty_modes, char opcode, uint32_t value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the size, in bytes, of the ttymode_array
|
|
||||||
* in the given guac_ssh_ttymodes data structure.
|
|
||||||
*
|
|
||||||
* @param tty_modes
|
|
||||||
* The pointer to the guac_ssh_ttymodes structure
|
|
||||||
* whose size we are curious about.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* The number of bytes of the opcodes and value paris
|
|
||||||
* in the data structure.
|
|
||||||
*/
|
|
||||||
int guac_ssh_ttymodes_size(guac_ssh_ttymodes *tty_modes);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert the ttymodes data structure into a char
|
|
||||||
* pointer array suitable for passing into the
|
|
||||||
* libssh2_channel_request_pty_ex() function.
|
|
||||||
*
|
|
||||||
* @param tty_modes
|
|
||||||
* The pointer to the guac_ssh_ttymodes structure
|
|
||||||
* that contains the opcode and value pairs
|
|
||||||
* we want to convert to a character pointer array.
|
|
||||||
*
|
|
||||||
* @param data_size
|
|
||||||
* The size of the resulting character pointer
|
|
||||||
* array.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* The character pointer array of opcode and
|
|
||||||
* value pairs to be passed to a SSH session.
|
|
||||||
*/
|
|
||||||
char* guac_ssh_ttymodes_to_array(guac_ssh_ttymodes *tty_modes, int data_size);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user