GUACAMOLE-269: Use backspace config to set up tty modes.
This commit is contained in:
parent
46e908c06e
commit
fd58d31eea
@ -192,6 +192,9 @@ void* ssh_client_thread(void* data) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize a ttymode array */
|
||||
guac_ssh_ttymodes ssh_ttymodes = init_ttymodes();
|
||||
|
||||
/* Set up screen recording, if requested */
|
||||
if (settings->recording_path != NULL) {
|
||||
ssh_client->recording = guac_common_recording_create(client,
|
||||
@ -209,6 +212,9 @@ void* ssh_client_thread(void* data) {
|
||||
settings->resolution, settings->width, settings->height,
|
||||
settings->color_scheme, settings->backspace);
|
||||
|
||||
/* Add the backspace key to the ttymode array */
|
||||
add_ttymode(&ssh_ttymodes, GUAC_SSH_TTY_OP_VERASE, settings->backspace);
|
||||
|
||||
/* Fail if terminal init failed */
|
||||
if (ssh_client->term == NULL) {
|
||||
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
|
||||
@ -298,8 +304,8 @@ void* ssh_client_thread(void* data) {
|
||||
}
|
||||
|
||||
/* Request PTY */
|
||||
if (libssh2_channel_request_pty_ex(ssh_client->term_channel, "linux", sizeof("linux")-1, GUAC_SSH_TTY_MODES,
|
||||
sizeof(GUAC_SSH_TTY_MODES), ssh_client->term->term_width, ssh_client->term->term_height, 0, 0)) {
|
||||
if (libssh2_channel_request_pty_ex(ssh_client->term_channel, "linux", sizeof("linux")-1, ttymodes_to_array(&ssh_ttymodes),
|
||||
sizeof_ttymodes(&ssh_ttymodes), 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;
|
||||
}
|
||||
|
@ -20,8 +20,59 @@
|
||||
#include "config.h"
|
||||
#include "ttymode.h"
|
||||
|
||||
const char GUAC_SSH_TTY_MODES[6] = {
|
||||
GUAC_SSH_TTY_OP_VERASE,
|
||||
0, 0, 0, GUAC_SSH_TERM_DEFAULT_BACKSPACE,
|
||||
GUAC_SSH_TTY_OP_END
|
||||
};
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
guac_ssh_ttymodes init_ttymodes() {
|
||||
// Simple allocation for a placeholder
|
||||
guac_ssh_ttymode* ttymode_array = malloc(1);
|
||||
|
||||
// Set up the initial data structure.
|
||||
guac_ssh_ttymodes empty_modes = {
|
||||
ttymode_array,
|
||||
0
|
||||
};
|
||||
|
||||
return empty_modes;
|
||||
}
|
||||
|
||||
void add_ttymode(guac_ssh_ttymodes *tty_modes, char opcode, uint32_t value) {
|
||||
tty_modes->num_opcodes++;
|
||||
tty_modes->ttymode_array = realloc(tty_modes->ttymode_array, sizeof(guac_ssh_ttymode) * tty_modes->num_opcodes);
|
||||
tty_modes->ttymode_array[tty_modes->num_opcodes - 1].opcode = opcode;
|
||||
tty_modes->ttymode_array[tty_modes->num_opcodes - 1].value = value;
|
||||
|
||||
}
|
||||
|
||||
int sizeof_ttymodes(guac_ssh_ttymodes *tty_modes) {
|
||||
// Each opcode pair is 5 bytes (1 opcode, 4 value)
|
||||
// Add one for the ending opcode
|
||||
return (tty_modes->num_opcodes * 5) + 1;
|
||||
}
|
||||
|
||||
char* ttymodes_to_array(guac_ssh_ttymodes *tty_modes) {
|
||||
// Total data size should be number of tracked opcodes
|
||||
// plus one final byte for the TTY_OP_END code.
|
||||
int data_size = (tty_modes->num_opcodes * 5) + 1;
|
||||
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
|
||||
temp[data_size - 1] = GUAC_SSH_TTY_OP_END;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* The SSH TTY mode encoding opcode that terminates
|
||||
* the list of TTY modes.
|
||||
@ -36,17 +38,51 @@
|
||||
#define GUAC_SSH_TTY_OP_VERASE 3
|
||||
|
||||
/**
|
||||
* The default ASCII code to send for the backspace
|
||||
* key that will be sent to the SSH server.
|
||||
* A data type which holds a single opcode
|
||||
* and the value for that opcode.
|
||||
*/
|
||||
#define GUAC_SSH_TERM_DEFAULT_BACKSPACE 127
|
||||
typedef struct guac_ssh_ttymode {
|
||||
char opcode;
|
||||
uint32_t value;
|
||||
} guac_ssh_ttymode;
|
||||
|
||||
/**
|
||||
* The array of TTY mode encoding data to send to the
|
||||
* SSH server. These consist of pairs of byte codes
|
||||
* and uint32 (4-byte) values, with a 0 to terminate
|
||||
* the list.
|
||||
* A data type which holds an array of
|
||||
* guac_ssh_ttymode data, along with the count of
|
||||
* the number of opcodes currently in the array.
|
||||
*/
|
||||
extern const char GUAC_SSH_TTY_MODES[6];
|
||||
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.
|
||||
*/
|
||||
guac_ssh_ttymodes init_ttymodes();
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void add_ttymode(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.
|
||||
*/
|
||||
int sizeof_ttymodes(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.
|
||||
*/
|
||||
char* ttymodes_to_array(guac_ssh_ttymodes *tty_modes);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user