GUACAMOLE-337: Merge move of libguacd code into public libguac API.
This commit is contained in:
commit
6236eb8f98
@ -22,7 +22,6 @@ ACLOCAL_AMFLAGS = -I m4
|
||||
# Subprojects
|
||||
DIST_SUBDIRS = \
|
||||
src/libguac \
|
||||
src/libguacd \
|
||||
src/common \
|
||||
src/common-ssh \
|
||||
src/terminal \
|
||||
@ -38,7 +37,6 @@ DIST_SUBDIRS = \
|
||||
SUBDIRS = \
|
||||
src/libguac \
|
||||
src/common \
|
||||
src/libguacd \
|
||||
tests
|
||||
|
||||
if ENABLE_COMMON_SSH
|
||||
|
@ -123,10 +123,6 @@ AC_SUBST([COMMON_INCLUDE], '-I$(top_srcdir)/src/common')
|
||||
AC_SUBST([PULSE_LTLIB], '$(top_builddir)/src/pulse/libguac_pulse.la')
|
||||
AC_SUBST([PULSE_INCLUDE], '-I$(top_srcdir)/src/pulse')
|
||||
|
||||
# Common utility library for guacd implementations
|
||||
AC_SUBST([LIBGUACD_LTLIB], '$(top_builddir)/src/libguacd/libguacd.la')
|
||||
AC_SUBST([LIBGUACD_INCLUDE], '-I$(top_srcdir)/src/libguacd')
|
||||
|
||||
# Common base SSH client
|
||||
AC_SUBST([COMMON_SSH_LTLIB], '$(top_builddir)/src/common-ssh/libguac_common_ssh.la')
|
||||
AC_SUBST([COMMON_SSH_INCLUDE], '-I$(top_srcdir)/src/common-ssh')
|
||||
@ -1172,7 +1168,6 @@ AC_CONFIG_FILES([Makefile
|
||||
src/common-ssh/Makefile
|
||||
src/terminal/Makefile
|
||||
src/libguac/Makefile
|
||||
src/libguacd/Makefile
|
||||
src/guacd/Makefile
|
||||
src/guacenc/Makefile
|
||||
src/pulse/Makefile
|
||||
|
@ -49,12 +49,10 @@ guacd_SOURCES = \
|
||||
guacd_CFLAGS = \
|
||||
-Werror -Wall -pedantic \
|
||||
@COMMON_INCLUDE@ \
|
||||
@LIBGUACD_INCLUDE@ \
|
||||
@LIBGUAC_INCLUDE@
|
||||
|
||||
guacd_LDADD = \
|
||||
@COMMON_LTLIB@ \
|
||||
@LIBGUACD_LTLIB@ \
|
||||
@LIBGUAC_LTLIB@
|
||||
|
||||
guacd_LDFLAGS = \
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "connection.h"
|
||||
#include "log.h"
|
||||
#include "move-fd.h"
|
||||
#include "libguacd/user.h"
|
||||
#include "proc.h"
|
||||
#include "proc-map.h"
|
||||
|
||||
@ -36,7 +35,7 @@
|
||||
|
||||
#ifdef ENABLE_SSL
|
||||
#include <openssl/ssl.h>
|
||||
#include "libguacd/socket-ssl.h"
|
||||
#include <guacamole/socket-ssl.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "connection.h"
|
||||
#include "conf-args.h"
|
||||
#include "conf-file.h"
|
||||
#include "libguacd/user.h"
|
||||
#include "log.h"
|
||||
#include "proc-map.h"
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "common/list.h"
|
||||
#include "libguacd/user.h"
|
||||
#include "proc.h"
|
||||
#include "proc-map.h"
|
||||
|
||||
|
@ -23,11 +23,16 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "common/list.h"
|
||||
#include "libguacd/user.h"
|
||||
#include "proc.h"
|
||||
|
||||
#include <guacamole/client.h>
|
||||
|
||||
/**
|
||||
* The maximum number of concurrent connections to a single instance
|
||||
* of guacd.
|
||||
*/
|
||||
#define GUACD_CLIENT_MAX_CONNECTIONS 65536
|
||||
|
||||
/**
|
||||
* The number of hash buckets in each process map.
|
||||
*/
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "libguacd/user.h"
|
||||
#include "log.h"
|
||||
#include "move-fd.h"
|
||||
#include "proc.h"
|
||||
@ -92,7 +91,7 @@ static void* guacd_user_thread(void* data) {
|
||||
user->owner = params->owner;
|
||||
|
||||
/* Handle user connection from handshake until disconnect/completion */
|
||||
guacd_handle_user(user);
|
||||
guac_user_handle_connection(user, GUACD_USEC_TIMEOUT);
|
||||
|
||||
/* Stop client and prevent future users if all users are disconnected */
|
||||
if (client->connected_users == 0) {
|
||||
|
@ -27,6 +27,19 @@
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
/**
|
||||
* The number of milliseconds to wait for messages in any phase before
|
||||
* timing out and closing the connection with an error.
|
||||
*/
|
||||
#define GUACD_TIMEOUT 15000
|
||||
|
||||
/**
|
||||
* The number of microseconds to wait for messages in any phase before
|
||||
* timing out and closing the conncetion with an error. This is always
|
||||
* equal to GUACD_TIMEOUT * 1000.
|
||||
*/
|
||||
#define GUACD_USEC_TIMEOUT (GUACD_TIMEOUT*1000)
|
||||
|
||||
/**
|
||||
* Process information of the internal remote desktop client.
|
||||
*/
|
||||
|
@ -91,7 +91,8 @@ libguac_la_SOURCES = \
|
||||
timestamp.c \
|
||||
unicode.c \
|
||||
user.c \
|
||||
user-handlers.c
|
||||
user-handlers.c \
|
||||
user-handshake.c
|
||||
|
||||
# Compile WebP support if available
|
||||
if ENABLE_WEBP
|
||||
@ -99,6 +100,11 @@ libguac_la_SOURCES += encode-webp.c
|
||||
noinst_HEADERS += encode-webp.h
|
||||
endif
|
||||
|
||||
# SSL support
|
||||
if ENABLE_SSL
|
||||
libguac_la_SOURCES += socket-ssl.c
|
||||
libguacinc_HEADERS += guacamole/socket-ssl.h
|
||||
endif
|
||||
|
||||
libguac_la_CFLAGS = \
|
||||
-Werror -Wall -pedantic -Iguacamole
|
||||
@ -109,6 +115,7 @@ libguac_la_LDFLAGS = \
|
||||
@JPEG_LIBS@ \
|
||||
@PNG_LIBS@ \
|
||||
@PTHREAD_LIBS@ \
|
||||
@SSL_LIBS@ \
|
||||
@UUID_LIBS@ \
|
||||
@VORBIS_LIBS@ \
|
||||
@WEBP_LIBS@
|
||||
|
@ -21,9 +21,15 @@
|
||||
#ifndef __GUACD_SOCKET_SSL_H
|
||||
#define __GUACD_SOCKET_SSL_H
|
||||
|
||||
#include "config.h"
|
||||
/**
|
||||
* Provides an SSL/TLS implementation of guac_socket. This header will only be
|
||||
* available if libguac was built with SSL support.
|
||||
*
|
||||
* @file socket-ssl.h
|
||||
*/
|
||||
|
||||
#include "socket-types.h"
|
||||
|
||||
#include <guacamole/socket.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
/**
|
@ -492,6 +492,30 @@ guac_user* guac_user_alloc();
|
||||
*/
|
||||
void guac_user_free(guac_user* user);
|
||||
|
||||
/**
|
||||
* Handles all I/O for the portion of a user's Guacamole connection following
|
||||
* the initial "select" instruction, including the rest of the handshake. The
|
||||
* handshake-related properties of the given guac_user are automatically
|
||||
* populated, and guac_user_handle_instruction() is invoked for all
|
||||
* instructions received after the handshake has completed. This function
|
||||
* blocks until the connection/user is aborted or the user disconnects.
|
||||
*
|
||||
* @param user
|
||||
* The user whose handshake and entire Guacamole protocol exchange should
|
||||
* be handled. The user must already be associated with a guac_socket and
|
||||
* guac_client, and the guac_client must already be fully initialized.
|
||||
*
|
||||
* @param usec_timeout
|
||||
* The number of microseconds to wait for instructions from the given
|
||||
* user before closing the connection with an error.
|
||||
*
|
||||
* @return
|
||||
* Zero if the user's Guacamole connection was successfully handled and
|
||||
* the user has disconnected, or non-zero if an error prevented the user's
|
||||
* connection from being handled properly.
|
||||
*/
|
||||
int guac_user_handle_connection(guac_user* user, int usec_timeout);
|
||||
|
||||
/**
|
||||
* Call the appropriate handler defined by the given user for the given
|
||||
* instruction. A comparison is made between the instruction opcode and the
|
||||
|
@ -19,13 +19,13 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "libguacd/socket-ssl.h"
|
||||
#include "error.h"
|
||||
#include "socket-ssl.h"
|
||||
#include "socket.h"
|
||||
|
||||
#include <poll.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <guacamole/error.h>
|
||||
#include <guacamole/socket.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
static ssize_t __guac_socket_ssl_read_handler(guac_socket* socket,
|
||||
@ -93,7 +93,7 @@ static int __guac_socket_ssl_select_handler(guac_socket* socket, int usec_timeou
|
||||
guac_error_message = "Error while waiting for data on secure socket";
|
||||
}
|
||||
|
||||
if (retval == 0) {
|
||||
else if (retval == 0) {
|
||||
guac_error = GUAC_STATUS_TIMEOUT;
|
||||
guac_error_message = "Timeout while waiting for data on secure socket";
|
||||
}
|
@ -19,24 +19,104 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "libguacd/log.h"
|
||||
#include "libguacd/user.h"
|
||||
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/error.h>
|
||||
#include <guacamole/parser.h>
|
||||
#include <guacamole/protocol.h>
|
||||
#include <guacamole/socket.h>
|
||||
#include <guacamole/user.h>
|
||||
#include "client.h"
|
||||
#include "error.h"
|
||||
#include "parser.h"
|
||||
#include "protocol.h"
|
||||
#include "socket.h"
|
||||
#include "user.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Parameters required by the user input thread.
|
||||
*/
|
||||
typedef struct guac_user_input_thread_params {
|
||||
|
||||
/**
|
||||
* The parser which will be used throughout the user's session.
|
||||
*/
|
||||
guac_parser* parser;
|
||||
|
||||
/**
|
||||
* A reference to the connected user.
|
||||
*/
|
||||
guac_user* user;
|
||||
|
||||
/**
|
||||
* The number of microseconds to wait for instructions from a connected
|
||||
* user before closing the connection with an error.
|
||||
*/
|
||||
int usec_timeout;
|
||||
|
||||
} guac_user_input_thread_params;
|
||||
|
||||
/**
|
||||
* Prints an error message using the logging facilities of the given user,
|
||||
* automatically including any information present in guac_error.
|
||||
*
|
||||
* @param user
|
||||
* The guac_user associated with the error that occurred.
|
||||
*
|
||||
* @param level
|
||||
* The level at which to log this message.
|
||||
*
|
||||
* @param message
|
||||
* The message to log.
|
||||
*/
|
||||
static void guac_user_log_guac_error(guac_user* user,
|
||||
guac_client_log_level level, const char* message) {
|
||||
|
||||
if (guac_error != GUAC_STATUS_SUCCESS) {
|
||||
|
||||
/* If error message provided, include in log */
|
||||
if (guac_error_message != NULL)
|
||||
guac_user_log(user, level, "%s: %s", message,
|
||||
guac_error_message);
|
||||
|
||||
/* Otherwise just log with standard status string */
|
||||
else
|
||||
guac_user_log(user, level, "%s: %s", message,
|
||||
guac_status_string(guac_error));
|
||||
|
||||
}
|
||||
|
||||
/* Just log message if no status code */
|
||||
else
|
||||
guac_user_log(user, level, "%s", message);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a reasonable explanatory message regarding handshake failure based on
|
||||
* the current value of guac_error.
|
||||
*
|
||||
* @param user
|
||||
* The guac_user associated with the failed Guacamole protocol handshake.
|
||||
*/
|
||||
static void guac_user_log_handshake_failure(guac_user* user) {
|
||||
|
||||
if (guac_error == GUAC_STATUS_CLOSED)
|
||||
guac_user_log(user, GUAC_LOG_INFO,
|
||||
"Guacamole connection closed during handshake");
|
||||
else if (guac_error == GUAC_STATUS_PROTOCOL_ERROR)
|
||||
guac_user_log(user, GUAC_LOG_ERROR,
|
||||
"Guacamole protocol violation. Perhaps the version of "
|
||||
"guacamole-client is incompatible with this version of "
|
||||
"libguac?");
|
||||
else
|
||||
guac_user_log(user, GUAC_LOG_WARNING,
|
||||
"Guacamole handshake failed: %s",
|
||||
guac_status_string(guac_error));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the given array of mimetypes (strings) into a newly-allocated NULL-
|
||||
* terminated array of strings. Both the array and the strings within the array
|
||||
* are newly-allocated and must be later freed via guacd_free_mimetypes().
|
||||
* are newly-allocated and must be later freed via guac_free_mimetypes().
|
||||
*
|
||||
* @param mimetypes
|
||||
* The array of mimetypes to copy.
|
||||
@ -49,7 +129,7 @@
|
||||
* copies of each of the mimetypes provided in the original mimetypes
|
||||
* array.
|
||||
*/
|
||||
static char** guacd_copy_mimetypes(char** mimetypes, int count) {
|
||||
static char** guac_copy_mimetypes(char** mimetypes, int count) {
|
||||
|
||||
int i;
|
||||
|
||||
@ -70,13 +150,13 @@ static char** guacd_copy_mimetypes(char** mimetypes, int count) {
|
||||
/**
|
||||
* Frees the given array of mimetypes, including the space allocated to each
|
||||
* mimetype string within the array. The provided array of mimetypes MUST have
|
||||
* been allocated with guacd_copy_mimetypes().
|
||||
* been allocated with guac_copy_mimetypes().
|
||||
*
|
||||
* @param mimetypes
|
||||
* The NULL-terminated array of mimetypes to free. This array MUST have
|
||||
* been previously allocated with guacd_copy_mimetypes().
|
||||
* been previously allocated with guac_copy_mimetypes().
|
||||
*/
|
||||
static void guacd_free_mimetypes(char** mimetypes) {
|
||||
static void guac_free_mimetypes(char** mimetypes) {
|
||||
|
||||
char** current_mimetype = mimetypes;
|
||||
|
||||
@ -91,9 +171,24 @@ static void guacd_free_mimetypes(char** mimetypes) {
|
||||
|
||||
}
|
||||
|
||||
void* guacd_user_input_thread(void* data) {
|
||||
/**
|
||||
* The thread which handles all user input, calling event handlers for received
|
||||
* instructions.
|
||||
*
|
||||
* @param data
|
||||
* A pointer to a guac_user_input_thread_params structure describing the
|
||||
* user whose input is being handled and the guac_parser with which to
|
||||
* handle it.
|
||||
*
|
||||
* @return
|
||||
* Always NULL.
|
||||
*/
|
||||
static void* guac_user_input_thread(void* data) {
|
||||
|
||||
guacd_user_input_thread_params* params = (guacd_user_input_thread_params*) data;
|
||||
guac_user_input_thread_params* params =
|
||||
(guac_user_input_thread_params*) data;
|
||||
|
||||
int usec_timeout = params->usec_timeout;
|
||||
guac_user* user = params->user;
|
||||
guac_parser* parser = params->parser;
|
||||
guac_client* client = user->client;
|
||||
@ -103,14 +198,14 @@ void* guacd_user_input_thread(void* data) {
|
||||
while (client->state == GUAC_CLIENT_RUNNING && user->active) {
|
||||
|
||||
/* Read instruction, stop on error */
|
||||
if (guac_parser_read(parser, socket, GUACD_USEC_TIMEOUT)) {
|
||||
if (guac_parser_read(parser, socket, usec_timeout)) {
|
||||
|
||||
if (guac_error == GUAC_STATUS_TIMEOUT)
|
||||
guac_user_abort(user, GUAC_PROTOCOL_STATUS_CLIENT_TIMEOUT, "User is not responding.");
|
||||
|
||||
else {
|
||||
if (guac_error != GUAC_STATUS_CLOSED)
|
||||
guacd_client_log_guac_error(client, GUAC_LOG_WARNING,
|
||||
guac_user_log_guac_error(user, GUAC_LOG_WARNING,
|
||||
"Guacamole connection failure");
|
||||
guac_user_stop(user);
|
||||
}
|
||||
@ -127,7 +222,7 @@ void* guacd_user_input_thread(void* data) {
|
||||
if (guac_user_handle_instruction(user, parser->opcode, parser->argc, parser->argv) < 0) {
|
||||
|
||||
/* Log error */
|
||||
guacd_client_log_guac_error(client, GUAC_LOG_WARNING,
|
||||
guac_user_log_guac_error(user, GUAC_LOG_WARNING,
|
||||
"User connection aborted");
|
||||
|
||||
/* Log handler details */
|
||||
@ -143,16 +238,37 @@ void* guacd_user_input_thread(void* data) {
|
||||
|
||||
}
|
||||
|
||||
int guacd_user_start(guac_parser* parser, guac_user* user) {
|
||||
/**
|
||||
* Starts the input/output threads of a new user. This function will block
|
||||
* until the user disconnects. If an error prevents the input/output threads
|
||||
* from starting, guac_user_stop() will be invoked on the given user.
|
||||
*
|
||||
* @param parser
|
||||
* The guac_parser to use to handle all input from the given user.
|
||||
*
|
||||
* @param user
|
||||
* The user whose associated I/O transfer threads should be started.
|
||||
*
|
||||
* @param usec_timeout
|
||||
* The number of microseconds to wait for instructions from the given
|
||||
* user before closing the connection with an error.
|
||||
*
|
||||
* @return
|
||||
* Zero if the I/O threads started successfully and user has disconnected,
|
||||
* or non-zero if the I/O threads could not be started.
|
||||
*/
|
||||
static int guac_user_start(guac_parser* parser, guac_user* user,
|
||||
int usec_timeout) {
|
||||
|
||||
guacd_user_input_thread_params params = {
|
||||
guac_user_input_thread_params params = {
|
||||
.parser = parser,
|
||||
.user = user
|
||||
.user = user,
|
||||
.usec_timeout = usec_timeout
|
||||
};
|
||||
|
||||
pthread_t input_thread;
|
||||
|
||||
if (pthread_create(&input_thread, NULL, guacd_user_input_thread, (void*) ¶ms)) {
|
||||
if (pthread_create(&input_thread, NULL, guac_user_input_thread, (void*) ¶ms)) {
|
||||
guac_user_log(user, GUAC_LOG_ERROR, "Unable to start input thread");
|
||||
guac_user_stop(user);
|
||||
return -1;
|
||||
@ -170,7 +286,7 @@ int guacd_user_start(guac_parser* parser, guac_user* user) {
|
||||
|
||||
}
|
||||
|
||||
int guacd_handle_user(guac_user* user) {
|
||||
int guac_user_handle_connection(guac_user* user, int usec_timeout) {
|
||||
|
||||
guac_socket* socket = user->socket;
|
||||
guac_client* client = user->client;
|
||||
@ -180,8 +296,8 @@ int guacd_handle_user(guac_user* user) {
|
||||
|| guac_socket_flush(socket)) {
|
||||
|
||||
/* Log error */
|
||||
guacd_client_log_handshake_failure(client);
|
||||
guacd_client_log_guac_error(client, GUAC_LOG_DEBUG,
|
||||
guac_user_log_handshake_failure(user);
|
||||
guac_user_log_guac_error(user, GUAC_LOG_DEBUG,
|
||||
"Error sending \"args\" to new user");
|
||||
|
||||
return 1;
|
||||
@ -190,11 +306,11 @@ int guacd_handle_user(guac_user* user) {
|
||||
guac_parser* parser = guac_parser_alloc();
|
||||
|
||||
/* Get optimal screen size */
|
||||
if (guac_parser_expect(parser, socket, GUACD_USEC_TIMEOUT, "size")) {
|
||||
if (guac_parser_expect(parser, socket, usec_timeout, "size")) {
|
||||
|
||||
/* Log error */
|
||||
guacd_client_log_handshake_failure(client);
|
||||
guacd_client_log_guac_error(client, GUAC_LOG_DEBUG,
|
||||
guac_user_log_handshake_failure(user);
|
||||
guac_user_log_guac_error(user, GUAC_LOG_DEBUG,
|
||||
"Error reading \"size\"");
|
||||
|
||||
guac_parser_free(parser);
|
||||
@ -203,7 +319,7 @@ int guacd_handle_user(guac_user* user) {
|
||||
|
||||
/* Validate content of size instruction */
|
||||
if (parser->argc < 2) {
|
||||
guac_client_log(client, GUAC_LOG_ERROR, "Received \"size\" "
|
||||
guac_user_log(user, GUAC_LOG_ERROR, "Received \"size\" "
|
||||
"instruction lacked required arguments.");
|
||||
guac_parser_free(parser);
|
||||
return 1;
|
||||
@ -213,7 +329,7 @@ int guacd_handle_user(guac_user* user) {
|
||||
user->info.optimal_width = atoi(parser->argv[0]);
|
||||
user->info.optimal_height = atoi(parser->argv[1]);
|
||||
|
||||
/* If DPI given, set the client resolution */
|
||||
/* If DPI given, set the user resolution */
|
||||
if (parser->argc >= 3)
|
||||
user->info.optimal_resolution = atoi(parser->argv[2]);
|
||||
|
||||
@ -222,11 +338,11 @@ int guacd_handle_user(guac_user* user) {
|
||||
user->info.optimal_resolution = 96;
|
||||
|
||||
/* Get supported audio formats */
|
||||
if (guac_parser_expect(parser, socket, GUACD_USEC_TIMEOUT, "audio")) {
|
||||
if (guac_parser_expect(parser, socket, usec_timeout, "audio")) {
|
||||
|
||||
/* Log error */
|
||||
guacd_client_log_handshake_failure(client);
|
||||
guacd_client_log_guac_error(client, GUAC_LOG_DEBUG,
|
||||
guac_user_log_handshake_failure(user);
|
||||
guac_user_log_guac_error(user, GUAC_LOG_DEBUG,
|
||||
"Error reading \"audio\"");
|
||||
|
||||
guac_parser_free(parser);
|
||||
@ -234,15 +350,15 @@ int guacd_handle_user(guac_user* user) {
|
||||
}
|
||||
|
||||
/* Store audio mimetypes */
|
||||
char** audio_mimetypes = guacd_copy_mimetypes(parser->argv, parser->argc);
|
||||
char** audio_mimetypes = guac_copy_mimetypes(parser->argv, parser->argc);
|
||||
user->info.audio_mimetypes = (const char**) audio_mimetypes;
|
||||
|
||||
/* Get supported video formats */
|
||||
if (guac_parser_expect(parser, socket, GUACD_USEC_TIMEOUT, "video")) {
|
||||
if (guac_parser_expect(parser, socket, usec_timeout, "video")) {
|
||||
|
||||
/* Log error */
|
||||
guacd_client_log_handshake_failure(client);
|
||||
guacd_client_log_guac_error(client, GUAC_LOG_DEBUG,
|
||||
guac_user_log_handshake_failure(user);
|
||||
guac_user_log_guac_error(user, GUAC_LOG_DEBUG,
|
||||
"Error reading \"video\"");
|
||||
|
||||
guac_parser_free(parser);
|
||||
@ -250,15 +366,15 @@ int guacd_handle_user(guac_user* user) {
|
||||
}
|
||||
|
||||
/* Store video mimetypes */
|
||||
char** video_mimetypes = guacd_copy_mimetypes(parser->argv, parser->argc);
|
||||
char** video_mimetypes = guac_copy_mimetypes(parser->argv, parser->argc);
|
||||
user->info.video_mimetypes = (const char**) video_mimetypes;
|
||||
|
||||
/* Get supported image formats */
|
||||
if (guac_parser_expect(parser, socket, GUACD_USEC_TIMEOUT, "image")) {
|
||||
if (guac_parser_expect(parser, socket, usec_timeout, "image")) {
|
||||
|
||||
/* Log error */
|
||||
guacd_client_log_handshake_failure(client);
|
||||
guacd_client_log_guac_error(client, GUAC_LOG_DEBUG,
|
||||
guac_user_log_handshake_failure(user);
|
||||
guac_user_log_guac_error(user, GUAC_LOG_DEBUG,
|
||||
"Error reading \"image\"");
|
||||
|
||||
guac_parser_free(parser);
|
||||
@ -266,15 +382,15 @@ int guacd_handle_user(guac_user* user) {
|
||||
}
|
||||
|
||||
/* Store image mimetypes */
|
||||
char** image_mimetypes = guacd_copy_mimetypes(parser->argv, parser->argc);
|
||||
char** image_mimetypes = guac_copy_mimetypes(parser->argv, parser->argc);
|
||||
user->info.image_mimetypes = (const char**) image_mimetypes;
|
||||
|
||||
/* Get args from connect instruction */
|
||||
if (guac_parser_expect(parser, socket, GUACD_USEC_TIMEOUT, "connect")) {
|
||||
if (guac_parser_expect(parser, socket, usec_timeout, "connect")) {
|
||||
|
||||
/* Log error */
|
||||
guacd_client_log_handshake_failure(client);
|
||||
guacd_client_log_guac_error(client, GUAC_LOG_DEBUG,
|
||||
guac_user_log_handshake_failure(user);
|
||||
guac_user_log_guac_error(user, GUAC_LOG_DEBUG,
|
||||
"Error reading \"connect\"");
|
||||
|
||||
guac_parser_free(parser);
|
||||
@ -298,7 +414,7 @@ int guacd_handle_user(guac_user* user) {
|
||||
client->connection_id, client->connected_users);
|
||||
|
||||
/* Handle user I/O, wait for connection to terminate */
|
||||
guacd_user_start(parser, user);
|
||||
guac_user_start(parser, user, usec_timeout);
|
||||
|
||||
/* Remove/free user */
|
||||
guac_client_remove_user(client, user);
|
||||
@ -308,9 +424,9 @@ int guacd_handle_user(guac_user* user) {
|
||||
}
|
||||
|
||||
/* Free mimetype lists */
|
||||
guacd_free_mimetypes(audio_mimetypes);
|
||||
guacd_free_mimetypes(video_mimetypes);
|
||||
guacd_free_mimetypes(image_mimetypes);
|
||||
guac_free_mimetypes(audio_mimetypes);
|
||||
guac_free_mimetypes(video_mimetypes);
|
||||
guac_free_mimetypes(image_mimetypes);
|
||||
|
||||
guac_parser_free(parser);
|
||||
|
@ -1,50 +0,0 @@
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
noinst_LTLIBRARIES = libguacd.la
|
||||
|
||||
noinst_HEADERS = \
|
||||
libguacd/log.h \
|
||||
libguacd/user.h
|
||||
|
||||
libguacd_la_SOURCES = \
|
||||
log.c \
|
||||
user.c
|
||||
|
||||
libguacd_la_CFLAGS = \
|
||||
-Werror -Wall -pedantic \
|
||||
@COMMON_INCLUDE@ \
|
||||
@LIBGUAC_INCLUDE@
|
||||
|
||||
libguacd_la_LIBADD = \
|
||||
@COMMON_LTLIB@ \
|
||||
@LIBGUAC_LTLIB@
|
||||
|
||||
libguacd_la_LDFLAGS = \
|
||||
@PTHREAD_LIBS@ \
|
||||
@SSL_LIBS@
|
||||
|
||||
# SSL support
|
||||
if ENABLE_SSL
|
||||
noinst_HEADERS += libguacd/socket-ssl.h
|
||||
libguacd_la_SOURCES += socket-ssl.c
|
||||
endif
|
||||
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef LIBGUACD_LOG_H
|
||||
#define LIBGUACD_LOG_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <guacamole/client.h>
|
||||
|
||||
/**
|
||||
* Prints an error message using the logging facilities of the given client,
|
||||
* automatically including any information present in guac_error. This function
|
||||
* accepts parameters identically to printf.
|
||||
*/
|
||||
void guacd_client_log_guac_error(guac_client* client,
|
||||
guac_client_log_level level, const char* message);
|
||||
|
||||
/**
|
||||
* Logs a reasonable explanatory message regarding handshake failure based on
|
||||
* the current value of guac_error.
|
||||
*/
|
||||
void guacd_client_log_handshake_failure(guac_client* client);
|
||||
|
||||
#endif
|
||||
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIBGUACD_USER_H
|
||||
#define LIBGUACD_USER_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <guacamole/parser.h>
|
||||
#include <guacamole/socket.h>
|
||||
#include <guacamole/user.h>
|
||||
|
||||
/**
|
||||
* The number of milliseconds to wait for messages in any phase before
|
||||
* timing out and closing the connection with an error.
|
||||
*/
|
||||
#define GUACD_TIMEOUT 15000
|
||||
|
||||
/**
|
||||
* The number of microseconds to wait for messages in any phase before
|
||||
* timing out and closing the conncetion with an error. This is always
|
||||
* equal to GUACD_TIMEOUT * 1000.
|
||||
*/
|
||||
#define GUACD_USEC_TIMEOUT (GUACD_TIMEOUT*1000)
|
||||
|
||||
/**
|
||||
* The maximum number of concurrent connections to a single instance
|
||||
* of guacd.
|
||||
*/
|
||||
#define GUACD_CLIENT_MAX_CONNECTIONS 65536
|
||||
|
||||
/**
|
||||
* Parameters required by the user input thread.
|
||||
*/
|
||||
typedef struct guacd_user_input_thread_params {
|
||||
|
||||
/**
|
||||
* The parser which will be used throughout the user's session.
|
||||
*/
|
||||
guac_parser* parser;
|
||||
|
||||
/**
|
||||
* A reference to the connected user.
|
||||
*/
|
||||
guac_user* user;
|
||||
|
||||
} guacd_user_input_thread_params;
|
||||
|
||||
/**
|
||||
* Starts the input/output threads of a new user. This function will block
|
||||
* until the user disconnects. If an error prevents the input/output threads
|
||||
* from starting, guac_user_stop() will be invoked on the given user.
|
||||
*
|
||||
* @param parser
|
||||
* The guac_parser to use to handle all input from the given user.
|
||||
*
|
||||
* @param user
|
||||
* The user whose associated I/O transfer threads should be started.
|
||||
*
|
||||
* @return
|
||||
* Zero if the I/O threads started successfully and user has disconnected,
|
||||
* or non-zero if the I/O threads could not be started.
|
||||
*/
|
||||
int guacd_user_start(guac_parser* parser, guac_user* user);
|
||||
|
||||
/**
|
||||
* Handles the initial handshake of a user and all subsequent I/O. This
|
||||
* function blocks until the user disconnects.
|
||||
*
|
||||
* @param user
|
||||
* The user whose handshake and entire Guacamole protocol exchange should
|
||||
* be handled.
|
||||
*
|
||||
* @return
|
||||
* Zero if the user's Guacamole connection was successfully handled and
|
||||
* the user has disconnected, or non-zero if an error prevented the user's
|
||||
* connection from being handled properly.
|
||||
*/
|
||||
int guacd_handle_user(guac_user* user);
|
||||
|
||||
/**
|
||||
* The thread which handles all user input, calling event handlers for received
|
||||
* instructions.
|
||||
*
|
||||
* @param data
|
||||
* A pointer to a guacd_user_input_thread_params structure describing the
|
||||
* user whose input is being handled and the guac_parser with which to
|
||||
* handle it.
|
||||
*
|
||||
* @return
|
||||
* Always NULL.
|
||||
*/
|
||||
void* guacd_user_input_thread(void* data);
|
||||
|
||||
#endif
|
||||
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libguacd/log.h"
|
||||
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/error.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void guacd_client_log_guac_error(guac_client* client,
|
||||
guac_client_log_level level, const char* message) {
|
||||
|
||||
if (guac_error != GUAC_STATUS_SUCCESS) {
|
||||
|
||||
/* If error message provided, include in log */
|
||||
if (guac_error_message != NULL)
|
||||
guac_client_log(client, level, "%s: %s",
|
||||
message,
|
||||
guac_error_message);
|
||||
|
||||
/* Otherwise just log with standard status string */
|
||||
else
|
||||
guac_client_log(client, level, "%s: %s",
|
||||
message,
|
||||
guac_status_string(guac_error));
|
||||
|
||||
}
|
||||
|
||||
/* Just log message if no status code */
|
||||
else
|
||||
guac_client_log(client, level, "%s", message);
|
||||
|
||||
}
|
||||
|
||||
void guacd_client_log_handshake_failure(guac_client* client) {
|
||||
|
||||
if (guac_error == GUAC_STATUS_CLOSED)
|
||||
guac_client_log(client, GUAC_LOG_INFO,
|
||||
"Guacamole connection closed during handshake");
|
||||
else if (guac_error == GUAC_STATUS_PROTOCOL_ERROR)
|
||||
guac_client_log(client, GUAC_LOG_ERROR,
|
||||
"Guacamole protocol violation. Perhaps the version of "
|
||||
"guacamole-client is incompatible with this version of "
|
||||
"guacd?");
|
||||
else
|
||||
guac_client_log(client, GUAC_LOG_WARNING,
|
||||
"Guacamole handshake failed: %s",
|
||||
guac_status_string(guac_error));
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user