From a4adb3f5c0dffc56843328ed6936d8638fe30a9c Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Sat, 25 Dec 2021 19:13:03 -0500 Subject: [PATCH 01/10] GUACAMOLE-1293: Add protocol support for msg instruction. --- src/libguac/client.c | 30 +++++++++++++++++++ src/libguac/guacamole/client.h | 15 ++++++++++ src/libguac/guacamole/protocol-constants.h | 2 +- src/libguac/guacamole/protocol-types.h | 8 ++++- src/libguac/guacamole/protocol.h | 15 ++++++++++ src/libguac/guacamole/user.h | 11 +++++++ src/libguac/protocol.c | 16 ++++++++++ .../tests/protocol/guac_protocol_version.c | 4 +-- src/libguac/user.c | 9 ++++++ 9 files changed, 106 insertions(+), 4 deletions(-) diff --git a/src/libguac/client.c b/src/libguac/client.c index 9738c0c2..cd4b5463 100644 --- a/src/libguac/client.c +++ b/src/libguac/client.c @@ -671,6 +671,36 @@ static void* __webp_support_callback(guac_user* user, void* data) { } #endif +/** + * A callback function which is invoked by guac_client_owner_supports_msg() + * to determine if the owner of a client supports the "msg" instruction, + * returning zero if the user does not support the instruction or non-zero if + * the user supports it. + * + * @param user + * The guac_user that will be checked for "msg" instruction support. + * + * @param data + * Data provided to the callback. This value is never used within this + * callback. + * + * @return + * A non-zero integer if the provided user who owns the connection supports + * the "msg" instruction, or zero if the user does not. The integer is cast + * as a void*. + */ +static void* guac_owner_supports_msg_callback(guac_user* user, void* data) { + + return (void*) ((intptr_t) guac_user_supports_msg(user)); + +} + +int guac_client_owner_supports_msg(guac_client* client) { + + return (int) ((intptr_t) guac_client_for_owner(client, guac_owner_supports_msg_callback, NULL)); + +} + /** * A callback function which is invoked by guac_client_owner_supports_required() * to determine if the owner of a client supports the "required" instruction, diff --git a/src/libguac/guacamole/client.h b/src/libguac/guacamole/client.h index 4ffe5cf4..2067c5cd 100644 --- a/src/libguac/guacamole/client.h +++ b/src/libguac/guacamole/client.h @@ -708,6 +708,21 @@ void guac_client_stream_webp(guac_client* client, guac_socket* socket, guac_composite_mode mode, const guac_layer* layer, int x, int y, cairo_surface_t* surface, int quality, int lossless); +/** + * Returns whether the owner of the given client supports the "msg" + * instruction, returning non-zero if the client owner does support the + * instruction, or zero if the owner does not. + * + * @param client + * The Guacamole client whose owner should be checked for supporting + * the "msg" instruction. + * + * @return + * Non-zero if the owner of the given client supports the "msg" + * instruction, zero otherwise. + */ +int guac_client_owner_supports_msg(guac_client* client); + /** * Returns whether the owner of the given client supports the "required" * instruction, returning non-zero if the client owner does support the diff --git a/src/libguac/guacamole/protocol-constants.h b/src/libguac/guacamole/protocol-constants.h index 13d7f680..a8fc9777 100644 --- a/src/libguac/guacamole/protocol-constants.h +++ b/src/libguac/guacamole/protocol-constants.h @@ -38,7 +38,7 @@ * This version is passed by the __guac_protocol_send_args() function from the * server to the client during the client/server handshake. */ -#define GUACAMOLE_PROTOCOL_VERSION "VERSION_1_3_0" +#define GUACAMOLE_PROTOCOL_VERSION "VERSION_1_5_0" /** * The maximum number of bytes that should be sent in any one blob instruction diff --git a/src/libguac/guacamole/protocol-types.h b/src/libguac/guacamole/protocol-types.h index 51652d2b..1cb1de25 100644 --- a/src/libguac/guacamole/protocol-types.h +++ b/src/libguac/guacamole/protocol-types.h @@ -306,7 +306,13 @@ typedef enum guac_protocol_version { * allowing connections in guacd to request information from the client and * await a response. */ - GUAC_PROTOCOL_VERSION_1_3_0 = 0x010300 + GUAC_PROTOCOL_VERSION_1_3_0 = 0x010300, + + /** + * Protocol version 1.5.0, which supports the "msg" instruction, allowing + * messages to be sent to the client. + */ + GUAC_PROTOCOL_VERSION_1_5_0 = 0x010500 } guac_protocol_version; diff --git a/src/libguac/guacamole/protocol.h b/src/libguac/guacamole/protocol.h index 362351c5..73578ba7 100644 --- a/src/libguac/guacamole/protocol.h +++ b/src/libguac/guacamole/protocol.h @@ -171,6 +171,21 @@ int guac_protocol_send_log(guac_socket* socket, const char* format, ...); int vguac_protocol_send_log(guac_socket* socket, const char* format, va_list args); +/** + * Sends the given string over the socket to be displayed on the client. Returns + * zero if the message was sent successfully or non-zero if an error occurs. + * + * @param socket + * The guac_socket connection to send the message to. + * + * @param message + * The message to send to the client. + * + * @return + * Zero if the message is sent successfully; otherwise non-zero. + */ +int guac_protocol_send_msg(guac_socket* socket, const char* message); + /** * Sends a mouse instruction over the given guac_socket connection. * diff --git a/src/libguac/guacamole/user.h b/src/libguac/guacamole/user.h index 963dbe68..8f6a2721 100644 --- a/src/libguac/guacamole/user.h +++ b/src/libguac/guacamole/user.h @@ -850,6 +850,17 @@ void guac_user_stream_webp(guac_user* user, guac_socket* socket, guac_composite_mode mode, const guac_layer* layer, int x, int y, cairo_surface_t* surface, int quality, int lossless); +/** + * Returns whether the given user supports the "msg" instruction. + * + * @param user + * The Guacamole user to check for support of the "msg" instruction. + * + * @return + * Non-zero if the user supports the "msg" instruction, otherwise zero. + */ +int guac_user_supports_msg(guac_user* user); + /** * Returns whether the given user supports the "required" instruction. * diff --git a/src/libguac/protocol.c b/src/libguac/protocol.c index 1c53c200..0745c415 100644 --- a/src/libguac/protocol.c +++ b/src/libguac/protocol.c @@ -65,6 +65,7 @@ guac_protocol_version_mapping guac_protocol_version_table[] = { { GUAC_PROTOCOL_VERSION_1_0_0, "VERSION_1_0_0" }, { GUAC_PROTOCOL_VERSION_1_1_0, "VERSION_1_1_0" }, { GUAC_PROTOCOL_VERSION_1_3_0, "VERSION_1_3_0" }, + { GUAC_PROTOCOL_VERSION_1_5_0, "VERSION_1_5_0" }, { GUAC_PROTOCOL_VERSION_UNKNOWN, NULL } }; @@ -658,6 +659,21 @@ int guac_protocol_send_log(guac_socket* socket, const char* format, ...) { } +int guac_protocol_send_msg(guac_socket* socket, const char* message) { + + int ret_val; + + guac_socket_instruction_begin(socket); + ret_val = + guac_socket_write_string(socket, "3.msg,") + || __guac_socket_write_length_string(socket, message) + || guac_socket_write_string(socket, ";"); + + guac_socket_instruction_end(socket); + return ret_val; + +} + int guac_protocol_send_file(guac_socket* socket, const guac_stream* stream, const char* mimetype, const char* name) { diff --git a/src/libguac/tests/protocol/guac_protocol_version.c b/src/libguac/tests/protocol/guac_protocol_version.c index 37f42e0f..f9b2fdf2 100644 --- a/src/libguac/tests/protocol/guac_protocol_version.c +++ b/src/libguac/tests/protocol/guac_protocol_version.c @@ -27,11 +27,11 @@ */ void test_guac_protocol__version_to_string() { - guac_protocol_version version_a = GUAC_PROTOCOL_VERSION_1_3_0; + guac_protocol_version version_a = GUAC_PROTOCOL_VERSION_1_5_0; guac_protocol_version version_b = GUAC_PROTOCOL_VERSION_1_0_0; guac_protocol_version version_c = GUAC_PROTOCOL_VERSION_UNKNOWN; - CU_ASSERT_STRING_EQUAL(guac_protocol_version_to_string(version_a), "VERSION_1_3_0"); + CU_ASSERT_STRING_EQUAL(guac_protocol_version_to_string(version_a), "VERSION_1_5_0"); CU_ASSERT_STRING_EQUAL(guac_protocol_version_to_string(version_b), "VERSION_1_0_0"); CU_ASSERT_PTR_NULL(guac_protocol_version_to_string(version_c)); diff --git a/src/libguac/user.c b/src/libguac/user.c index 4320ca77..d16f43b9 100644 --- a/src/libguac/user.c +++ b/src/libguac/user.c @@ -316,6 +316,15 @@ void guac_user_stream_webp(guac_user* user, guac_socket* socket, } +int guac_user_supports_msg(guac_user* user) { + + if (user == NULL) + return 0; + + return (user->info.protocol_version >= GUAC_PROTOCOL_VERSION_1_5_0); + +} + int guac_user_supports_required(guac_user* user) { if (user == NULL) From cb7ae25177cdfab3b45c9246c8425872ad820c49 Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Sat, 25 Dec 2021 19:14:51 -0500 Subject: [PATCH 02/10] GUACAMOLE-1293: Add support for the name handshake instruction. --- src/libguac/guacamole/protocol-types.h | 3 ++- src/libguac/guacamole/user.h | 6 ++++++ src/libguac/user-handlers.c | 16 ++++++++++++++++ src/libguac/user-handlers.h | 7 +++++++ src/libguac/user-handshake.c | 4 +++- 5 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/libguac/guacamole/protocol-types.h b/src/libguac/guacamole/protocol-types.h index 1cb1de25..074ab97f 100644 --- a/src/libguac/guacamole/protocol-types.h +++ b/src/libguac/guacamole/protocol-types.h @@ -310,7 +310,8 @@ typedef enum guac_protocol_version { /** * Protocol version 1.5.0, which supports the "msg" instruction, allowing - * messages to be sent to the client. + * messages to be sent to the client, and adds support for the "name" + * handshake instruction. */ GUAC_PROTOCOL_VERSION_1_5_0 = 0x010500 diff --git a/src/libguac/guacamole/user.h b/src/libguac/guacamole/user.h index 8f6a2721..06db8fd6 100644 --- a/src/libguac/guacamole/user.h +++ b/src/libguac/guacamole/user.h @@ -89,6 +89,12 @@ struct guac_user_info { */ int optimal_resolution; + /** + * The human-readable name of the Guacamole user. If the client does not + * provide a name then this will be NULL. + */ + const char* name; + /** * The timezone of the remote system. If the client does not provide * a specific timezone then this will be NULL. The format of the timezone diff --git a/src/libguac/user-handlers.c b/src/libguac/user-handlers.c index c5cad9df..0c084457 100644 --- a/src/libguac/user-handlers.c +++ b/src/libguac/user-handlers.c @@ -64,6 +64,7 @@ __guac_instruction_handler_mapping __guac_handshake_handler_map[] = { {"video", __guac_handshake_video_handler}, {"image", __guac_handshake_image_handler}, {"timezone", __guac_handshake_timezone_handler}, + {"name", __guac_handshake_name_handler}, {NULL, NULL} }; @@ -676,6 +677,21 @@ int __guac_handshake_image_handler(guac_user* user, int argc, char** argv) { } +int __guac_handshake_name_handler(guac_user* user, int argc, char** argv) { + + /* Free any past value */ + free((char *) user->info.name); + + if (argc > 0 && strcmp(argv[0], "")) + user->info.name = (const char*) strdup(argv[0]); + + else + user->info.name = NULL; + + return 0; + +} + int __guac_handshake_timezone_handler(guac_user* user, int argc, char** argv) { /* Free any past value */ diff --git a/src/libguac/user-handlers.h b/src/libguac/user-handlers.h index a51a3f89..7f82302b 100644 --- a/src/libguac/user-handlers.h +++ b/src/libguac/user-handlers.h @@ -218,6 +218,13 @@ __guac_instruction_handler __guac_handshake_video_handler; */ __guac_instruction_handler __guac_handshake_image_handler; +/** + * Internal handler function that is called when the name instruction is + * received during the handshake process, specifying the name of the Guacamole + * user establishing the connection. + */ +__guac_instruction_handler __guac_handshake_name_handler; + /** * Internal handler function that is called when the timezone instruction is * received during the handshake process, specifying the timezone of the diff --git a/src/libguac/user-handshake.c b/src/libguac/user-handshake.c index 4e0fa446..0863325f 100644 --- a/src/libguac/user-handshake.c +++ b/src/libguac/user-handshake.c @@ -296,6 +296,7 @@ int guac_user_handle_connection(guac_user* user, int usec_timeout) { user->info.audio_mimetypes = NULL; user->info.image_mimetypes = NULL; user->info.video_mimetypes = NULL; + user->info.name = NULL; user->info.timezone = NULL; /* Count number of arguments. */ @@ -370,7 +371,8 @@ int guac_user_handle_connection(guac_user* user, int usec_timeout) { guac_free_mimetypes((char **) user->info.image_mimetypes); guac_free_mimetypes((char **) user->info.video_mimetypes); - /* Free timezone info. */ + /* Free name and timezone info. */ + free((char *) user->info.name); free((char *) user->info.timezone); guac_parser_free(parser); From 6312e1720d2de671472872b17c0b0e64fbd19c73 Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Sat, 25 Dec 2021 19:15:21 -0500 Subject: [PATCH 03/10] GUACAMOLE-1293: Add support for notifying owner of users joining and leaving. --- src/libguac/client.c | 128 +++++++++++++++++++++++++++++++++ src/libguac/guacamole/client.h | 36 ++++++++++ 2 files changed, 164 insertions(+) diff --git a/src/libguac/client.c b/src/libguac/client.c index cd4b5463..3f307579 100644 --- a/src/libguac/client.c +++ b/src/libguac/client.c @@ -302,6 +302,10 @@ int guac_client_add_user(guac_client* client, guac_user* user, int argc, char** /* Update owner pointer if user is owner */ if (user->owner) client->__owner = user; + + /* Notify owner of user joining connection. */ + else + guac_client_owner_notify_join(client, user); } @@ -331,6 +335,10 @@ void guac_client_remove_user(guac_client* client, guac_user* user) { if (user->owner) client->__owner = NULL; + /* Update owner of user having left the connection. */ + else + guac_client_owner_notify_leave(client, user); + pthread_rwlock_unlock(&(client->__users_lock)); /* Call handler, if defined */ @@ -731,6 +739,126 @@ int guac_client_owner_supports_required(guac_client* client) { } +/** + * A callback function that is invokved by guac_client_owner_notify_join() to + * notify the owner of a connection that another user has joined the + * connection, returning zero if the message is sent successfully, or non-zero + * if an error occurs. + * + * @param user + * The user to send the notification to, which will be the owner of the + * connection. + * + * @param data + * The data provided to the callback, which is the user that is joining the + * connection. + * + * @return + * Zero if the message is sent successfully to the owner, otherwise + * non-zero, cast as a void*. + */ +static void* guac_client_owner_notify_join_callback(guac_user* user, void* data) { + + const guac_user* joiner = (const guac_user *) data; + int retval = 0; + + char* owner = "owner"; + if (user->info.name != NULL) + owner = strdup(user->info.name); + + char* joinName = "anonymous"; + if (joiner->info.name != NULL) + joinName = strdup(joiner->info.name); + + guac_user_log(user, GUAC_LOG_DEBUG, "Notifying %s of %s joining.", owner, joinName); + + size_t msg_size = snprintf(NULL, 0, "User %s has joined the connection.", joinName); + char* msg = malloc(msg_size + 1); + sprintf(msg, "User %s has joined the connection.", joinName); + + /* Send required parameters to owner. */ + if (user != NULL) + retval = guac_protocol_send_msg(user->socket, msg); + + else + retval = -1; + + free(owner); + free(joinName); + free(msg); + + return (void*) ((intptr_t) retval); + +} + +int guac_client_owner_notify_join(guac_client* client, guac_user* joiner) { + + /* Don't send msg instruction if client does not support it. */ + if (!guac_client_owner_supports_msg(client)) + return -1; + + guac_client_log(client, GUAC_LOG_DEBUG, "Notifying owner of %s joining.", joiner->user_id); + + return (int) ((intptr_t) guac_client_for_owner(client, guac_client_owner_notify_join_callback, joiner)); + +} + +/** + * A callback function that is invokved by guac_client_owner_notify_leave() to + * notify the owner of a connection that another user has left the connection, + * returning zero if the message is sent successfully, or non-zero + * if an error occurs. + * + * @param user + * The user to send the notification to, which will be the owner of the + * connection. + * + * @param data + * The data provided to the callback, which is the user that is leaving the + * connection. + * + * @return + * Zero if the message is sent successfully to the owner, otherwise + * non-zero, cast as a void*. + */ +static void* guac_client_owner_notify_leave_callback(guac_user* user, void* data) { + + const guac_user* quitter = (const guac_user *) data; + + char* owner = "owner"; + if (user->info.name != NULL) + owner = strdup(user->info.name); + + char* quitterName = "anonymous"; + if (quitter->info.name != NULL) + quitterName = strdup(quitter->info.name); + + guac_user_log(user, GUAC_LOG_DEBUG, "Notifying %s of %s leaving.", owner, quitterName); + + size_t msg_size = snprintf(NULL, 0, "User %s has left the connection.", quitterName); + char* msg = malloc(msg_size + 1); + sprintf(msg, "User %s has left the connection.", quitterName); + + /* Send required parameters to owner. */ + if (user != NULL) + return (void*) ((intptr_t) guac_protocol_send_msg(user->socket, msg)); + + return (void*) ((intptr_t) -1); + +} + +int guac_client_owner_notify_leave(guac_client* client, guac_user* quitter) { + + /* Don't send msg instruction if client does not support it. */ + if (!guac_client_owner_supports_msg(client)) + return -1; + + guac_client_log(client, GUAC_LOG_DEBUG, "Notifying owner of %s leaving.", quitter->user_id); + + return (int) ((intptr_t) guac_client_for_owner(client, guac_client_owner_notify_leave_callback, quitter)); + +} + int guac_client_supports_webp(guac_client* client) { #ifdef ENABLE_WEBP diff --git a/src/libguac/guacamole/client.h b/src/libguac/guacamole/client.h index 2067c5cd..5712476f 100644 --- a/src/libguac/guacamole/client.h +++ b/src/libguac/guacamole/client.h @@ -738,6 +738,42 @@ int guac_client_owner_supports_msg(guac_client* client); */ int guac_client_owner_supports_required(guac_client* client); +/** + * Notifies the owner of the given client that a user has joined the connection, + * and returns zero if the message was sent successfully, or non-zero if the + * notification failed. + * + * @param client + * The Guacamole Client whose owner should be notified of a user joining + * the connection. + * + * @param joiner + * The Guacamole User who joined the connection. + * + * @return + * Zero if the notification to the owner was sent successfully, or non-zero + * if an error occurred. + */ +int guac_client_owner_notify_join(guac_client* client, guac_user* joiner); + +/** + * Notifies the owner of the given client that a user has left the connection, + * and returns zero if the message was sent successfully, or non-zero if the + * notification failed. + * + * @param client + * The Guacamole Client whose owner should be notified of a user leaving + * the connection. + * + * @param quitter + * The Guacamole User who left the connection. + * + * @return + * Zero if the notification to the owner was sent successfully, or non-zero + * if an error occurred. + */ +int guac_client_owner_notify_leave(guac_client* client, guac_user* quitter); + /** * Returns whether all users of the given client support WebP. If any user does * not support WebP, or the server cannot encode WebP images, zero is returned. From 6d7156bc70d568d125b659176b8a7dddcfe4a9f9 Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Fri, 1 Apr 2022 19:30:31 -0400 Subject: [PATCH 04/10] GUACAMOLE-1293: Update struct member that stores human-readable name. --- src/libguac/client.c | 16 ++++++++-------- src/libguac/guacamole/user.h | 2 +- src/libguac/user-handlers.c | 14 ++++++++------ src/libguac/user-handlers.h | 4 ++-- src/libguac/user-handshake.c | 6 +++--- 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/libguac/client.c b/src/libguac/client.c index 3f307579..612a0bb1 100644 --- a/src/libguac/client.c +++ b/src/libguac/client.c @@ -763,12 +763,12 @@ static void* guac_client_owner_notify_join_callback(guac_user* user, void* data) int retval = 0; char* owner = "owner"; - if (user->info.name != NULL) - owner = strdup(user->info.name); + if (user->info.username != NULL) + owner = strdup(user->info.username); char* joinName = "anonymous"; - if (joiner->info.name != NULL) - joinName = strdup(joiner->info.name); + if (joiner->info.username != NULL) + joinName = strdup(joiner->info.username); guac_user_log(user, GUAC_LOG_DEBUG, "Notifying %s of %s joining.", owner, joinName); @@ -826,12 +826,12 @@ static void* guac_client_owner_notify_leave_callback(guac_user* user, void* data const guac_user* quitter = (const guac_user *) data; char* owner = "owner"; - if (user->info.name != NULL) - owner = strdup(user->info.name); + if (user->info.username != NULL) + owner = strdup(user->info.username); char* quitterName = "anonymous"; - if (quitter->info.name != NULL) - quitterName = strdup(quitter->info.name); + if (quitter->info.username != NULL) + quitterName = strdup(quitter->info.username); guac_user_log(user, GUAC_LOG_DEBUG, "Notifying %s of %s leaving.", owner, quitterName); diff --git a/src/libguac/guacamole/user.h b/src/libguac/guacamole/user.h index 06db8fd6..dc27bb6d 100644 --- a/src/libguac/guacamole/user.h +++ b/src/libguac/guacamole/user.h @@ -93,7 +93,7 @@ struct guac_user_info { * The human-readable name of the Guacamole user. If the client does not * provide a name then this will be NULL. */ - const char* name; + const char* username; /** * The timezone of the remote system. If the client does not provide diff --git a/src/libguac/user-handlers.c b/src/libguac/user-handlers.c index 0c084457..66488c6a 100644 --- a/src/libguac/user-handlers.c +++ b/src/libguac/user-handlers.c @@ -64,7 +64,7 @@ __guac_instruction_handler_mapping __guac_handshake_handler_map[] = { {"video", __guac_handshake_video_handler}, {"image", __guac_handshake_image_handler}, {"timezone", __guac_handshake_timezone_handler}, - {"name", __guac_handshake_name_handler}, + {"username", __guac_handshake_username_handler}, {NULL, NULL} }; @@ -677,16 +677,18 @@ int __guac_handshake_image_handler(guac_user* user, int argc, char** argv) { } -int __guac_handshake_name_handler(guac_user* user, int argc, char** argv) { +int __guac_handshake_username_handler(guac_user* user, int argc, char** argv) { - /* Free any past value */ - free((char *) user->info.name); + /* Free any past value for the user's name */ + free((char *) user->info.username); + /* If a value is provided for the username, copy it into guac_user. */ if (argc > 0 && strcmp(argv[0], "")) - user->info.name = (const char*) strdup(argv[0]); + user->info.username = (const char*) strdup(argv[0]); + /* No or empty value was provided, so make sure this is NULLed out. */ else - user->info.name = NULL; + user->info.username = NULL; return 0; diff --git a/src/libguac/user-handlers.h b/src/libguac/user-handlers.h index 7f82302b..785e5b6b 100644 --- a/src/libguac/user-handlers.h +++ b/src/libguac/user-handlers.h @@ -219,11 +219,11 @@ __guac_instruction_handler __guac_handshake_video_handler; __guac_instruction_handler __guac_handshake_image_handler; /** - * Internal handler function that is called when the name instruction is + * Internal handler function that is called when the username instruction is * received during the handshake process, specifying the name of the Guacamole * user establishing the connection. */ -__guac_instruction_handler __guac_handshake_name_handler; +__guac_instruction_handler __guac_handshake_username_handler; /** * Internal handler function that is called when the timezone instruction is diff --git a/src/libguac/user-handshake.c b/src/libguac/user-handshake.c index 0863325f..e2910f0e 100644 --- a/src/libguac/user-handshake.c +++ b/src/libguac/user-handshake.c @@ -296,7 +296,7 @@ int guac_user_handle_connection(guac_user* user, int usec_timeout) { user->info.audio_mimetypes = NULL; user->info.image_mimetypes = NULL; user->info.video_mimetypes = NULL; - user->info.name = NULL; + user->info.username = NULL; user->info.timezone = NULL; /* Count number of arguments. */ @@ -371,8 +371,8 @@ int guac_user_handle_connection(guac_user* user, int usec_timeout) { guac_free_mimetypes((char **) user->info.image_mimetypes); guac_free_mimetypes((char **) user->info.video_mimetypes); - /* Free name and timezone info. */ - free((char *) user->info.name); + /* Free username and timezone info. */ + free((char *) user->info.username); free((char *) user->info.timezone); guac_parser_free(parser); From 26eadc37a3bf776c32dfc8c8e18e45de1b0f7185 Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Sat, 9 Apr 2022 16:47:15 -0400 Subject: [PATCH 05/10] GUACAMOLE-1293: Move to status code plus arguments for msg instruction. --- src/libguac/client.c | 58 +++++++++++++------------- src/libguac/guacamole/protocol-types.h | 26 +++++++++++- src/libguac/guacamole/protocol.h | 12 ++++-- src/libguac/protocol.c | 6 ++- 4 files changed, 68 insertions(+), 34 deletions(-) diff --git a/src/libguac/client.c b/src/libguac/client.c index 612a0bb1..6f35b480 100644 --- a/src/libguac/client.c +++ b/src/libguac/client.c @@ -762,30 +762,31 @@ static void* guac_client_owner_notify_join_callback(guac_user* user, void* data) const guac_user* joiner = (const guac_user *) data; int retval = 0; - char* owner = "owner"; - if (user->info.username != NULL) + char* owner = strdup("owner"); + if (user->info.username != NULL) { + free(owner); owner = strdup(user->info.username); + } - char* joinName = "anonymous"; - if (joiner->info.username != NULL) + char* joinName = strdup("anonymous"); + if (joiner->info.username != NULL) { + free(joinName); joinName = strdup(joiner->info.username); + } - guac_user_log(user, GUAC_LOG_DEBUG, "Notifying %s of %s joining.", owner, joinName); - - size_t msg_size = snprintf(NULL, 0, "User %s has joined the connection.", joinName); - char* msg = malloc(msg_size + 1); - sprintf(msg, "User %s has joined the connection.", joinName); + guac_user_log(user, GUAC_LOG_DEBUG, "Notifying owner %s of %s joining.", owner, joinName); /* Send required parameters to owner. */ - if (user != NULL) - retval = guac_protocol_send_msg(user->socket, msg); + if (user != NULL) { + const char* args[] = { (const char*)joinName, NULL }; + retval = guac_protocol_send_msg(user->socket, GUAC_MSG_CLIENT_JOINED, args); + } else retval = -1; free(owner); free(joinName); - free(msg); return (void*) ((intptr_t) retval); @@ -797,8 +798,6 @@ int guac_client_owner_notify_join(guac_client* client, guac_user* joiner) { if (!guac_client_owner_supports_msg(client)) return -1; - guac_client_log(client, GUAC_LOG_DEBUG, "Notifying owner of %s joining.", joiner->user_id); - return (int) ((intptr_t) guac_client_for_owner(client, guac_client_owner_notify_join_callback, joiner)); } @@ -825,24 +824,29 @@ static void* guac_client_owner_notify_leave_callback(guac_user* user, void* data const guac_user* quitter = (const guac_user *) data; - char* owner = "owner"; - if (user->info.username != NULL) - owner = strdup(user->info.username); + char* ownerName = strdup("owner"); + if (user->info.username != NULL) { + free(ownerName); + ownerName = strdup(user->info.username); + } - char* quitterName = "anonymous"; - if (quitter->info.username != NULL) + char* quitterName = strdup("anonymous"); + if (quitter->info.username != NULL) { + free(quitterName); quitterName = strdup(quitter->info.username); + } - guac_user_log(user, GUAC_LOG_DEBUG, "Notifying %s of %s leaving.", owner, quitterName); - - size_t msg_size = snprintf(NULL, 0, "User %s has left the connection.", quitterName); - char* msg = malloc(msg_size + 1); - sprintf(msg, "User %s has left the connection.", quitterName); + guac_user_log(user, GUAC_LOG_DEBUG, "Notifying owner %s of %s leaving.", ownerName, quitterName); /* Send required parameters to owner. */ - if (user != NULL) - return (void*) ((intptr_t) guac_protocol_send_msg(user->socket, msg)); + if (user != NULL) { + const char* args[] = { (const char*)quitterName, NULL }; + return (void*) ((intptr_t) guac_protocol_send_msg(user->socket, GUAC_MSG_CLIENT_LEFT, args)); + } + free(ownerName); + free(quitterName); + return (void*) ((intptr_t) -1); } @@ -853,8 +857,6 @@ int guac_client_owner_notify_leave(guac_client* client, guac_user* quitter) { if (!guac_client_owner_supports_msg(client)) return -1; - guac_client_log(client, GUAC_LOG_DEBUG, "Notifying owner of %s leaving.", quitter->user_id); - return (int) ((intptr_t) guac_client_for_owner(client, guac_client_owner_notify_leave_callback, quitter)); } diff --git a/src/libguac/guacamole/protocol-types.h b/src/libguac/guacamole/protocol-types.h index 074ab97f..5bb1e04c 100644 --- a/src/libguac/guacamole/protocol-types.h +++ b/src/libguac/guacamole/protocol-types.h @@ -310,12 +310,36 @@ typedef enum guac_protocol_version { /** * Protocol version 1.5.0, which supports the "msg" instruction, allowing - * messages to be sent to the client, and adds support for the "name" + * messages to be sent to the client, and adds support for the "username" * handshake instruction. */ GUAC_PROTOCOL_VERSION_1_5_0 = 0x010500 } guac_protocol_version; +/** + * A type that represents codes for human-readable messages sent by the "msg" + * instruction to the Client, that will be displayed in the client's browser. + * The codes will be interpreted by the client into translatable messages, and + * make take arguments, as noted below. + */ +typedef enum guac_msg_client { + + /** + * A message that notifies the owner of a connection that another user has + * joined their connection. There should be a single argument, the username + * of the user who has joined. + */ + GUAC_MSG_CLIENT_JOINED = 0x0001, + + /** + * A message that notifies the owner of a connection that another user has + * left their connection. There should be a single argument provided, the + * username of the user who has left. + */ + GUAC_MSG_CLIENT_LEFT = 0x0002 + +} guac_msg_client; + #endif diff --git a/src/libguac/guacamole/protocol.h b/src/libguac/guacamole/protocol.h index 73578ba7..16111314 100644 --- a/src/libguac/guacamole/protocol.h +++ b/src/libguac/guacamole/protocol.h @@ -178,13 +178,19 @@ int vguac_protocol_send_log(guac_socket* socket, const char* format, * @param socket * The guac_socket connection to send the message to. * - * @param message - * The message to send to the client. + * @param msg + * The message code to send to the client. + * + * @param args + * A null-terminated array of strings that will be provided to the client + * as part of the message, that the client may then place in the message, + * or null if the message requires no arguments. * * @return * Zero if the message is sent successfully; otherwise non-zero. */ -int guac_protocol_send_msg(guac_socket* socket, const char* message); +int guac_protocol_send_msg(guac_socket* socket, guac_msg_client msg, + const char** args); /** * Sends a mouse instruction over the given guac_socket connection. diff --git a/src/libguac/protocol.c b/src/libguac/protocol.c index 0745c415..407b056e 100644 --- a/src/libguac/protocol.c +++ b/src/libguac/protocol.c @@ -659,14 +659,16 @@ int guac_protocol_send_log(guac_socket* socket, const char* format, ...) { } -int guac_protocol_send_msg(guac_socket* socket, const char* message) { +int guac_protocol_send_msg(guac_socket* socket, guac_msg_client msg, + const char** args) { int ret_val; guac_socket_instruction_begin(socket); ret_val = guac_socket_write_string(socket, "3.msg,") - || __guac_socket_write_length_string(socket, message) + || __guac_socket_write_length_int(socket, msg) + || guac_socket_write_array(socket, args) || guac_socket_write_string(socket, ";"); guac_socket_instruction_end(socket); From 02b24d0101ef1d5a2bbb91c149d708be49860167 Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Mon, 25 Jul 2022 21:29:15 -0400 Subject: [PATCH 06/10] GUACAMOLE-1293: Simplify the assignment of strings/constants. --- src/libguac/client.c | 64 +++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 42 deletions(-) diff --git a/src/libguac/client.c b/src/libguac/client.c index 6f35b480..b7526ec6 100644 --- a/src/libguac/client.c +++ b/src/libguac/client.c @@ -760,35 +760,23 @@ int guac_client_owner_supports_required(guac_client* client) { static void* guac_client_owner_notify_join_callback(guac_user* user, void* data) { const guac_user* joiner = (const guac_user *) data; - int retval = 0; - char* owner = strdup("owner"); - if (user->info.username != NULL) { - free(owner); - owner = strdup(user->info.username); - } + if (user == NULL) + return (void*) ((intptr_t) -1); - char* joinName = strdup("anonymous"); - if (joiner->info.username != NULL) { - free(joinName); - joinName = strdup(joiner->info.username); - } + char* owner = "owner"; + if (user->info.username != NULL) + owner = (char *) user->info.username; + + char* joinName = "anonymous"; + if (joiner->info.username != NULL) + joinName = (char *) joiner->info.username; guac_user_log(user, GUAC_LOG_DEBUG, "Notifying owner %s of %s joining.", owner, joinName); /* Send required parameters to owner. */ - if (user != NULL) { - const char* args[] = { (const char*)joinName, NULL }; - retval = guac_protocol_send_msg(user->socket, GUAC_MSG_CLIENT_JOINED, args); - } - - else - retval = -1; - - free(owner); - free(joinName); - - return (void*) ((intptr_t) retval); + const char* args[] = { (const char*)joinName, NULL }; + return (void*) ((intptr_t) guac_protocol_send_msg(user->socket, GUAC_MSG_CLIENT_JOINED, args)); } @@ -824,30 +812,22 @@ static void* guac_client_owner_notify_leave_callback(guac_user* user, void* data const guac_user* quitter = (const guac_user *) data; - char* ownerName = strdup("owner"); - if (user->info.username != NULL) { - free(ownerName); - ownerName = strdup(user->info.username); - } + if (user == NULL) + return (void*) ((intptr_t) -1); - char* quitterName = strdup("anonymous"); - if (quitter->info.username != NULL) { - free(quitterName); - quitterName = strdup(quitter->info.username); - } + char* ownerName = "owner"; + if (user->info.username != NULL) + ownerName = (char *) user->info.username; + + char* quitterName = "anonymous"; + if (quitter->info.username != NULL) + quitterName = (char *) quitter->info.username; guac_user_log(user, GUAC_LOG_DEBUG, "Notifying owner %s of %s leaving.", ownerName, quitterName); /* Send required parameters to owner. */ - if (user != NULL) { - const char* args[] = { (const char*)quitterName, NULL }; - return (void*) ((intptr_t) guac_protocol_send_msg(user->socket, GUAC_MSG_CLIENT_LEFT, args)); - } - - free(ownerName); - free(quitterName); - - return (void*) ((intptr_t) -1); + const char* args[] = { (const char*)quitterName, NULL }; + return (void*) ((intptr_t) guac_protocol_send_msg(user->socket, GUAC_MSG_CLIENT_LEFT, args)); } From 897712c7434823342894e414dae6d58eede89a98 Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Tue, 8 Nov 2022 07:09:54 -0500 Subject: [PATCH 07/10] GUACAMOLE-1293: Update and add debug logging. --- src/libguac/client.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/libguac/client.c b/src/libguac/client.c index b7526ec6..e8739580 100644 --- a/src/libguac/client.c +++ b/src/libguac/client.c @@ -772,7 +772,7 @@ static void* guac_client_owner_notify_join_callback(guac_user* user, void* data) if (joiner->info.username != NULL) joinName = (char *) joiner->info.username; - guac_user_log(user, GUAC_LOG_DEBUG, "Notifying owner %s of %s joining.", owner, joinName); + guac_user_log(user, GUAC_LOG_DEBUG, "Notifying owner \"%s\" of \"%s\" joining.", owner, joinName); /* Send required parameters to owner. */ const char* args[] = { (const char*)joinName, NULL }; @@ -783,8 +783,12 @@ static void* guac_client_owner_notify_join_callback(guac_user* user, void* data) int guac_client_owner_notify_join(guac_client* client, guac_user* joiner) { /* Don't send msg instruction if client does not support it. */ - if (!guac_client_owner_supports_msg(client)) + if (!guac_client_owner_supports_msg(client)) { + guac_client_log(client, GUAC_LOG_DEBUG, + "Client does not support the \"msg\" instruction and " + "will not be notified of the user joining the connection."); return -1; + } return (int) ((intptr_t) guac_client_for_owner(client, guac_client_owner_notify_join_callback, joiner)); @@ -823,7 +827,7 @@ static void* guac_client_owner_notify_leave_callback(guac_user* user, void* data if (quitter->info.username != NULL) quitterName = (char *) quitter->info.username; - guac_user_log(user, GUAC_LOG_DEBUG, "Notifying owner %s of %s leaving.", ownerName, quitterName); + guac_user_log(user, GUAC_LOG_DEBUG, "Notifying owner \"%s\" of \"%s\" leaving.", ownerName, quitterName); /* Send required parameters to owner. */ const char* args[] = { (const char*)quitterName, NULL }; @@ -834,8 +838,12 @@ static void* guac_client_owner_notify_leave_callback(guac_user* user, void* data int guac_client_owner_notify_leave(guac_client* client, guac_user* quitter) { /* Don't send msg instruction if client does not support it. */ - if (!guac_client_owner_supports_msg(client)) + if (!guac_client_owner_supports_msg(client)) { + guac_client_log(client, GUAC_LOG_DEBUG, + "Client does not support the \"msg\" instruction and " + "will not be notified of the user leaving the connection."); return -1; + } return (int) ((intptr_t) guac_client_for_owner(client, guac_client_owner_notify_leave_callback, quitter)); From aa92239eddd56820b47cb829d6ff6d1a1ce1b4f6 Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Tue, 8 Nov 2022 07:15:15 -0500 Subject: [PATCH 08/10] GUACAMOLE-1293: Rename new enum values to be more consistent with existing code. --- src/libguac/client.c | 4 ++-- src/libguac/guacamole/protocol-types.h | 8 ++++---- src/libguac/guacamole/protocol.h | 2 +- src/libguac/protocol.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libguac/client.c b/src/libguac/client.c index e8739580..9738d9b7 100644 --- a/src/libguac/client.c +++ b/src/libguac/client.c @@ -776,7 +776,7 @@ static void* guac_client_owner_notify_join_callback(guac_user* user, void* data) /* Send required parameters to owner. */ const char* args[] = { (const char*)joinName, NULL }; - return (void*) ((intptr_t) guac_protocol_send_msg(user->socket, GUAC_MSG_CLIENT_JOINED, args)); + return (void*) ((intptr_t) guac_protocol_send_msg(user->socket, GUAC_MESSAGE_USER_JOINED, args)); } @@ -831,7 +831,7 @@ static void* guac_client_owner_notify_leave_callback(guac_user* user, void* data /* Send required parameters to owner. */ const char* args[] = { (const char*)quitterName, NULL }; - return (void*) ((intptr_t) guac_protocol_send_msg(user->socket, GUAC_MSG_CLIENT_LEFT, args)); + return (void*) ((intptr_t) guac_protocol_send_msg(user->socket, GUAC_MESSAGE_USER_LEFT, args)); } diff --git a/src/libguac/guacamole/protocol-types.h b/src/libguac/guacamole/protocol-types.h index 5bb1e04c..5c209c89 100644 --- a/src/libguac/guacamole/protocol-types.h +++ b/src/libguac/guacamole/protocol-types.h @@ -323,23 +323,23 @@ typedef enum guac_protocol_version { * The codes will be interpreted by the client into translatable messages, and * make take arguments, as noted below. */ -typedef enum guac_msg_client { +typedef enum guac_message_type { /** * A message that notifies the owner of a connection that another user has * joined their connection. There should be a single argument, the username * of the user who has joined. */ - GUAC_MSG_CLIENT_JOINED = 0x0001, + GUAC_MESSAGE_USER_JOINED = 0x0001, /** * A message that notifies the owner of a connection that another user has * left their connection. There should be a single argument provided, the * username of the user who has left. */ - GUAC_MSG_CLIENT_LEFT = 0x0002 + GUAC_MESSAGE_USER_LEFT = 0x0002 -} guac_msg_client; +} guac_message_type; #endif diff --git a/src/libguac/guacamole/protocol.h b/src/libguac/guacamole/protocol.h index 16111314..91debdde 100644 --- a/src/libguac/guacamole/protocol.h +++ b/src/libguac/guacamole/protocol.h @@ -189,7 +189,7 @@ int vguac_protocol_send_log(guac_socket* socket, const char* format, * @return * Zero if the message is sent successfully; otherwise non-zero. */ -int guac_protocol_send_msg(guac_socket* socket, guac_msg_client msg, +int guac_protocol_send_msg(guac_socket* socket, guac_message_type msg, const char** args); /** diff --git a/src/libguac/protocol.c b/src/libguac/protocol.c index 407b056e..3421af50 100644 --- a/src/libguac/protocol.c +++ b/src/libguac/protocol.c @@ -659,7 +659,7 @@ int guac_protocol_send_log(guac_socket* socket, const char* format, ...) { } -int guac_protocol_send_msg(guac_socket* socket, guac_msg_client msg, +int guac_protocol_send_msg(guac_socket* socket, guac_message_type msg, const char** args) { int ret_val; From 623c398005b626039e3427be3b049e7155caf6f1 Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Tue, 8 Nov 2022 07:44:11 -0500 Subject: [PATCH 09/10] GUACAMOLE-1293: Change new user info member to simply "name" to clarify its purpose. --- src/libguac/client.c | 16 ++++++++-------- src/libguac/guacamole/protocol-types.h | 8 ++++---- src/libguac/guacamole/user.h | 14 ++++++++------ src/libguac/user-handlers.c | 12 ++++++------ src/libguac/user-handlers.h | 4 ++-- src/libguac/user-handshake.c | 6 +++--- 6 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/libguac/client.c b/src/libguac/client.c index 9738d9b7..d91f3d32 100644 --- a/src/libguac/client.c +++ b/src/libguac/client.c @@ -765,12 +765,12 @@ static void* guac_client_owner_notify_join_callback(guac_user* user, void* data) return (void*) ((intptr_t) -1); char* owner = "owner"; - if (user->info.username != NULL) - owner = (char *) user->info.username; + if (user->info.name != NULL) + owner = (char *) user->info.name; char* joinName = "anonymous"; - if (joiner->info.username != NULL) - joinName = (char *) joiner->info.username; + if (joiner->info.name != NULL) + joinName = (char *) joiner->info.name; guac_user_log(user, GUAC_LOG_DEBUG, "Notifying owner \"%s\" of \"%s\" joining.", owner, joinName); @@ -820,12 +820,12 @@ static void* guac_client_owner_notify_leave_callback(guac_user* user, void* data return (void*) ((intptr_t) -1); char* ownerName = "owner"; - if (user->info.username != NULL) - ownerName = (char *) user->info.username; + if (user->info.name != NULL) + ownerName = (char *) user->info.name; char* quitterName = "anonymous"; - if (quitter->info.username != NULL) - quitterName = (char *) quitter->info.username; + if (quitter->info.name != NULL) + quitterName = (char *) quitter->info.name; guac_user_log(user, GUAC_LOG_DEBUG, "Notifying owner \"%s\" of \"%s\" leaving.", ownerName, quitterName); diff --git a/src/libguac/guacamole/protocol-types.h b/src/libguac/guacamole/protocol-types.h index 5c209c89..c943b431 100644 --- a/src/libguac/guacamole/protocol-types.h +++ b/src/libguac/guacamole/protocol-types.h @@ -310,7 +310,7 @@ typedef enum guac_protocol_version { /** * Protocol version 1.5.0, which supports the "msg" instruction, allowing - * messages to be sent to the client, and adds support for the "username" + * messages to be sent to the client, and adds support for the "name" * handshake instruction. */ GUAC_PROTOCOL_VERSION_1_5_0 = 0x010500 @@ -327,15 +327,15 @@ typedef enum guac_message_type { /** * A message that notifies the owner of a connection that another user has - * joined their connection. There should be a single argument, the username - * of the user who has joined. + * joined their connection. There should be a single argument provided, the + * name of the user who has joined. */ GUAC_MESSAGE_USER_JOINED = 0x0001, /** * A message that notifies the owner of a connection that another user has * left their connection. There should be a single argument provided, the - * username of the user who has left. + * name of the user who has left. */ GUAC_MESSAGE_USER_LEFT = 0x0002 diff --git a/src/libguac/guacamole/user.h b/src/libguac/guacamole/user.h index dc27bb6d..13fb146d 100644 --- a/src/libguac/guacamole/user.h +++ b/src/libguac/guacamole/user.h @@ -88,12 +88,6 @@ struct guac_user_info { * stated resolution of the display size request is recommended. */ int optimal_resolution; - - /** - * The human-readable name of the Guacamole user. If the client does not - * provide a name then this will be NULL. - */ - const char* username; /** * The timezone of the remote system. If the client does not provide @@ -108,6 +102,14 @@ struct guac_user_info { */ guac_protocol_version protocol_version; + /** + * The human-readable name of the Guacamole user, supplied by the client + * during the handshake. This is an arbitrary value, with no requirements or + * constraints, including that it need not uniquely identify the user. + * If the client does not provide a name then this will be NULL. + */ + const char* name; + }; struct guac_user { diff --git a/src/libguac/user-handlers.c b/src/libguac/user-handlers.c index 66488c6a..db1e7b8b 100644 --- a/src/libguac/user-handlers.c +++ b/src/libguac/user-handlers.c @@ -64,7 +64,7 @@ __guac_instruction_handler_mapping __guac_handshake_handler_map[] = { {"video", __guac_handshake_video_handler}, {"image", __guac_handshake_image_handler}, {"timezone", __guac_handshake_timezone_handler}, - {"username", __guac_handshake_username_handler}, + {"name", __guac_handshake_name_handler}, {NULL, NULL} }; @@ -677,18 +677,18 @@ int __guac_handshake_image_handler(guac_user* user, int argc, char** argv) { } -int __guac_handshake_username_handler(guac_user* user, int argc, char** argv) { +int __guac_handshake_name_handler(guac_user* user, int argc, char** argv) { /* Free any past value for the user's name */ - free((char *) user->info.username); + free((char *) user->info.name); - /* If a value is provided for the username, copy it into guac_user. */ + /* If a value is provided for the name, copy it into guac_user. */ if (argc > 0 && strcmp(argv[0], "")) - user->info.username = (const char*) strdup(argv[0]); + user->info.name = (const char*) strdup(argv[0]); /* No or empty value was provided, so make sure this is NULLed out. */ else - user->info.username = NULL; + user->info.name = NULL; return 0; diff --git a/src/libguac/user-handlers.h b/src/libguac/user-handlers.h index 785e5b6b..7f82302b 100644 --- a/src/libguac/user-handlers.h +++ b/src/libguac/user-handlers.h @@ -219,11 +219,11 @@ __guac_instruction_handler __guac_handshake_video_handler; __guac_instruction_handler __guac_handshake_image_handler; /** - * Internal handler function that is called when the username instruction is + * Internal handler function that is called when the name instruction is * received during the handshake process, specifying the name of the Guacamole * user establishing the connection. */ -__guac_instruction_handler __guac_handshake_username_handler; +__guac_instruction_handler __guac_handshake_name_handler; /** * Internal handler function that is called when the timezone instruction is diff --git a/src/libguac/user-handshake.c b/src/libguac/user-handshake.c index e2910f0e..0863325f 100644 --- a/src/libguac/user-handshake.c +++ b/src/libguac/user-handshake.c @@ -296,7 +296,7 @@ int guac_user_handle_connection(guac_user* user, int usec_timeout) { user->info.audio_mimetypes = NULL; user->info.image_mimetypes = NULL; user->info.video_mimetypes = NULL; - user->info.username = NULL; + user->info.name = NULL; user->info.timezone = NULL; /* Count number of arguments. */ @@ -371,8 +371,8 @@ int guac_user_handle_connection(guac_user* user, int usec_timeout) { guac_free_mimetypes((char **) user->info.image_mimetypes); guac_free_mimetypes((char **) user->info.video_mimetypes); - /* Free username and timezone info. */ - free((char *) user->info.username); + /* Free name and timezone info. */ + free((char *) user->info.name); free((char *) user->info.timezone); guac_parser_free(parser); From 5b1677f21ab4608d35c96d592dd8e318f934574b Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Thu, 24 Nov 2022 18:12:49 -0500 Subject: [PATCH 10/10] GUACAMOLE-1293: Fix copy-pasta and style issues; add user ID to information passed to client. --- src/libguac/client.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/libguac/client.c b/src/libguac/client.c index d91f3d32..29fb5b78 100644 --- a/src/libguac/client.c +++ b/src/libguac/client.c @@ -764,18 +764,22 @@ static void* guac_client_owner_notify_join_callback(guac_user* user, void* data) if (user == NULL) return (void*) ((intptr_t) -1); - char* owner = "owner"; + char* log_owner = "owner"; if (user->info.name != NULL) - owner = (char *) user->info.name; + log_owner = (char *) user->info.name; - char* joinName = "anonymous"; - if (joiner->info.name != NULL) - joinName = (char *) joiner->info.name; + char* log_joiner = "anonymous"; + char* send_joiner = ""; + if (joiner->info.name != NULL) { + log_joiner = (char *) joiner->info.name; + send_joiner = (char *) joiner->info.name; + } - guac_user_log(user, GUAC_LOG_DEBUG, "Notifying owner \"%s\" of \"%s\" joining.", owner, joinName); + guac_user_log(user, GUAC_LOG_DEBUG, "Notifying owner \"%s\" of \"%s\" joining.", + log_owner, log_joiner); - /* Send required parameters to owner. */ - const char* args[] = { (const char*)joinName, NULL }; + /* Send user joined notification to owner. */ + const char* args[] = { (const char*)joiner->user_id, (const char*)send_joiner, NULL }; return (void*) ((intptr_t) guac_protocol_send_msg(user->socket, GUAC_MESSAGE_USER_JOINED, args)); } @@ -819,18 +823,22 @@ static void* guac_client_owner_notify_leave_callback(guac_user* user, void* data if (user == NULL) return (void*) ((intptr_t) -1); - char* ownerName = "owner"; + char* log_owner = "owner"; if (user->info.name != NULL) - ownerName = (char *) user->info.name; + log_owner = (char *) user->info.name; - char* quitterName = "anonymous"; - if (quitter->info.name != NULL) - quitterName = (char *) quitter->info.name; + char* log_quitter = "anonymous"; + char* send_quitter = ""; + if (quitter->info.name != NULL) { + log_quitter = (char *) quitter->info.name; + send_quitter = (char *) quitter->info.name; + } - guac_user_log(user, GUAC_LOG_DEBUG, "Notifying owner \"%s\" of \"%s\" leaving.", ownerName, quitterName); + guac_user_log(user, GUAC_LOG_DEBUG, "Notifying owner \"%s\" of \"%s\" leaving.", + log_owner, log_quitter); - /* Send required parameters to owner. */ - const char* args[] = { (const char*)quitterName, NULL }; + /* Send user left notification to owner. */ + const char* args[] = { (const char*)quitter->user_id, (const char*)send_quitter, NULL }; return (void*) ((intptr_t) guac_protocol_send_msg(user->socket, GUAC_MESSAGE_USER_LEFT, args)); }