Add abort instruction. Add status codes to abort and error.
This commit is contained in:
parent
72d29f18fd
commit
cec58edef3
@ -53,6 +53,66 @@
|
|||||||
* @file protocol.h
|
* @file protocol.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set of all possible status codes returned by protocol operations. These
|
||||||
|
* codes relate to Guacamole server/client communication, and not to internal
|
||||||
|
* communicatin of errors within libguac and linked software.
|
||||||
|
*
|
||||||
|
* In general:
|
||||||
|
*
|
||||||
|
* 0x0000 - 0x00FF: Successful operations
|
||||||
|
* 0x0100 - 0x01FF: Operations that failed due to implementation status
|
||||||
|
* 0x0200 - 0x02FF: Operations that failed due to environmental errors
|
||||||
|
* 0x0300 - 0x03FF: Operations that failed due to user action
|
||||||
|
*/
|
||||||
|
typedef enum guac_protocol_status {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The operation succeeded.
|
||||||
|
*/
|
||||||
|
GUAC_PROTOCOL_STATUS_SUCCESS = 0x0000,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The requested operation is unsupported.
|
||||||
|
*/
|
||||||
|
GUAC_PROTOCOL_STATUS_UNSUPPORTED = 0x0100,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permission was denied to perform the operation.
|
||||||
|
*/
|
||||||
|
GUAC_PROTOCOL_STATUS_PERMISSION_DENIED = 0x0200,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The operation could not be performed due to an internal failure of a
|
||||||
|
* related resource or function.
|
||||||
|
*/
|
||||||
|
GUAC_PROTOCOL_STATUS_INTERNAL_ERROR = 0x0201,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The operation could not be performed due to timeout of a related
|
||||||
|
* server-side resource.
|
||||||
|
*/
|
||||||
|
GUAC_PROTOCOL_STATUS_SERVER_TIMEOUT = 0x0202,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The operation was canceled. The an operation may be canceled for any
|
||||||
|
* reason.
|
||||||
|
*/
|
||||||
|
GUAC_PROTOCOL_STATUS_CANCELED = 0x0300,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The operation was unsuccessful due to faulty user input.
|
||||||
|
*/
|
||||||
|
GUAC_PROTOCOL_STATUS_INVALID_PARAMETER = 0x0301,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The operation could not be performed due to timeout of a related
|
||||||
|
* client-side resource.
|
||||||
|
*/
|
||||||
|
GUAC_PROTOCOL_STATUS_CLIENT_TIMEOUT = 0x0302
|
||||||
|
|
||||||
|
} guac_protocol_status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Composite modes used by Guacamole draw instructions. Each
|
* Composite modes used by Guacamole draw instructions. Each
|
||||||
* composite mode maps to a unique channel mask integer.
|
* composite mode maps to a unique channel mask integer.
|
||||||
@ -211,10 +271,12 @@ int guac_protocol_send_disconnect(guac_socket* socket);
|
|||||||
* returned, and guac_error is set appropriately.
|
* returned, and guac_error is set appropriately.
|
||||||
*
|
*
|
||||||
* @param socket The guac_socket connection to use.
|
* @param socket The guac_socket connection to use.
|
||||||
* @param error The description associated with the error.
|
* @param error The human-readable description associated with the error.
|
||||||
|
* @param status The status code related to the error.
|
||||||
* @return Zero on success, non-zero on error.
|
* @return Zero on success, non-zero on error.
|
||||||
*/
|
*/
|
||||||
int guac_protocol_send_error(guac_socket* socket, const char* error);
|
int guac_protocol_send_error(guac_socket* socket, const char* error,
|
||||||
|
guac_protocol_status status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a nest instruction over the given guac_socket connection.
|
* Sends a nest instruction over the given guac_socket connection.
|
||||||
@ -334,6 +396,22 @@ int guac_protocol_send_file(guac_socket* socket, const guac_stream* stream,
|
|||||||
int guac_protocol_send_blob(guac_socket* socket, const guac_stream* stream,
|
int guac_protocol_send_blob(guac_socket* socket, const guac_stream* stream,
|
||||||
void* data, int count);
|
void* data, int count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends an abort instruction over the given guac_socket connection.
|
||||||
|
*
|
||||||
|
* If an error occurs sending the instruction, a non-zero value is
|
||||||
|
* returned, and guac_error is set appropriately.
|
||||||
|
*
|
||||||
|
* @param socket The guac_socket connection to use.
|
||||||
|
* @param stream The stream to use.
|
||||||
|
* @param reason The human-readable reason the stream is being aborted.
|
||||||
|
* @param status The status associated with the reason the stream being
|
||||||
|
* aborted.
|
||||||
|
* @return Zero on success, non-zero on error.
|
||||||
|
*/
|
||||||
|
int guac_protocol_send_abort(guac_socket* socket, const guac_stream* stream,
|
||||||
|
const char* reason, guac_protocol_status status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends an end instruction over the given guac_socket connection.
|
* Sends an end instruction over the given guac_socket connection.
|
||||||
*
|
*
|
||||||
|
@ -355,6 +355,26 @@ int __guac_socket_write_length_png(guac_socket* socket, cairo_surface_t* surface
|
|||||||
|
|
||||||
/* Protocol functions */
|
/* Protocol functions */
|
||||||
|
|
||||||
|
int guac_protocol_send_abort(guac_socket* socket, const guac_stream* stream,
|
||||||
|
const char* reason, guac_protocol_status status) {
|
||||||
|
|
||||||
|
int ret_val;
|
||||||
|
|
||||||
|
guac_socket_instruction_begin(socket);
|
||||||
|
ret_val =
|
||||||
|
guac_socket_write_string(socket, "5.abort,")
|
||||||
|
|| __guac_socket_write_length_int(socket, stream->index)
|
||||||
|
|| guac_socket_write_string(socket, ",")
|
||||||
|
|| __guac_socket_write_length_string(socket, reason)
|
||||||
|
|| guac_socket_write_string(socket, ",")
|
||||||
|
|| __guac_socket_write_length_int(socket, status)
|
||||||
|
|| guac_socket_write_string(socket, ";");
|
||||||
|
|
||||||
|
guac_socket_instruction_end(socket);
|
||||||
|
return ret_val;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static int __guac_protocol_send_args(guac_socket* socket, const char** args) {
|
static int __guac_protocol_send_args(guac_socket* socket, const char** args) {
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
@ -751,7 +771,6 @@ int guac_protocol_send_distort(guac_socket* socket, const guac_layer* layer,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int guac_protocol_send_end(guac_socket* socket, const guac_stream* stream) {
|
int guac_protocol_send_end(guac_socket* socket, const guac_stream* stream) {
|
||||||
|
|
||||||
int ret_val;
|
int ret_val;
|
||||||
@ -768,7 +787,8 @@ int guac_protocol_send_end(guac_socket* socket, const guac_stream* stream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int guac_protocol_send_error(guac_socket* socket, const char* error) {
|
int guac_protocol_send_error(guac_socket* socket, const char* error,
|
||||||
|
guac_protocol_status status) {
|
||||||
|
|
||||||
int ret_val;
|
int ret_val;
|
||||||
|
|
||||||
@ -776,6 +796,8 @@ int guac_protocol_send_error(guac_socket* socket, const char* error) {
|
|||||||
ret_val =
|
ret_val =
|
||||||
guac_socket_write_string(socket, "5.error,")
|
guac_socket_write_string(socket, "5.error,")
|
||||||
|| __guac_socket_write_length_string(socket, error)
|
|| __guac_socket_write_length_string(socket, error)
|
||||||
|
|| guac_socket_write_string(socket, ",")
|
||||||
|
|| __guac_socket_write_length_int(socket, status)
|
||||||
|| guac_socket_write_string(socket, ";");
|
|| guac_socket_write_string(socket, ";");
|
||||||
|
|
||||||
guac_socket_instruction_end(socket);
|
guac_socket_instruction_end(socket);
|
||||||
|
@ -260,7 +260,9 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) {
|
|||||||
|
|
||||||
/* Init channels (pre-connect) */
|
/* Init channels (pre-connect) */
|
||||||
if (freerdp_channels_pre_connect(channels, instance)) {
|
if (freerdp_channels_pre_connect(channels, instance)) {
|
||||||
guac_protocol_send_error(client->socket, "Error initializing RDP client channel manager");
|
guac_protocol_send_error(client->socket,
|
||||||
|
"Error initializing RDP client channel manager",
|
||||||
|
GUAC_PROTOCOL_STATUS_INTERNAL_ERROR);
|
||||||
guac_socket_flush(client->socket);
|
guac_socket_flush(client->socket);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -277,7 +279,9 @@ BOOL rdp_freerdp_post_connect(freerdp* instance) {
|
|||||||
|
|
||||||
/* Init channels (post-connect) */
|
/* Init channels (post-connect) */
|
||||||
if (freerdp_channels_post_connect(channels, instance)) {
|
if (freerdp_channels_post_connect(channels, instance)) {
|
||||||
guac_protocol_send_error(client->socket, "Error initializing RDP client channel manager");
|
guac_protocol_send_error(client->socket,
|
||||||
|
"Error initializing RDP client channel manager",
|
||||||
|
GUAC_PROTOCOL_STATUS_INTERNAL_ERROR);
|
||||||
guac_socket_flush(client->socket);
|
guac_socket_flush(client->socket);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -374,7 +378,8 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
|
|||||||
if (argc != RDP_ARGS_COUNT) {
|
if (argc != RDP_ARGS_COUNT) {
|
||||||
|
|
||||||
guac_protocol_send_error(client->socket,
|
guac_protocol_send_error(client->socket,
|
||||||
"Wrong argument count received.");
|
"Wrong argument count received.",
|
||||||
|
GUAC_PROTOCOL_STATUS_INVALID_PARAMETER);
|
||||||
guac_socket_flush(client->socket);
|
guac_socket_flush(client->socket);
|
||||||
|
|
||||||
guac_error = GUAC_STATUS_BAD_ARGUMENT;
|
guac_error = GUAC_STATUS_BAD_ARGUMENT;
|
||||||
@ -603,7 +608,8 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
|
|||||||
if (!freerdp_connect(rdp_inst)) {
|
if (!freerdp_connect(rdp_inst)) {
|
||||||
|
|
||||||
guac_protocol_send_error(client->socket,
|
guac_protocol_send_error(client->socket,
|
||||||
"Error connecting to RDP server");
|
"Error connecting to RDP server",
|
||||||
|
GUAC_PROTOCOL_STATUS_INTERNAL_ERROR);
|
||||||
guac_socket_flush(client->socket);
|
guac_socket_flush(client->socket);
|
||||||
|
|
||||||
guac_error = GUAC_STATUS_BAD_STATE;
|
guac_error = GUAC_STATUS_BAD_STATE;
|
||||||
|
@ -95,7 +95,8 @@ int ssh_guac_client_handle_messages(guac_client* client) {
|
|||||||
|
|
||||||
/* Notify on error */
|
/* Notify on error */
|
||||||
if (bytes_read < 0) {
|
if (bytes_read < 0) {
|
||||||
guac_protocol_send_error(socket, "Error reading data.");
|
guac_protocol_send_error(socket, "Error reading data.",
|
||||||
|
GUAC_PROTOCOL_STATUS_INTERNAL_ERROR);
|
||||||
guac_socket_flush(socket);
|
guac_socket_flush(socket);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,8 @@ void* ssh_client_thread(void* data) {
|
|||||||
/* Open SSH session */
|
/* Open SSH session */
|
||||||
client_data->session = ssh_new();
|
client_data->session = ssh_new();
|
||||||
if (client_data->session == NULL) {
|
if (client_data->session == NULL) {
|
||||||
guac_protocol_send_error(socket, "Unable to create SSH session.");
|
guac_protocol_send_error(socket, "Unable to create SSH session.",
|
||||||
|
GUAC_PROTOCOL_STATUS_INTERNAL_ERROR);
|
||||||
guac_socket_flush(socket);
|
guac_socket_flush(socket);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -174,14 +175,16 @@ void* ssh_client_thread(void* data) {
|
|||||||
|
|
||||||
/* Connect */
|
/* Connect */
|
||||||
if (ssh_connect(client_data->session) != SSH_OK) {
|
if (ssh_connect(client_data->session) != SSH_OK) {
|
||||||
guac_protocol_send_error(socket, "Unable to connect via SSH.");
|
guac_protocol_send_error(socket, "Unable to connect via SSH.",
|
||||||
|
GUAC_PROTOCOL_STATUS_INTERNAL_ERROR);
|
||||||
guac_socket_flush(socket);
|
guac_socket_flush(socket);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Authenticate */
|
/* Authenticate */
|
||||||
if (ssh_userauth_password(client_data->session, NULL, client_data->password) != SSH_AUTH_SUCCESS) {
|
if (ssh_userauth_password(client_data->session, NULL, client_data->password) != SSH_AUTH_SUCCESS) {
|
||||||
guac_protocol_send_error(socket, "SSH auth failed.");
|
guac_protocol_send_error(socket, "SSH auth failed.",
|
||||||
|
GUAC_PROTOCOL_STATUS_PERMISSION_DENIED);
|
||||||
guac_socket_flush(socket);
|
guac_socket_flush(socket);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -189,14 +192,16 @@ void* ssh_client_thread(void* data) {
|
|||||||
/* Open channel for terminal */
|
/* Open channel for terminal */
|
||||||
client_data->term_channel = channel_new(client_data->session);
|
client_data->term_channel = channel_new(client_data->session);
|
||||||
if (client_data->term_channel == NULL) {
|
if (client_data->term_channel == NULL) {
|
||||||
guac_protocol_send_error(socket, "Unable to open channel.");
|
guac_protocol_send_error(socket, "Unable to open channel.",
|
||||||
|
GUAC_PROTOCOL_STATUS_INTERNAL_ERROR);
|
||||||
guac_socket_flush(socket);
|
guac_socket_flush(socket);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open session for channel */
|
/* Open session for channel */
|
||||||
if (channel_open_session(client_data->term_channel) != SSH_OK) {
|
if (channel_open_session(client_data->term_channel) != SSH_OK) {
|
||||||
guac_protocol_send_error(socket, "Unable to open channel session.");
|
guac_protocol_send_error(socket, "Unable to open channel session.",
|
||||||
|
GUAC_PROTOCOL_STATUS_INTERNAL_ERROR);
|
||||||
guac_socket_flush(socket);
|
guac_socket_flush(socket);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -204,14 +209,16 @@ void* ssh_client_thread(void* data) {
|
|||||||
/* Request PTY */
|
/* Request PTY */
|
||||||
if (channel_request_pty_size(client_data->term_channel, "linux",
|
if (channel_request_pty_size(client_data->term_channel, "linux",
|
||||||
client_data->term->term_width, client_data->term->term_height) != SSH_OK) {
|
client_data->term->term_width, client_data->term->term_height) != SSH_OK) {
|
||||||
guac_protocol_send_error(socket, "Unable to allocate PTY for channel.");
|
guac_protocol_send_error(socket, "Unable to allocate PTY for channel.",
|
||||||
|
GUAC_PROTOCOL_STATUS_INTERNAL_ERROR);
|
||||||
guac_socket_flush(socket);
|
guac_socket_flush(socket);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Request shell */
|
/* Request shell */
|
||||||
if (channel_request_shell(client_data->term_channel) != SSH_OK) {
|
if (channel_request_shell(client_data->term_channel) != SSH_OK) {
|
||||||
guac_protocol_send_error(socket, "Unable to associate shell with PTY.");
|
guac_protocol_send_error(socket, "Unable to associate shell with PTY.",
|
||||||
|
GUAC_PROTOCOL_STATUS_INTERNAL_ERROR);
|
||||||
guac_socket_flush(socket);
|
guac_socket_flush(socket);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -207,7 +207,9 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
|
|||||||
/*** PARSE ARGUMENTS ***/
|
/*** PARSE ARGUMENTS ***/
|
||||||
|
|
||||||
if (argc != VNC_ARGS_COUNT) {
|
if (argc != VNC_ARGS_COUNT) {
|
||||||
guac_protocol_send_error(client->socket, "Wrong argument count received.");
|
guac_protocol_send_error(client->socket,
|
||||||
|
"Wrong argument count received.",
|
||||||
|
GUAC_PROTOCOL_STATUS_INVALID_PARAMETER);
|
||||||
guac_socket_flush(client->socket);
|
guac_socket_flush(client->socket);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -290,7 +292,8 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
|
|||||||
/* If the final connect attempt fails, return error */
|
/* If the final connect attempt fails, return error */
|
||||||
if (!rfb_client) {
|
if (!rfb_client) {
|
||||||
guac_protocol_send_error(client->socket,
|
guac_protocol_send_error(client->socket,
|
||||||
"Error initializing VNC client");
|
"Error initializing VNC client",
|
||||||
|
GUAC_PROTOCOL_STATUS_INTERNAL_ERROR);
|
||||||
guac_socket_flush(client->socket);
|
guac_socket_flush(client->socket);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user