[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r365613342
##
File path: src/protocols/rdp/channels/cliprdr.c
##
@@ -0,0 +1,605 @@
+/*
+ * 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 "channels/cliprdr.h"
+#include "client.h"
+#include "common/clipboard.h"
+#include "common/iconv.h"
+#include "plugins/channels.h"
+#include "rdp.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+/**
+ * Sends a Format List PDU to the RDP server containing the formats of
+ * clipboard data supported. This PDU is used both to indicate the general
+ * clipboard formats supported at the begining of an RDP session and to inform
+ * the RDP server that new clipboard data is available within the listed
+ * formats.
+ *
+ * @param cliprdr
+ * The CliprdrClientContext structure used by FreeRDP to handle the
+ * CLIPRDR channel for the current RDP session.
+ *
+ * @return
+ * CHANNEL_RC_OK (zero) if the Format List PDU was sent successfully, an
+ * error code (non-zero) otherwise.
+ */
+static UINT guac_rdp_cliprdr_send_format_list(CliprdrClientContext* cliprdr) {
+
+/* This function is only invoked within FreeRDP-specific handlers for
+ * CLIPRDR, which are not assigned, and thus not callable, until after the
+ * relevant guac_rdp_clipboard structure is allocated and associated with
+ * the CliprdrClientContext */
+guac_rdp_clipboard* clipboard = (guac_rdp_clipboard*) cliprdr->custom;
+assert(clipboard != NULL);
+
+/* We support CP-1252 and UTF-16 text */
+CLIPRDR_FORMAT_LIST format_list = {
+.formats = (CLIPRDR_FORMAT[]) {
+{ .formatId = CF_TEXT },
+{ .formatId = CF_UNICODETEXT }
+},
+.numFormats = 2
+};
+
+guac_client_log(clipboard->client, GUAC_LOG_TRACE, "CLIPRDR: Sending "
+"format list");
+
+return cliprdr->ClientFormatList(cliprdr, &format_list);
+
+}
+
+/**
+ * Sends a Clipboard Capabilities PDU to the RDP server describing the features
+ * of the CLIPRDR channel that are supported by the client.
+ *
+ * @param cliprdr
+ * The CliprdrClientContext structure used by FreeRDP to handle the
+ * CLIPRDR channel for the current RDP session.
+ *
+ * @return
+ * CHANNEL_RC_OK (zero) if the Clipboard Capabilities PDU was sent
+ * successfully, an error code (non-zero) otherwise.
+ */
+static UINT guac_rdp_cliprdr_send_capabilities(CliprdrClientContext* cliprdr) {
+
+CLIPRDR_GENERAL_CAPABILITY_SET cap_set = {
+.capabilitySetType = CB_CAPSTYPE_GENERAL, /* CLIPRDR specification
requires that this is CB_CAPSTYPE_GENERAL, the only defined set type */
+.capabilitySetLength = 12, /* The size of the capability set within
the PDU - for CB_CAPSTYPE_GENERAL, this is ALWAYS 12 bytes */
+.version = CB_CAPS_VERSION_2, /* The version of the CLIPRDR
specification supported */
+.generalFlags = CB_USE_LONG_FORMAT_NAMES /* Bitwise OR of all
supported feature flags */
+};
+
+CLIPRDR_CAPABILITIES caps = {
+.cCapabilitiesSets = 1,
+.capabilitySets = (CLIPRDR_CAPABILITY_SET*) &cap_set
+};
+
+return cliprdr->ClientCapabilities(cliprdr, &caps);
+
+}
+
+/**
+ * Callback invoked by the FreeRDP CLIPRDR plugin for received Monitor Ready
+ * PDUs. The Monitor Ready PDU is sent by the RDP server only during
+ * initialization of the CLIPRDR channel. It is part of the CLIPRDR channel
+ * handshake and indicates that the RDP server's handling of clipboard
+ * redirection is ready to proceed.
+ *
+ * @param cliprdr
+ * The CliprdrClientContext structure used by FreeRDP to handle the CLIPRDR
+ * channel for the current RDP session.
+ *
+ * @param monitor_ready
+ * The CLIPRDR_MONITOR_READY structure representing the Monitor Ready PDU
+ * that was received.
+ *
+ * @return
+ * CHANNEL_RC_OK (zero) if the PDU was handled successfully, an error code
+ * (non-zero) otherwise.
+ */
+static UINT guac_rdp_cliprdr_monitor_ready(CliprdrClientContext* cliprdr,
+
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r365556619
##
File path: src/protocols/rdp/bitmap.h
##
@@ -66,8 +61,11 @@ typedef struct guac_rdp_bitmap {
*
* @param bitmap
* The bitmap to cache.
+ *
+ * @return
+ * TRUE if successful, FALSE otherwise.
Review comment:
Regarding the other cases, yes - the other functions are written to comply
with the API of the FreeRDP library, which does require a `BOOL` return to
signal failures, even if our implementation doesn't have a failure condition in
most (all?) cases.
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r365556483
##
File path: src/protocols/rdp/channels/cliprdr.c
##
@@ -0,0 +1,601 @@
+/*
+ * 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 "channels/cliprdr.h"
+#include "client.h"
+#include "common/clipboard.h"
+#include "common/iconv.h"
+#include "plugins/channels.h"
+#include "rdp.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+/**
+ * Sends a Format List PDU to the RDP server containing the formats of
+ * clipboard data supported. This PDU is used both to indicate the general
+ * clipboard formats supported at the begining of an RDP session and to inform
+ * the RDP server that new clipboard data is available within the listed
+ * formats.
+ *
+ * @param cliprdr
+ * The CliprdrClientContext structure used by FreeRDP to handle the
+ * CLIPRDR channel for the current RDP session.
+ *
+ * @return
+ * CHANNEL_RC_OK (zero) if the Format List PDU was sent successfully, an
+ * error code (non-zero) otherwise.
+ */
+static UINT guac_rdp_cliprdr_send_format_list(CliprdrClientContext* cliprdr) {
+
+/* This function is only invoked within FreeRDP-specific handlers for
+ * CLIPRDR, which are not assigned, and thus not callable, until after the
+ * relevant guac_rdp_clipboard structure is allocated and associated with
+ * the CliprdrClientContext */
+guac_rdp_clipboard* clipboard = (guac_rdp_clipboard*) cliprdr->custom;
+assert(clipboard != NULL);
+
+/* We support CP-1252 and UTF-16 text */
+CLIPRDR_FORMAT_LIST format_list = {
+.formats = (CLIPRDR_FORMAT[]) {
+{ .formatId = CF_TEXT },
+{ .formatId = CF_UNICODETEXT }
+},
+.numFormats = 2
+};
+
+guac_client_log(clipboard->client, GUAC_LOG_TRACE, "CLIPRDR: Sending "
+"format list");
+
+return cliprdr->ClientFormatList(cliprdr, &format_list);
+
+}
+
+/**
+ * Sends a Clipboard Capabilities PDU to the RDP server describing the features
+ * of the CLIPRDR channel that are supported by the client.
+ *
+ * @param cliprdr
+ * The CliprdrClientContext structure used by FreeRDP to handle the
+ * CLIPRDR channel for the current RDP session.
+ *
+ * @return
+ * CHANNEL_RC_OK (zero) if the Clipboard Capabilities PDU was sent
+ * successfully, an error code (non-zero) otherwise.
+ */
+static UINT guac_rdp_cliprdr_send_capabilities(CliprdrClientContext* cliprdr) {
+
+CLIPRDR_GENERAL_CAPABILITY_SET cap_set = {
+.capabilitySetType = CB_CAPSTYPE_GENERAL, /* CLIPRDR specification
requires that this is CB_CAPSTYPE_GENERAL, the only defined set type */
+.capabilitySetLength = 12, /* The size of the capability set within
the PDU - for CB_CAPSTYPE_GENERAL, this is ALWAYS 12 bytes */
+.version = CB_CAPS_VERSION_2, /* The version of the CLIPRDR
specification supported */
+.generalFlags = CB_USE_LONG_FORMAT_NAMES /* Bitwise OR of all
supported feature flags */
+};
+
+CLIPRDR_CAPABILITIES caps = {
+.cCapabilitiesSets = 1,
+.capabilitySets = (CLIPRDR_CAPABILITY_SET*) &cap_set
+};
+
+return cliprdr->ClientCapabilities(cliprdr, &caps);
+
+}
+
+/**
+ * Callback invoked by the FreeRDP CLIPRDR plugin for received Monitor Ready
+ * PDUs. The Monitor Ready PDU is sent by the RDP server only during
+ * initialization of the CLIPRDR channel. It is part of the CLIPRDR channel
+ * handshake and indicates that the RDP server's handling of clipboard
+ * redirection is ready to proceed.
+ *
+ * @param cliprdr
+ * The CliprdrClientContext structure used by FreeRDP to handle the CLIPRDR
+ * channel for the current RDP session.
+ *
+ * @param monitor_ready
+ * The CLIPRDR_MONITOR_READY structure representing the Monitor Ready PDU
+ * that was received.
+ *
+ * @return
+ * CHANNEL_RC_OK (zero) if the PDU was handled successfully, an error code
+ * (non-zero) otherwise.
+ */
+static UINT guac_rdp_cliprdr_monitor_ready(CliprdrClientContext* cliprdr,
+
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r365556441
##
File path: src/protocols/rdp/channels/cliprdr.c
##
@@ -0,0 +1,601 @@
+/*
+ * 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 "channels/cliprdr.h"
+#include "client.h"
+#include "common/clipboard.h"
+#include "common/iconv.h"
+#include "plugins/channels.h"
+#include "rdp.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+/**
+ * Sends a Format List PDU to the RDP server containing the formats of
+ * clipboard data supported. This PDU is used both to indicate the general
+ * clipboard formats supported at the begining of an RDP session and to inform
+ * the RDP server that new clipboard data is available within the listed
+ * formats.
+ *
+ * @param cliprdr
+ * The CliprdrClientContext structure used by FreeRDP to handle the
+ * CLIPRDR channel for the current RDP session.
+ *
+ * @return
+ * CHANNEL_RC_OK (zero) if the Format List PDU was sent successfully, an
+ * error code (non-zero) otherwise.
+ */
+static UINT guac_rdp_cliprdr_send_format_list(CliprdrClientContext* cliprdr) {
+
+/* This function is only invoked within FreeRDP-specific handlers for
+ * CLIPRDR, which are not assigned, and thus not callable, until after the
+ * relevant guac_rdp_clipboard structure is allocated and associated with
+ * the CliprdrClientContext */
+guac_rdp_clipboard* clipboard = (guac_rdp_clipboard*) cliprdr->custom;
+assert(clipboard != NULL);
+
+/* We support CP-1252 and UTF-16 text */
+CLIPRDR_FORMAT_LIST format_list = {
+.formats = (CLIPRDR_FORMAT[]) {
+{ .formatId = CF_TEXT },
+{ .formatId = CF_UNICODETEXT }
+},
+.numFormats = 2
+};
+
+guac_client_log(clipboard->client, GUAC_LOG_TRACE, "CLIPRDR: Sending "
+"format list");
+
+return cliprdr->ClientFormatList(cliprdr, &format_list);
+
+}
+
+/**
+ * Sends a Clipboard Capabilities PDU to the RDP server describing the features
+ * of the CLIPRDR channel that are supported by the client.
+ *
+ * @param cliprdr
+ * The CliprdrClientContext structure used by FreeRDP to handle the
+ * CLIPRDR channel for the current RDP session.
+ *
+ * @return
+ * CHANNEL_RC_OK (zero) if the Clipboard Capabilities PDU was sent
+ * successfully, an error code (non-zero) otherwise.
+ */
+static UINT guac_rdp_cliprdr_send_capabilities(CliprdrClientContext* cliprdr) {
+
+CLIPRDR_GENERAL_CAPABILITY_SET cap_set = {
+.capabilitySetType = CB_CAPSTYPE_GENERAL, /* CLIPRDR specification
requires that this is CB_CAPSTYPE_GENERAL, the only defined set type */
+.capabilitySetLength = 12, /* The size of the capability set within
the PDU - for CB_CAPSTYPE_GENERAL, this is ALWAYS 12 bytes */
+.version = CB_CAPS_VERSION_2, /* The version of the CLIPRDR
specification supported */
+.generalFlags = CB_USE_LONG_FORMAT_NAMES /* Bitwise OR of all
supported feature flags */
+};
+
+CLIPRDR_CAPABILITIES caps = {
+.cCapabilitiesSets = 1,
+.capabilitySets = (CLIPRDR_CAPABILITY_SET*) &cap_set
+};
+
+return cliprdr->ClientCapabilities(cliprdr, &caps);
+
+}
+
+/**
+ * Callback invoked by the FreeRDP CLIPRDR plugin for received Monitor Ready
+ * PDUs. The Monitor Ready PDU is sent by the RDP server only during
+ * initialization of the CLIPRDR channel. It is part of the CLIPRDR channel
+ * handshake and indicates that the RDP server's handling of clipboard
+ * redirection is ready to proceed.
+ *
+ * @param cliprdr
+ * The CliprdrClientContext structure used by FreeRDP to handle the CLIPRDR
+ * channel for the current RDP session.
+ *
+ * @param monitor_ready
+ * The CLIPRDR_MONITOR_READY structure representing the Monitor Ready PDU
+ * that was received.
+ *
+ * @return
+ * CHANNEL_RC_OK (zero) if the PDU was handled successfully, an error code
+ * (non-zero) otherwise.
+ */
+static UINT guac_rdp_cliprdr_monitor_ready(CliprdrClientContext* cliprdr,
+
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r36946
##
File path: src/protocols/rdp/upload.c
##
@@ -0,0 +1,236 @@
+/*
+ * 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 "fs.h"
+#include "rdp.h"
+#include "upload.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+/**
+ * Writes the given filename to the given upload path, sanitizing the filename
+ * and translating the filename to the root directory.
+ *
+ * @param filename
+ * The filename to sanitize and move to the root directory.
+ *
+ * @param path
+ * A pointer to a buffer which should receive the sanitized path. The
+ * buffer must have at least GUAC_RDP_FS_MAX_PATH bytes available.
+ */
+static void __generate_upload_path(const char* filename, char* path) {
+
+int i;
+
+/* Add initial backslash */
+*(path++) = '\\';
+
+for (i=1; iclient;
+guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
+
+int file_id;
+char file_path[GUAC_RDP_FS_MAX_PATH];
+
+/* Get filesystem, return error if no filesystem */
+guac_rdp_fs* fs = rdp_client->filesystem;
+if (fs == NULL) {
+guac_protocol_send_ack(user->socket, stream, "FAIL (NO FS)",
+GUAC_PROTOCOL_STATUS_SERVER_ERROR);
+guac_socket_flush(user->socket);
+return 0;
+}
Review comment:
Yep - the error is being returned to the user via the `ack`. The received
instruction has otherwise been successfully handled and the rest of the user's
connection can continue.
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r36874
##
File path: src/protocols/rdp/channels/pipe-svc.c
##
@@ -0,0 +1,230 @@
+/*
+ * 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 "channels/common-svc.h"
+#include "channels/pipe-svc.h"
+#include "common/list.h"
+#include "rdp.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+void guac_rdp_pipe_svc_send_pipe(guac_socket* socket, guac_rdp_pipe_svc*
pipe_svc) {
+
+/* Send pipe instruction for the SVC's output stream */
+guac_protocol_send_pipe(socket, pipe_svc->output_pipe,
+"application/octet-stream", pipe_svc->svc->name);
+
+}
+
+void guac_rdp_pipe_svc_send_pipes(guac_user* user) {
+
+guac_client* client = user->client;
+guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
+
+guac_common_list_lock(rdp_client->available_svc);
+
+/* Send pipe for each allocated SVC's output stream */
+guac_common_list_element* current = rdp_client->available_svc->head;
+while (current != NULL) {
+guac_rdp_pipe_svc_send_pipe(user->socket, (guac_rdp_pipe_svc*)
current->data);
+current = current->next;
+}
+
+guac_common_list_unlock(rdp_client->available_svc);
+
+}
+
+void guac_rdp_pipe_svc_add(guac_client* client, guac_rdp_pipe_svc* pipe_svc) {
+
+guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
+
+/* Add to list of available SVC */
+guac_common_list_lock(rdp_client->available_svc);
+guac_common_list_add(rdp_client->available_svc, pipe_svc);
+guac_common_list_unlock(rdp_client->available_svc);
+
+}
+
+guac_rdp_pipe_svc* guac_rdp_pipe_svc_get(guac_client* client, const char*
name) {
+
+guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
+guac_common_list_element* current;
+guac_rdp_pipe_svc* found = NULL;
+
+/* For each available SVC */
+guac_common_list_lock(rdp_client->available_svc);
+current = rdp_client->available_svc->head;
+while (current != NULL) {
+
+/* If name matches, found */
+guac_rdp_pipe_svc* current_svc = (guac_rdp_pipe_svc*) current->data;
+if (strcmp(current_svc->svc->name, name) == 0) {
+found = current_svc;
+break;
+}
+
+current = current->next;
+
+}
+guac_common_list_unlock(rdp_client->available_svc);
+
+return found;
+
+}
+
+guac_rdp_pipe_svc* guac_rdp_pipe_svc_remove(guac_client* client, const char*
name) {
+
+guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
+guac_common_list_element* current;
+guac_rdp_pipe_svc* found = NULL;
+
+/* For each available SVC */
+guac_common_list_lock(rdp_client->available_svc);
+current = rdp_client->available_svc->head;
+while (current != NULL) {
+
+/* If name matches, remove entry */
+guac_rdp_pipe_svc* current_svc = (guac_rdp_pipe_svc*) current->data;
+if (strcmp(current_svc->svc->name, name) == 0) {
+guac_common_list_remove(rdp_client->available_svc, current);
+found = current_svc;
+break;
+}
+
+current = current->next;
+
+}
+guac_common_list_unlock(rdp_client->available_svc);
+
+/* Return removed entry, if any */
+return found;
+
+}
+
+int guac_rdp_pipe_svc_pipe_handler(guac_user* user, guac_stream* stream,
+char* mimetype, char* name) {
+
+guac_rdp_pipe_svc* pipe_svc = guac_rdp_pipe_svc_get(user->client, name);
+
+/* Fail if no such SVC */
+if (pipe_svc == NULL) {
+guac_user_log(user, GUAC_LOG_WARNING, "User requested non-existent "
+"pipe (no such SVC configured): \"%s\"", name);
+guac_protocol_send_ack(user->socket, stream, "FAIL (NO SUCH PIPE)",
+GUAC_PROTOCOL_STATUS_CLIENT_BAD_REQUEST);
+guac_socket_flush(user->socket);
+return 0;
Review comment:
Yes. Returning an error code from within an instruction handler aborts the
user's connection:
https://github.com/apache/guacamole-server/blob/381ff1
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r36236
##
File path: src/protocols/rdp/bitmap.h
##
@@ -66,8 +61,11 @@ typedef struct guac_rdp_bitmap {
*
* @param bitmap
* The bitmap to cache.
+ *
+ * @return
+ * TRUE if successful, FALSE otherwise.
Review comment:
In this case, no, I don't believe so. I was probably just on a roll with
`BOOL`-ing everything.
I'll recheck the body of the function and switch things back to `void` if
`BOOL` is not needed. The fewer things need changing, the better.
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r36182
##
File path: src/protocols/rdp/channels/cliprdr.c
##
@@ -0,0 +1,601 @@
+/*
+ * 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 "channels/cliprdr.h"
+#include "client.h"
+#include "common/clipboard.h"
+#include "common/iconv.h"
+#include "plugins/channels.h"
+#include "rdp.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+/**
+ * Sends a Format List PDU to the RDP server containing the formats of
+ * clipboard data supported. This PDU is used both to indicate the general
+ * clipboard formats supported at the begining of an RDP session and to inform
+ * the RDP server that new clipboard data is available within the listed
+ * formats.
+ *
+ * @param cliprdr
+ * The CliprdrClientContext structure used by FreeRDP to handle the
+ * CLIPRDR channel for the current RDP session.
+ *
+ * @return
+ * CHANNEL_RC_OK (zero) if the Format List PDU was sent successfully, an
+ * error code (non-zero) otherwise.
+ */
+static UINT guac_rdp_cliprdr_send_format_list(CliprdrClientContext* cliprdr) {
+
+/* This function is only invoked within FreeRDP-specific handlers for
+ * CLIPRDR, which are not assigned, and thus not callable, until after the
+ * relevant guac_rdp_clipboard structure is allocated and associated with
+ * the CliprdrClientContext */
+guac_rdp_clipboard* clipboard = (guac_rdp_clipboard*) cliprdr->custom;
+assert(clipboard != NULL);
+
+/* We support CP-1252 and UTF-16 text */
+CLIPRDR_FORMAT_LIST format_list = {
+.formats = (CLIPRDR_FORMAT[]) {
+{ .formatId = CF_TEXT },
+{ .formatId = CF_UNICODETEXT }
+},
+.numFormats = 2
+};
+
+guac_client_log(clipboard->client, GUAC_LOG_TRACE, "CLIPRDR: Sending "
+"format list");
+
+return cliprdr->ClientFormatList(cliprdr, &format_list);
+
+}
+
+/**
+ * Sends a Clipboard Capabilities PDU to the RDP server describing the features
+ * of the CLIPRDR channel that are supported by the client.
+ *
+ * @param cliprdr
+ * The CliprdrClientContext structure used by FreeRDP to handle the
+ * CLIPRDR channel for the current RDP session.
+ *
+ * @return
+ * CHANNEL_RC_OK (zero) if the Clipboard Capabilities PDU was sent
+ * successfully, an error code (non-zero) otherwise.
+ */
+static UINT guac_rdp_cliprdr_send_capabilities(CliprdrClientContext* cliprdr) {
+
+CLIPRDR_GENERAL_CAPABILITY_SET cap_set = {
+.capabilitySetType = CB_CAPSTYPE_GENERAL, /* CLIPRDR specification
requires that this is CB_CAPSTYPE_GENERAL, the only defined set type */
+.capabilitySetLength = 12, /* The size of the capability set within
the PDU - for CB_CAPSTYPE_GENERAL, this is ALWAYS 12 bytes */
+.version = CB_CAPS_VERSION_2, /* The version of the CLIPRDR
specification supported */
+.generalFlags = CB_USE_LONG_FORMAT_NAMES /* Bitwise OR of all
supported feature flags */
+};
+
+CLIPRDR_CAPABILITIES caps = {
+.cCapabilitiesSets = 1,
+.capabilitySets = (CLIPRDR_CAPABILITY_SET*) &cap_set
+};
+
+return cliprdr->ClientCapabilities(cliprdr, &caps);
+
+}
+
+/**
+ * Callback invoked by the FreeRDP CLIPRDR plugin for received Monitor Ready
+ * PDUs. The Monitor Ready PDU is sent by the RDP server only during
+ * initialization of the CLIPRDR channel. It is part of the CLIPRDR channel
+ * handshake and indicates that the RDP server's handling of clipboard
+ * redirection is ready to proceed.
+ *
+ * @param cliprdr
+ * The CliprdrClientContext structure used by FreeRDP to handle the CLIPRDR
+ * channel for the current RDP session.
+ *
+ * @param monitor_ready
+ * The CLIPRDR_MONITOR_READY structure representing the Monitor Ready PDU
+ * that was received.
+ *
+ * @return
+ * CHANNEL_RC_OK (zero) if the PDU was handled successfully, an error code
+ * (non-zero) otherwise.
+ */
+static UINT guac_rdp_cliprdr_monitor_ready(CliprdrClientContext* cliprdr,
+
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r36126
##
File path: src/protocols/rdp/channels/pipe-svc.h
##
@@ -0,0 +1,188 @@
+/*
+ * 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 GUAC_RDP_CHANNELS_PIPE_SVC_H
+#define GUAC_RDP_CHANNELS_PIPE_SVC_H
+
+#include "channels/common-svc.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/**
+ * The maximum number of bytes to allow within each channel name, including
+ * null terminator.
+ */
+#define GUAC_RDP_SVC_MAX_LENGTH 8
+
+/**
+ * Structure describing a static virtual channel and a corresponding Guacamole
+ * pipe stream;
+ */
+typedef struct guac_rdp_pipe_svc {
+
+/**
+ * The output pipe, opened when the RDP server receives a connection to
+ * the static channel.
+ */
+guac_stream* output_pipe;
+
+/**
+ * The underlying static channel. Data written to this SVC by the RDP
+ * server will be forwarded along the pipe stream to the Guacamole client,
+ * and data written to the pipe stream by the Guacamole client will be
+ * forwarded along the SVC to the RDP server.
+ */
+guac_rdp_common_svc* svc;
+
+} guac_rdp_pipe_svc;
+
+/**
+ * Initializes arbitrary static virtual channel (SVC) support for RDP, handling
+ * communication for the SVC having the given name. Data sent from within the
+ * RDP session using this channel will be sent along an identically-named pipe
+ * stream to the Guacamole client, and data sent along a pipe stream having the
+ * same name will be written to the SVC and received within the RDP session. If
+ * failures occur while loading the plugin, messages noting the specifics of
+ * those failures will be logged, and support for the given channel will not be
+ * functional.
+ *
+ * This MUST be called within the PreConnect callback of the freerdp instance
+ * for static virtual channel support to be loaded.
+ *
+ * @param context
+ * The rdpContext associated with the FreeRDP side of the RDP connection.
+ *
+ * @param name
+ * The name of the SVC which should be handled.
+ */
+void guac_rdp_pipe_svc_load_plugin(rdpContext* context, char* name);
+
+/**
+ * Sends the "pipe" instruction describing the given static virtual channel
+ * along the given socket. This pipe instruction will relate the SVC's
+ * underlying output stream with the SVC's name and the mimetype
+ * "application/octet-stream".
+ *
+ * @param socket
+ * The socket along which the "pipe" instruction should be sent.
+ *
+ * @param svc
+ * The static virtual channel that the "pipe" instruction should describe.
+ */
+void guac_rdp_pipe_svc_send_pipe(guac_socket* socket, guac_rdp_pipe_svc* svc);
+
+/**
+ * Sends the "pipe" instructions describing all static virtual channels
+ * available to the given user along that user's socket. Each pipe instruction
+ * will relate the associated SVC's underlying output stream with the SVC's
+ * name and the mimetype "application/octet-stream".
+ *
+ * @param user
+ * The user to send the "pipe" instructions to.
+ */
+void guac_rdp_pipe_svc_send_pipes(guac_user* user);
+
+/**
+ * Add the given SVC to the list of all available SVCs. This function must be
+ * invoked after the SVC is connected for inbound pipe streams having that
+ * SVC's name to result in received data being sent into the RDP session.
+ *
+ * @param client
+ * The guac_client associated with the current RDP session.
+ *
+ * @param svc
+ * The static virtual channel to add to the list of all such channels
+ * available.
+ */
+void guac_rdp_pipe_svc_add(guac_client* client, guac_rdp_pipe_svc* svc);
+
+/**
+ * Retrieve the SVC with the given name from the list stored in the client. The
+ * requested SVC must previously have been added using guac_rdp_pipe_svc_add().
+ *
+ * @param client
+ * The guac_client associated with the current RDP session.
+ *
+ * @param name
+ * The name of the static virtual channel to retrieve.
+ *
+ * @return
+ * The static virtual channel with the given name, or NULL if no such
+ * virtual channel exists.
+ */
+gu
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r36108
##
File path: src/protocols/rdp/channels/pipe-svc.h
##
@@ -0,0 +1,188 @@
+/*
+ * 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 GUAC_RDP_CHANNELS_PIPE_SVC_H
+#define GUAC_RDP_CHANNELS_PIPE_SVC_H
+
+#include "channels/common-svc.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/**
+ * The maximum number of bytes to allow within each channel name, including
+ * null terminator.
+ */
+#define GUAC_RDP_SVC_MAX_LENGTH 8
+
+/**
+ * Structure describing a static virtual channel and a corresponding Guacamole
+ * pipe stream;
+ */
+typedef struct guac_rdp_pipe_svc {
+
+/**
+ * The output pipe, opened when the RDP server receives a connection to
+ * the static channel.
+ */
+guac_stream* output_pipe;
+
+/**
+ * The underlying static channel. Data written to this SVC by the RDP
+ * server will be forwarded along the pipe stream to the Guacamole client,
+ * and data written to the pipe stream by the Guacamole client will be
+ * forwarded along the SVC to the RDP server.
+ */
+guac_rdp_common_svc* svc;
+
+} guac_rdp_pipe_svc;
+
+/**
+ * Initializes arbitrary static virtual channel (SVC) support for RDP, handling
+ * communication for the SVC having the given name. Data sent from within the
+ * RDP session using this channel will be sent along an identically-named pipe
+ * stream to the Guacamole client, and data sent along a pipe stream having the
+ * same name will be written to the SVC and received within the RDP session. If
+ * failures occur while loading the plugin, messages noting the specifics of
+ * those failures will be logged, and support for the given channel will not be
+ * functional.
+ *
+ * This MUST be called within the PreConnect callback of the freerdp instance
+ * for static virtual channel support to be loaded.
+ *
+ * @param context
+ * The rdpContext associated with the FreeRDP side of the RDP connection.
+ *
+ * @param name
+ * The name of the SVC which should be handled.
+ */
+void guac_rdp_pipe_svc_load_plugin(rdpContext* context, char* name);
+
+/**
+ * Sends the "pipe" instruction describing the given static virtual channel
+ * along the given socket. This pipe instruction will relate the SVC's
+ * underlying output stream with the SVC's name and the mimetype
+ * "application/octet-stream".
+ *
+ * @param socket
+ * The socket along which the "pipe" instruction should be sent.
+ *
+ * @param svc
+ * The static virtual channel that the "pipe" instruction should describe.
+ */
+void guac_rdp_pipe_svc_send_pipe(guac_socket* socket, guac_rdp_pipe_svc* svc);
+
+/**
+ * Sends the "pipe" instructions describing all static virtual channels
+ * available to the given user along that user's socket. Each pipe instruction
+ * will relate the associated SVC's underlying output stream with the SVC's
+ * name and the mimetype "application/octet-stream".
+ *
+ * @param user
+ * The user to send the "pipe" instructions to.
+ */
+void guac_rdp_pipe_svc_send_pipes(guac_user* user);
+
+/**
+ * Add the given SVC to the list of all available SVCs. This function must be
+ * invoked after the SVC is connected for inbound pipe streams having that
+ * SVC's name to result in received data being sent into the RDP session.
+ *
+ * @param client
+ * The guac_client associated with the current RDP session.
+ *
+ * @param svc
+ * The static virtual channel to add to the list of all such channels
+ * available.
+ */
+void guac_rdp_pipe_svc_add(guac_client* client, guac_rdp_pipe_svc* svc);
+
+/**
+ * Retrieve the SVC with the given name from the list stored in the client. The
+ * requested SVC must previously have been added using guac_rdp_pipe_svc_add().
+ *
+ * @param client
+ * The guac_client associated with the current RDP session.
+ *
+ * @param name
+ * The name of the static virtual channel to retrieve.
+ *
+ * @return
+ * The static virtual channel with the given name, or NULL if no such
+ * virtual channel exists.
+ */
+gu
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x URL: https://github.com/apache/guacamole-server/pull/243#discussion_r36050 ## File path: src/protocols/rdp/channels/rdpdr/rdpdr-fs-messages-dir-info.h ## @@ -17,58 +17,76 @@ * under the License. */ - -#ifndef __GUAC_RDPDR_FS_MESSAGES_DIR_INFO_H -#define __GUAC_RDPDR_FS_MESSAGES_DIR_INFO_H +#ifndef GUAC_RDP_CHANNELS_RDPDR_FS_MESSAGES_DIR_INFO_H +#define GUAC_RDP_CHANNELS_RDPDR_FS_MESSAGES_DIR_INFO_H /** * Handlers for directory queries received over the RDPDR channel via the * IRP_MJ_DIRECTORY_CONTROL major function and the IRP_MN_QUERY_DIRECTORY minor * function. * - * @file rdpdr_fs_messages_dir_info.h + * @file rdpdr-fs-messages-dir-info.h */ -#include "config.h" - -#include "rdpdr_service.h" +#include "channels/common-svc.h" +#include "channels/rdpdr/rdpdr.h" -#ifdef ENABLE_WINPR #include -#else -#include "compat/winpr-stream.h" -#endif + +/** + * Handler for Device I/O Requests which query information about the files + * within a directory. + * + * @param svc + * The guac_rdp_common_svc representing the static virtual channel being + * used for RDPDR. + * + * @param device + * The guac_rdpdr_device of the relevant device, as dictated by the + * deviceId field of common RDPDR header within the received PDU. Within + * the guac_rdpdr_iorequest structure, the deviceId field is stored within + * device_id. + * + * @param iorequest + * The contents of the common RDPDR Device I/O Request header shared by all + * RDPDR devices. + * + * @param entry_name + * The filename of the file being queried. + * + * @param entry_file_id + * The ID of the file being queried. + */ +typedef void guac_rdpdr_directory_query_handler(guac_rdp_common_svc* svc, +guac_rdpdr_device* device, guac_rdpdr_iorequest* iorequest, +const char* entry_name, int entry_file_id); /** * Processes a query request for FileDirectoryInformation. From the * documentation this is "defined as the file's name, time stamp, and size, or its * attributes." */ -void guac_rdpdr_fs_process_query_directory_info(guac_rdpdr_device* device, -const char* entry_name, int file_id, int completion_id); +guac_rdpdr_directory_query_handler guac_rdpdr_fs_process_query_directory_info; /** * Processes a query request for FileFullDirectoryInformation. From the * documentation, this is "defined as all the basic information, plus extended * attribute size." */ -void guac_rdpdr_fs_process_query_full_directory_info(guac_rdpdr_device* device, -const char* entry_name, int file_id, int completion_id); +guac_rdpdr_directory_query_handler guac_rdpdr_fs_process_query_full_directory_info; /** * Processes a query request for FileBothDirectoryInformation. From the * documentation, this absurdly-named request is "basic information plus Review comment: Heh. :) This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: [email protected] With regards, Apache Git Services
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x URL: https://github.com/apache/guacamole-server/pull/243#discussion_r365554913 ## File path: src/protocols/rdp/channels/audio-input.h ## @@ -296,18 +292,13 @@ guac_user_end_handler guac_rdp_audio_end_handler; /** * Adds Guacamole's "guacai" plugin to the list of dynamic virtual channel * plugins to be loaded by FreeRDP's "drdynvc" plugin. The plugin will only - * be loaded once guac_rdp_load_drdynvc() is invoked with the guac_rdp_dvc_list - * passed to this function. The "guacai" plugin ultimately adds support for the - * "AUDIO_INPUT" dynamic virtual channel. + * be loaded once the "drdynvc" plugin is loaded. The "guacai" plugin + * ultimately adds support for the "AUDIO_INPUT" dynamic virtual channel. Review comment: This should be fixed, I think. @jmuehlner found a few of these, as well, and I fixed them in commit 2139d40 after doing a search of all files beneath `src/protocols/rdp/` for any other occurrences of extra spaces in comments. This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: [email protected] With regards, Apache Git Services
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r364986388
##
File path: src/protocols/rdp/plugins/channels.c
##
@@ -0,0 +1,129 @@
+/*
+ * 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 "plugins/channels.h"
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+int guac_rdp_wrapped_entry_ex_count = 0;
+
+int guac_rdp_wrapped_entry_count = 0;
+
+PVIRTUALCHANNELENTRYEX guac_rdp_wrapped_entry_ex[GUAC_RDP_MAX_CHANNELS] = {
NULL };
+
+PVIRTUALCHANNELENTRY guac_rdp_wrapped_entry[GUAC_RDP_MAX_CHANNELS] = { NULL };
+
+PVIRTUALCHANNELENTRYEX guac_rdp_plugin_wrap_entry_ex(PVIRTUALCHANNELENTRYEX
entry_ex) {
+
+/* Do not wrap if there is insufficient space to store the wrapped
+ * function */
+if (guac_rdp_wrapped_entry_ex_count == GUAC_RDP_MAX_CHANNELS)
+return entry_ex;
+
+/* Generate wrapped version of provided entry point */
+PVIRTUALCHANNELENTRYEX wrapper =
guac_rdp_entry_ex_wrappers[guac_rdp_wrapped_entry_ex_count];
+guac_rdp_wrapped_entry_ex[guac_rdp_wrapped_entry_ex_count] = entry_ex;
+guac_rdp_wrapped_entry_ex_count++;
+
+return wrapper;
+
+}
+
+PVIRTUALCHANNELENTRY guac_rdp_plugin_wrap_entry(PVIRTUALCHANNELENTRY entry) {
+
+/* Do not wrap if there is insufficient space to store the wrapped
+ * function */
+if (guac_rdp_wrapped_entry_count == GUAC_RDP_MAX_CHANNELS)
Review comment:
OK - I went ahead and refactored `guac_freerdp_channels_load_plugin()` such
that it accepts a `rdpContext` instead, allowing warnings to be logged if
plugins may fail to load due to limits being reached. It's no longer a true
drop-in replacement, but it really doesn't need to be.
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r364973223
##
File path: src/protocols/rdp/upload.c
##
@@ -0,0 +1,236 @@
+/*
+ * 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 "fs.h"
+#include "rdp.h"
+#include "upload.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+/**
+ * Writes the given filename to the given upload path, sanitizing the filename
+ * and translating the filename to the root directory.
+ *
+ * @param filename
+ * The filename to sanitize and move to the root directory.
+ *
+ * @param path
+ * A pointer to a buffer which should receive the sanitized path. The
+ * buffer must hav at least GUAC_RDP_FS_MAX_PATH bytes available.
+ */
+static void __generate_upload_path(const char* filename, char* path) {
+
+int i;
+
+/* Add initial backslash */
+*(path++) = '\\';
+
+for (i=1; iclient;
+guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
+
+int file_id;
+char file_path[GUAC_RDP_FS_MAX_PATH];
+
+/* Get filesystem, return error if no filesystem */
+guac_rdp_fs* fs = rdp_client->filesystem;
+if (fs == NULL) {
+guac_protocol_send_ack(user->socket, stream, "FAIL (NO FS)",
+GUAC_PROTOCOL_STATUS_SERVER_ERROR);
+guac_socket_flush(user->socket);
+return 0;
+}
+
+/* Translate name */
+__generate_upload_path(filename, file_path);
+
+/* Open file */
+file_id = guac_rdp_fs_open(fs, file_path, GENERIC_WRITE, 0,
+FILE_OVERWRITE_IF, 0);
+if (file_id < 0) {
+guac_protocol_send_ack(user->socket, stream, "FAIL (CANNOT OPEN)",
+GUAC_PROTOCOL_STATUS_CLIENT_FORBIDDEN);
+guac_socket_flush(user->socket);
+return 0;
+}
+
+/* Init upload status */
+guac_rdp_upload_status* upload_status =
malloc(sizeof(guac_rdp_upload_status));
+upload_status->offset = 0;
+upload_status->file_id = file_id;
+stream->data = upload_status;
+stream->blob_handler = guac_rdp_upload_blob_handler;
+stream->end_handler = guac_rdp_upload_end_handler;
+
+guac_protocol_send_ack(user->socket, stream, "OK (STREAM BEGIN)",
+GUAC_PROTOCOL_STATUS_SUCCESS);
+guac_socket_flush(user->socket);
+return 0;
+
+}
+
+int guac_rdp_upload_blob_handler(guac_user* user, guac_stream* stream,
+void* data, int length) {
+
+int bytes_written;
+guac_rdp_upload_status* upload_status = (guac_rdp_upload_status*)
stream->data;
+
+/* Get filesystem, return error if no filesystem 0*/
Review comment:
Fixed.
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x URL: https://github.com/apache/guacamole-server/pull/243#discussion_r364973163 ## File path: src/protocols/rdp/upload.c ## @@ -0,0 +1,236 @@ +/* + * 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 "fs.h" +#include "rdp.h" +#include "upload.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + * Writes the given filename to the given upload path, sanitizing the filename + * and translating the filename to the root directory. + * + * @param filename + * The filename to sanitize and move to the root directory. + * + * @param path + * A pointer to a buffer which should receive the sanitized path. The + * buffer must hav at least GUAC_RDP_FS_MAX_PATH bytes available. Review comment: Fixed. This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: [email protected] With regards, Apache Git Services
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x URL: https://github.com/apache/guacamole-server/pull/243#discussion_r364972808 ## File path: src/protocols/rdp/channels/audio-input.h ## @@ -296,18 +292,13 @@ guac_user_end_handler guac_rdp_audio_end_handler; /** * Adds Guacamole's "guacai" plugin to the list of dynamic virtual channel * plugins to be loaded by FreeRDP's "drdynvc" plugin. The plugin will only - * be loaded once guac_rdp_load_drdynvc() is invoked with the guac_rdp_dvc_list - * passed to this function. The "guacai" plugin ultimately adds support for the - * "AUDIO_INPUT" dynamic virtual channel. + * be loaded once the "drdynvc" plugin is loaded. The "guacai" plugin + * ultimately adds support for the "AUDIO_INPUT" dynamic virtual channel. Review comment: Should now be fixed. This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: [email protected] With regards, Apache Git Services
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r364972724
##
File path: src/protocols/rdp/channels/pipe-svc.h
##
@@ -0,0 +1,188 @@
+/*
+ * 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 GUAC_RDP_CHANNELS_PIPE_SVC_H
+#define GUAC_RDP_CHANNELS_PIPE_SVC_H
+
+#include "channels/common-svc.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/**
+ * The maximum number of bytes to allow within each channel name, including
+ * null terminator.
+ */
+#define GUAC_RDP_SVC_MAX_LENGTH 8
+
+/**
+ * Structure describing a static virtual channel and a corresponding Guacamole
+ * pipe stream;
+ */
+typedef struct guac_rdp_pipe_svc {
+
+/**
+ * The output pipe, opened when the RDP server receives a connection to
+ * the static channel.
+ */
+guac_stream* output_pipe;
+
+/**
+ * The underlying static channel. Data written to this SVC by the RDP
+ * server will be forwarded along the pipe stream to the Guacamole client,
+ * and data written to the pipe stream by the Guacamole client will be
+ * forwarded along the SVC to the RDP server.
+ */
+guac_rdp_common_svc* svc;
+
+} guac_rdp_pipe_svc;
+
+/**
+ * Initializes arbitrary static virtual channel (SVC) support for RDP, handling
+ * communication for the SVC having the given name. Data sent from within the
+ * RDP session using this channel will be sent along an identically-named pipe
+ * stream to the Guacamole client, and data sent along a pipe stream having the
+ * same name will be written to the SVC and received within the RDP session. If
+ * failures occur while loading the plugin, messages noting the specifics of
+ * those failures will be logged, and support for the given channel will not be
+ * functional.
+ *
+ * This MUST be called within the PreConnect callback of the freerdp instance
+ * for static virtual channel support to be loaded.
+ *
+ * @param context
+ * The rdpContext associated with the FreeRDP side of the RDP connection.
+ *
+ * @param name
+ * The name of the SVC which should be handled.
+ */
+void guac_rdp_pipe_svc_load_plugin(rdpContext* context, char* name);
+
+/**
+ * Sends the "pipe" instruction describing the given static virtual channel
+ * along the given socket. This pipe instruction will relate the SVC's
+ * underlying output stream with the SVC's name and the mimetype
+ * "application/octet-stream".
+ *
+ * @param socket
+ * The socket along which the "pipe" instruction should be sent.
+ *
+ * @param svc
+ * The static virtual channel that the "pipe" instruction should describe.
+ */
+void guac_rdp_pipe_svc_send_pipe(guac_socket* socket, guac_rdp_pipe_svc* svc);
+
+/**
+ * Sends the "pipe" instructions describing all static virtual channels
+ * available to the given user along that user's socket. Each pipe instruction
+ * will relate the associated SVC's underlying output stream with the SVC's
+ * name and the mimetype "application/octet-stream".
+ *
+ * @param user
+ * The user to send the "pipe" instructions to.
+ */
+void guac_rdp_pipe_svc_send_pipes(guac_user* user);
+
+/**
+ * Add the given SVC to the list of all available SVCs. This function must be
+ * invoked after the SVC is connected for inbound pipe streams having that
+ * SVC's name to result in received data being sent into the RDP session.
+ *
+ * @param client
+ * The guac_client associated with the current RDP session.
+ *
+ * @param svc
+ * The static virtual channel to add to the list of all such channels
+ * available.
+ */
+void guac_rdp_pipe_svc_add(guac_client* client, guac_rdp_pipe_svc* svc);
+
+/**
+ * Retrieve the SVC with the given name from the list stored in the client. The
+ * requested SVC must previously have been added using guac_rdp_pipe_svc_add().
+ *
+ * @param client
+ * The guac_client associated with the current RDP session.
+ *
+ * @param name
+ * The name of the static virtual channel to retrieve.
+ *
+ * @return
+ * The static virtual channel with the given name, or NULL if no such
+ * virtual channel exists.
+ */
+gu
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r364972380
##
File path: src/protocols/rdp/download.c
##
@@ -0,0 +1,240 @@
+/*
+ * 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 "common/json.h"
+#include "download.h"
+#include "fs.h"
+#include "ls.h"
+#include "rdp.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+int guac_rdp_download_ack_handler(guac_user* user, guac_stream* stream,
+char* message, guac_protocol_status status) {
+
+guac_client* client = user->client;
+guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
+guac_rdp_download_status* download_status = (guac_rdp_download_status*)
stream->data;
+
+/* Get filesystem, return error if no filesystem */
+guac_rdp_fs* fs = rdp_client->filesystem;
+if (fs == NULL) {
+guac_protocol_send_ack(user->socket, stream, "FAIL (NO FS)",
+GUAC_PROTOCOL_STATUS_SERVER_ERROR);
+guac_socket_flush(user->socket);
+return 0;
+}
+
+/* If successful, read data */
+if (status == GUAC_PROTOCOL_STATUS_SUCCESS) {
+
+/* Attempt read into buffer */
+char buffer[4096];
+int bytes_read = guac_rdp_fs_read(fs,
+download_status->file_id,
+download_status->offset, buffer, sizeof(buffer));
+
+/* If bytes read, send as blob */
+if (bytes_read > 0) {
+download_status->offset += bytes_read;
+guac_protocol_send_blob(user->socket, stream,
+buffer, bytes_read);
+}
+
+/* If EOF, send end */
+else if (bytes_read == 0) {
+guac_protocol_send_end(user->socket, stream);
+guac_user_free_stream(user, stream);
+free(download_status);
+}
+
+/* Otherwise, fail stream */
+else {
+guac_user_log(user, GUAC_LOG_ERROR,
+"Error reading file for download");
+guac_protocol_send_end(user->socket, stream);
+guac_user_free_stream(user, stream);
+free(download_status);
+}
+
+guac_socket_flush(user->socket);
+
+}
+
+/* Otherwise, return stream to user */
+else
+guac_user_free_stream(user, stream);
+
+return 0;
+
+}
+
+int guac_rdp_download_get_handler(guac_user* user, guac_object* object,
+char* name) {
+
+guac_client* client = user->client;
+guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
+
+/* Get filesystem, ignore request if no filesystem */
+guac_rdp_fs* fs = rdp_client->filesystem;
+if (fs == NULL)
+return 0;
+
+/* Attempt to open file for reading */
+int file_id = guac_rdp_fs_open(fs, name, GENERIC_READ, 0, FILE_OPEN, 0);
+if (file_id < 0) {
+guac_user_log(user, GUAC_LOG_INFO, "Unable to read file \"%s\"",
+name);
+return 0;
+}
+
+/* Get opened file */
+guac_rdp_fs_file* file = guac_rdp_fs_get_file(fs, file_id);
+if (file == NULL) {
+guac_client_log(fs->client, GUAC_LOG_DEBUG,
+"%s: Successful open produced bad file_id: %i",
+__func__, file_id);
+return 0;
+}
+
+/* If directory, send contents of directory */
+if (file->attributes & FILE_ATTRIBUTE_DIRECTORY) {
+
+/* Create stream data */
+guac_rdp_ls_status* ls_status = malloc(sizeof(guac_rdp_ls_status));
+ls_status->fs = fs;
+ls_status->file_id = file_id;
+guac_strlcpy(ls_status->directory_name, name,
+sizeof(ls_status->directory_name));
+
+/* Allocate stream for body */
+guac_stream* stream = guac_user_alloc_stream(user);
+stream->ack_handler = guac_rdp_ls_ack_handler;
+stream->data = ls_status;
+
+/* Init JSON object state */
+guac_common_json_begin_object(user, stream,
+&ls_status->json_state);
+
+/* Associate new stream with get request */
+guac_protocol_send_body(user->socket, obj
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r364972624
##
File path: src/protocols/rdp/channels/rdpdr/rdpdr.h
##
@@ -0,0 +1,250 @@
+/*
+ * 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 GUAC_RDP_CHANNELS_RDPDR_H
+#define GUAC_RDP_CHANNELS_RDPDR_H
+
+#include "channels/common-svc.h"
+
+#include
+#include
+#include
+
+#include
+
+/**
+ * The maximum number of bytes to allow for a device read.
+ */
+#define GUAC_RDP_MAX_READ_BUFFER 4194304
+
+/**
+ * Arbitrary device forwarded over the RDPDR channel.
+ */
+typedef struct guac_rdpdr_device guac_rdpdr_device;
+
+/**
+ * The contents of the header common to all RDPDR Device I/O Requests. See:
+ *
+ *
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpefs/a087ffa8-d0d5-4874-ac7b-0494f63e2d5d
+ */
+typedef struct guac_rdpdr_iorequest {
+
+/**
+ * The unique ID assigned to the device receiving this I/O request.
+ */
+int device_id;
+
+/**
+ * The unique ID which identifies the relevant file, as returned when the
+ * file was opened. This field may not be relevant to all requests.
+ */
+int file_id;
+
+/**
+ * The unique ID that should be used to refer to this I/O request in future
+ * responses.
+ */
+int completion_id;
+
+/**
+ * Integer ID which identifies the function being requested, such as
+ * IRP_MJ_CREATE (open a file within a shared drive) or IRP_MJ_WRITE (write
+ * data to an open file).
+ */
+int major_func;
+
+/**
+ * Integer ID which identifies a variant of the function denoted by
+ * major_func. This value is only valid for IRP_MJ_DIRECTORY_CONTROL.
+ */
+int minor_func;
+
+} guac_rdpdr_iorequest;
+
+/**
+ * Handler for Device I/O Requests. RDPDR devices must provide an
+ * implementation of this function to be able to handle inbound I/O requests.
+ *
+ * @param svc
+ * The guac_rdp_common_svc representing the static virtual channel being
+ * used for RDPDR.
+ *
+ * @param device
+ * The guac_rdpdr_device of the relevant device, as dictated by the
+ * deviceId field of common RDPDR header within the received PDU. Within
+ * the guac_rdpdr_iorequest structure, the deviceId field is stored within
+ * device_id.
+ *
+ * @param iorequest
+ * The contents of the common RDPDR Device I/O Request header shared by all
+ * RDPDR devices.
+ *
+ * @param input_stream
+ * The remaining data within the received PDU, following the common RDPDR
+ * Device I/O Request header.
+ */
+typedef void guac_rdpdr_device_iorequest_handler(guac_rdp_common_svc* svc,
+guac_rdpdr_device* device, guac_rdpdr_iorequest* iorequest,
+wStream* input_stream);
+
+/**
+ * Handler for cleaning up the dynamically-allocated portions of a device.
+ *
+ * @param svc
+ * The guac_rdp_common_svc representing the static virtual channel being
+ * used for RDPDR.
+ *
+ * @param device
+ * The guac_rdpdr_device of the device being freed.
+ */
+typedef void guac_rdpdr_device_free_handler(guac_rdp_common_svc* svc,
+guac_rdpdr_device* device);
+
+struct guac_rdpdr_device {
+
+/**
+ * The ID assigned to this device by the RDPDR plugin.
+ */
+int device_id;
+
+/**
+ * Device name, used for logging and for passthrough to the
+ * server.
+ */
+const char* device_name;
+
+/**
+ * The type of RDPDR device that this represents.
+ */
+uint32_t device_type;
+
+/**
+ * The DOS name of the device. Max 8 bytes, including terminator.
+ */
+const char *dos_name;
+
+/**
+ * The stream that stores the RDPDR device announcement for this device.
+ */
+wStream* device_announce;
+
+/**
+ * The length of the device_announce wStream.
+ */
+int device_announce_len;
+
+/**
+ * Handler which should be called for every I/O request received.
+ */
+guac_rdpdr_device_iorequest_handler* iorequest_handler;
+
+/**
+ * Handler which should be called when the device is being freed.
+ */
+guac_rdpd
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r364955658
##
File path: configure.ac
##
@@ -541,507 +540,17 @@ AC_ARG_WITH([rdp],
if test "x$with_rdp" != "xno"
then
-have_winpr=yes
-have_freerdp=yes
-legacy_freerdp_extensions=no
-rdpsettings_interface=unknown
-rdpsettings_audiocapture=yes
-rdpsettings_audioplayback=yes
-rdpsettings_deviceredirection=yes
-freerdp_interface=unknown
-event_interface=unknown
-
-# libfreerdp-core / libfreerdp
-AC_CHECK_LIB([freerdp-core], [freerdp_new],
- [RDP_LIBS="$RDP_LIBS -lfreerdp-core"],
- [AC_CHECK_LIB([freerdp], [freerdp_new],
- [RDP_LIBS="$RDP_LIBS -lfreerdp
-lfreerdp-client"],
- [AC_MSG_WARN([
+have_freerdp2=yes
+PKG_CHECK_MODULES([RDP], [freerdp2 freerdp-client2 winpr2],,
+ [AC_MSG_WARN([
- Unable to find libfreerdp-core / libfreerdp
+ Unable to find FreeRDP (libfreerdp2 / libfreerdp-client2 / libwinpr2)
RDP will be disabled.
])
- have_freerdp=no])])
+ have_freerdp2=no])
fi
-
-# libfreerdp-cache
-if test "x${have_freerdp}" = "xyes"
-then
-AC_CHECK_LIB([freerdp-cache], [glyph_cache_register_callbacks],
- [RDP_LIBS="$RDP_LIBS -lfreerdp-cache"])
-fi
-
-# libfreerdp-channels (1.0) / libfreerdp-client + libfreerdp-core (1.1)
-if test "x${have_freerdp}" = "xyes"
-then
-AC_CHECK_LIB([freerdp-client], [freerdp_channels_new],
- [RDP_LIBS="$RDP_LIBS -lfreerdp-client"],
- [AC_CHECK_LIB([freerdp-channels], [freerdp_channels_new],
- [RDP_LIBS="$RDP_LIBS -lfreerdp-channels"
- legacy_freerdp_extensions=yes])],
- [-lfreerdp-core])
-fi
-
-# libfreerdp-utils
-if test "x${have_freerdp}" = "xyes"
-then
-AC_CHECK_LIB([freerdp-utils], [svc_plugin_init],
- [RDP_LIBS="$RDP_LIBS -lfreerdp-utils"])
-fi
-
-# libfreerdp-codec
-if test "x${have_freerdp}" = "xyes"
-then
-AC_CHECK_LIB([freerdp-codec], [freerdp_image_convert],
- [RDP_LIBS="$RDP_LIBS -lfreerdp-codec"])
-fi
-
-# Available color conversion functions
-if test "x${have_freerdp}" = "xyes"
-then
-AC_CHECK_DECL([freerdp_convert_gdi_order_color],
-[AC_DEFINE([HAVE_FREERDP_CONVERT_GDI_ORDER_COLOR],,
- [Whether freerdp_convert_gdi_order_color() is defined])],,
-[#include ])
-
-AC_CHECK_DECL([freerdp_color_convert_drawing_order_color_to_gdi_color],
-
[AC_DEFINE([HAVE_FREERDP_COLOR_CONVERT_DRAWING_ORDER_COLOR_TO_GDI_COLOR],,
- [Whether
freerdp_color_convert_drawing_order_color_to_gdi_color() is defined])],,
-[#include ])
-fi
-
-# Check for interval polling in plugins
-if test "x${have_freerdp}" = "xyes"
-then
-AC_CHECK_MEMBERS([rdpSvcPlugin.interval_ms],,,
- [[#include ]])
-fi
-
-# Keyboard layout header
-if test "x${have_freerdp}" = "xyes"
-then
-AC_CHECK_HEADERS([freerdp/locale/keyboard.h],,
- [AC_CHECK_HEADERS([freerdp/kbd/layouts.h],,
- [AC_MSG_WARN([
-
- Unable to find keyboard layout headers
- RDP will be disabled.
- ])
-have_freerdp=no])])
-fi
-
-# New headers defining addins
-if test "x${have_freerdp}" = "xyes"
-then
-AC_CHECK_HEADERS([freerdp/addin.h freerdp/client/channels.h])
-fi
-
-# Header defining cliprdr
-if test "x${have_freerdp}" = "xyes"
-then
-AC_CHECK_HEADERS([freerdp/client/cliprdr.h],,
- [AC_CHECK_HEADERS([freerdp/plugins/cliprdr.h],,
- [AC_MSG_WARN([
-
- Unable to find cliprdr headers
- RDP will be disabled.
- ])
-have_freerdp=no],
- [#include ])],
- [#include
- #include ])
-fi
-
-# Header defining display update channel
-if test "x${have_freerdp}" = "xyes"
-then
-AC_CHECK_HEADERS([freerdp/client/disp.h],
- [AC_DEFINE([HAVE_FREERDP_DISPLAY_UPDATE_SUPPORT],,
-[Whether FreeRDP supports the display update
channel])]
- [AC_CHECK_MEMBERS([rdpSettings.SupportDisplayControl],,,
- [[#include ]])],,
- [#include
- #include ])
-fi
-
-# Support for RDP gateways
-if test "x${have_freerdp}" = "xy
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r364954598
##
File path: src/protocols/rdp/channels/rdpdr/rdpdr-messages.c
##
@@ -0,0 +1,349 @@
+/*
+ * 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 "channels/rdpdr/rdpdr-messages.h"
+#include "channels/rdpdr/rdpdr.h"
+#include "rdp.h"
+#include "settings.h"
+
+#include
+#include
+#include
+
+#include
+#include
+
+/**
+ * Sends a Client Announce Reply message. The Client Announce Reply message is
+ * required to be sent in response to the Server Announce Request message. See:
+ *
+ *
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpefs/d6fe6d1b-c145-4a6f-99aa-4fe3cdcea398
+ *
+ * @param svc
+ * The guac_rdp_common_svc representing the static virtual channel being
+ * used for RDPDR.
+ *
+ * @param major
+ * The major version of the RDPDR protocol in use. This value must always
+ * be 1.
+ *
+ * @param minor
+ * The minor version of the RDPDR protocol in use. This value must be
+ * either 2, 5, 10, 12, or 13.
+ *
+ * @param client_id
+ * The client ID received in the Server Announce Request, or a randomly
+ * generated ID.
+ */
+static void guac_rdpdr_send_client_announce_reply(guac_rdp_common_svc* svc,
+unsigned int major, unsigned int minor, unsigned int client_id) {
+
+wStream* output_stream = Stream_New(NULL, 12);
+
+/* Write header */
+Stream_Write_UINT16(output_stream, RDPDR_CTYP_CORE);
+Stream_Write_UINT16(output_stream, PAKID_CORE_CLIENTID_CONFIRM);
+
+/* Write content */
+Stream_Write_UINT16(output_stream, major);
+Stream_Write_UINT16(output_stream, minor);
+Stream_Write_UINT32(output_stream, client_id);
+
+guac_rdp_common_svc_write(svc, output_stream);
+
+}
+
+/**
+ * Sends a Client Name Request message. The Client Name Request message is used
+ * by the client to announce its own name. See:
+ *
+ *
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpefs/902497f1-3b1c-4aee-95f8-1668f9b7b7d2
+ *
+ * @param svc
+ * The guac_rdp_common_svc representing the static virtual channel being
+ * used for RDPDR.
+ *
+ * @param name
+ * The name that should be used for the client.
+ */
+static void guac_rdpdr_send_client_name_request(guac_rdp_common_svc* svc,
+const char* name) {
+
+int name_bytes = strlen(name) + 1;
+wStream* output_stream = Stream_New(NULL, 16 + name_bytes);
+
+/* Write header */
+Stream_Write_UINT16(output_stream, RDPDR_CTYP_CORE);
+Stream_Write_UINT16(output_stream, PAKID_CORE_CLIENT_NAME);
+
+/* Write content */
+Stream_Write_UINT32(output_stream, 0); /* ASCII */
+Stream_Write_UINT32(output_stream, 0); /* 0 required by RDPDR spec */
+Stream_Write_UINT32(output_stream, name_bytes);
+Stream_Write(output_stream, name, name_bytes);
+
+guac_rdp_common_svc_write(svc, output_stream);
+
+}
+
+/**
+ * Sends a Client Core Capability Response message. The Client Core Capability
+ * Response message is used to announce the client's capabilities, in response
+ * to receiving the server's capabilities via a Server Core Capability Request.
+ * See:
+ *
+ *
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpefs/f513bf87-cca0-488a-ac5c-18cf18f4a7e1
+ *
+ * @param svc
+ * The guac_rdp_common_svc representing the static virtual channel being
+ * used for RDPDR.
+ */
+static void guac_rdpdr_send_client_capability(guac_rdp_common_svc* svc) {
+
+wStream* output_stream = Stream_New(NULL, 256);
+guac_client_log(svc->client, GUAC_LOG_DEBUG, "Sending capabilities...");
+
+/* Write header */
+Stream_Write_UINT16(output_stream, RDPDR_CTYP_CORE);
+Stream_Write_UINT16(output_stream, PAKID_CORE_CLIENT_CAPABILITY);
+
+/* Capability count + padding */
+Stream_Write_UINT16(output_stream, 3);
+Stream_Write_UINT16(output_stream, 0); /* Padding */
+
+/* General capability header */
+Stream_Write_UINT16(output_stream, CAP_GENERAL_TYPE);
+Stream_Write_UINT16(output_stream, 44);
+Stream_Write_UINT32(output_stream, GENERAL_CA
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r364951731
##
File path: src/protocols/rdp/plugins/channels.c
##
@@ -0,0 +1,129 @@
+/*
+ * 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 "plugins/channels.h"
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+int guac_rdp_wrapped_entry_ex_count = 0;
+
+int guac_rdp_wrapped_entry_count = 0;
+
+PVIRTUALCHANNELENTRYEX guac_rdp_wrapped_entry_ex[GUAC_RDP_MAX_CHANNELS] = {
NULL };
+
+PVIRTUALCHANNELENTRY guac_rdp_wrapped_entry[GUAC_RDP_MAX_CHANNELS] = { NULL };
+
+PVIRTUALCHANNELENTRYEX guac_rdp_plugin_wrap_entry_ex(PVIRTUALCHANNELENTRYEX
entry_ex) {
+
+/* Do not wrap if there is insufficient space to store the wrapped
+ * function */
+if (guac_rdp_wrapped_entry_ex_count == GUAC_RDP_MAX_CHANNELS)
+return entry_ex;
+
+/* Generate wrapped version of provided entry point */
+PVIRTUALCHANNELENTRYEX wrapper =
guac_rdp_entry_ex_wrappers[guac_rdp_wrapped_entry_ex_count];
+guac_rdp_wrapped_entry_ex[guac_rdp_wrapped_entry_ex_count] = entry_ex;
+guac_rdp_wrapped_entry_ex_count++;
+
+return wrapper;
+
+}
+
+PVIRTUALCHANNELENTRY guac_rdp_plugin_wrap_entry(PVIRTUALCHANNELENTRY entry) {
+
+/* Do not wrap if there is insufficient space to store the wrapped
+ * function */
+if (guac_rdp_wrapped_entry_count == GUAC_RDP_MAX_CHANNELS)
Review comment:
> No warning or anything if wrapping fails?
To log a message using the normal logging subsystem exposed by libguac, we
would need access to the `guac_client`, however the `guac_client` is
unavailable at this level as the calling function
(`guac_freerdp_channels_load_plugin()`) was meant to be a drop-in replacement
for part of the FreeRDP API (`freerdp_channels_load_plugin()`) and none of the
parameters received by these functions have a path for reaching the
`guac_client`.
We could work around this by:
* *Not* having this function be a true drop-in replacement. There is
arguably little utility to having the function be a drop-in replacement now
that the code has been migrated. Passing different arguments (perhaps
`rdpContext`) would allow access to the associated `guac_client`.
* Using FreeRDP's logging subsystem (part of libwinpr). That subsystem is
rerouted early on in the connection process such that all messages logged from
FreeRDP actually get logged to the `guac_client` at the debug level.
> What are the consequences if this happens?
Generally, it shouldn't - there is an upper bound on the maximum number of
static channels that can be loaded. This upper bound is set by RDP itself and
by FreeRDP, and the `GUAC_RDP_MAX_CHANNELS` constant is set to a value that is
intended to be well above this limit. While we can't verify this at runtime,
there is a compile-time check that will fail the build if the constant is set
incorrectly:
https://github.com/apache/guacamole-server/blob/55959b54564cd7ce8800225ed8d3741345eb90a2/src/protocols/rdp/plugins/channels.h#L39-L42
The plugin would fail to load due to there not being a slot available to
hold the plugin.
Setting that aside, though, let's assume something strange is going on and
the plugin does successfully load after the limit is reached:
The first attempt to load a plugin X would succeed, as prior instances of X
had their entry points wrapped and FreeRDP sees this load attempt as unique.
After this point, further attempts to load copies of X would fail due to its
entry point already being present, and FreeRDP would refuse to load the plugin.
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r364951731
##
File path: src/protocols/rdp/plugins/channels.c
##
@@ -0,0 +1,129 @@
+/*
+ * 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 "plugins/channels.h"
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+int guac_rdp_wrapped_entry_ex_count = 0;
+
+int guac_rdp_wrapped_entry_count = 0;
+
+PVIRTUALCHANNELENTRYEX guac_rdp_wrapped_entry_ex[GUAC_RDP_MAX_CHANNELS] = {
NULL };
+
+PVIRTUALCHANNELENTRY guac_rdp_wrapped_entry[GUAC_RDP_MAX_CHANNELS] = { NULL };
+
+PVIRTUALCHANNELENTRYEX guac_rdp_plugin_wrap_entry_ex(PVIRTUALCHANNELENTRYEX
entry_ex) {
+
+/* Do not wrap if there is insufficient space to store the wrapped
+ * function */
+if (guac_rdp_wrapped_entry_ex_count == GUAC_RDP_MAX_CHANNELS)
+return entry_ex;
+
+/* Generate wrapped version of provided entry point */
+PVIRTUALCHANNELENTRYEX wrapper =
guac_rdp_entry_ex_wrappers[guac_rdp_wrapped_entry_ex_count];
+guac_rdp_wrapped_entry_ex[guac_rdp_wrapped_entry_ex_count] = entry_ex;
+guac_rdp_wrapped_entry_ex_count++;
+
+return wrapper;
+
+}
+
+PVIRTUALCHANNELENTRY guac_rdp_plugin_wrap_entry(PVIRTUALCHANNELENTRY entry) {
+
+/* Do not wrap if there is insufficient space to store the wrapped
+ * function */
+if (guac_rdp_wrapped_entry_count == GUAC_RDP_MAX_CHANNELS)
Review comment:
> No warning or anything if wrapping fails?
To log a message using the normal logging subsystem exposed by libguac, we
would need access to the `guac_client`, however the `guac_client` is
unavailable at this level as the calling function
(`guac_freerdp_channels_load_plugin()`) was meant to be a drop-in replacement
for part of the FreeRDP API (`freerdp_channels_load_plugin()`) and none of the
parameters received by these functions have a path for reaching the
`guac_client`.
We could work around this by:
* *Not* having this function be a true drop-in replacement. There is
arguably little utility to having the function be a drop-in replacement now
that the code has been migrated. Passing different arguments (perhaps
`rdpContext`) would allow access to the associated `guac_client`.
* Using FreeRDP's logging subsystem (part of libwinpr). That subsystem is
rerouted early on in the connection process such that all messages logged from
FreeRDP actually get logged to the `guac_client` at the debug level.
> What are the consequences if this happens?
Generally, it shouldn't - there is an upper bound on the maximum number of
static channels that can be loaded. This upper bound is set by RDP itself and
by FreeRDP. The `GUAC_RDP_MAX_CHANNELS` constant is set to the maximum number
of static channels that FreeRDP can load, and while we can't verify this at
runtime, there is a compile-time check that will fail the build if the constant
is set incorrectly:
https://github.com/apache/guacamole-server/blob/55959b54564cd7ce8800225ed8d3741345eb90a2/src/protocols/rdp/plugins/channels.h#L39-L42
The plugin would fail to load due to there not being a slot available to
hold the plugin.
Setting that aside, though, let's assume something strange is going on and
the plugin does successfully load after the limit is reached:
The first attempt to load a plugin X would succeed, as prior instances of X
had their entry points wrapped and FreeRDP sees this load attempt as unique.
After this point, further attempts to load copies of X would fail due to its
entry point already being present, and FreeRDP would refuse to load the plugin.
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r364365088
##
File path: src/protocols/rdp/upload.c
##
@@ -0,0 +1,236 @@
+/*
+ * 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 "fs.h"
+#include "rdp.h"
+#include "upload.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+/**
+ * Writes the given filename to the given upload path, sanitizing the filename
+ * and translating the filename to the root directory.
+ *
+ * @param filename
+ * The filename to sanitize and move to the root directory.
+ *
+ * @param path
+ * A pointer to a buffer which should receive the sanitized path. The
+ * buffer must hav at least GUAC_RDP_FS_MAX_PATH bytes available.
+ */
+static void __generate_upload_path(const char* filename, char* path) {
+
+int i;
+
+/* Add initial backslash */
+*(path++) = '\\';
+
+for (i=1; iclient;
+guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
+
+int file_id;
+char file_path[GUAC_RDP_FS_MAX_PATH];
+
+/* Get filesystem, return error if no filesystem */
+guac_rdp_fs* fs = rdp_client->filesystem;
+if (fs == NULL) {
+guac_protocol_send_ack(user->socket, stream, "FAIL (NO FS)",
+GUAC_PROTOCOL_STATUS_SERVER_ERROR);
+guac_socket_flush(user->socket);
+return 0;
+}
+
+/* Translate name */
+__generate_upload_path(filename, file_path);
+
+/* Open file */
+file_id = guac_rdp_fs_open(fs, file_path, GENERIC_WRITE, 0,
+FILE_OVERWRITE_IF, 0);
+if (file_id < 0) {
+guac_protocol_send_ack(user->socket, stream, "FAIL (CANNOT OPEN)",
+GUAC_PROTOCOL_STATUS_CLIENT_FORBIDDEN);
+guac_socket_flush(user->socket);
+return 0;
+}
+
+/* Init upload status */
+guac_rdp_upload_status* upload_status =
malloc(sizeof(guac_rdp_upload_status));
+upload_status->offset = 0;
+upload_status->file_id = file_id;
+stream->data = upload_status;
+stream->blob_handler = guac_rdp_upload_blob_handler;
+stream->end_handler = guac_rdp_upload_end_handler;
+
+guac_protocol_send_ack(user->socket, stream, "OK (STREAM BEGIN)",
+GUAC_PROTOCOL_STATUS_SUCCESS);
+guac_socket_flush(user->socket);
+return 0;
+
+}
+
+int guac_rdp_upload_blob_handler(guac_user* user, guac_stream* stream,
+void* data, int length) {
+
+int bytes_written;
+guac_rdp_upload_status* upload_status = (guac_rdp_upload_status*)
stream->data;
+
+/* Get filesystem, return error if no filesystem 0*/
Review comment:
Arg, it's a vim typo. I must have been moving the cursor to the beginning of
the line.
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r364364329
##
File path: src/protocols/rdp/download.c
##
@@ -0,0 +1,240 @@
+/*
+ * 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 "common/json.h"
+#include "download.h"
+#include "fs.h"
+#include "ls.h"
+#include "rdp.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+int guac_rdp_download_ack_handler(guac_user* user, guac_stream* stream,
+char* message, guac_protocol_status status) {
+
+guac_client* client = user->client;
+guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
+guac_rdp_download_status* download_status = (guac_rdp_download_status*)
stream->data;
+
+/* Get filesystem, return error if no filesystem */
+guac_rdp_fs* fs = rdp_client->filesystem;
+if (fs == NULL) {
+guac_protocol_send_ack(user->socket, stream, "FAIL (NO FS)",
+GUAC_PROTOCOL_STATUS_SERVER_ERROR);
+guac_socket_flush(user->socket);
+return 0;
+}
+
+/* If successful, read data */
+if (status == GUAC_PROTOCOL_STATUS_SUCCESS) {
+
+/* Attempt read into buffer */
+char buffer[4096];
+int bytes_read = guac_rdp_fs_read(fs,
+download_status->file_id,
+download_status->offset, buffer, sizeof(buffer));
+
+/* If bytes read, send as blob */
+if (bytes_read > 0) {
+download_status->offset += bytes_read;
+guac_protocol_send_blob(user->socket, stream,
+buffer, bytes_read);
+}
+
+/* If EOF, send end */
+else if (bytes_read == 0) {
+guac_protocol_send_end(user->socket, stream);
+guac_user_free_stream(user, stream);
+free(download_status);
+}
+
+/* Otherwise, fail stream */
+else {
+guac_user_log(user, GUAC_LOG_ERROR,
+"Error reading file for download");
+guac_protocol_send_end(user->socket, stream);
+guac_user_free_stream(user, stream);
+free(download_status);
+}
+
+guac_socket_flush(user->socket);
+
+}
+
+/* Otherwise, return stream to user */
+else
+guac_user_free_stream(user, stream);
+
+return 0;
+
+}
+
+int guac_rdp_download_get_handler(guac_user* user, guac_object* object,
+char* name) {
+
+guac_client* client = user->client;
+guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
+
+/* Get filesystem, ignore request if no filesystem */
+guac_rdp_fs* fs = rdp_client->filesystem;
+if (fs == NULL)
+return 0;
+
+/* Attempt to open file for reading */
+int file_id = guac_rdp_fs_open(fs, name, GENERIC_READ, 0, FILE_OPEN, 0);
+if (file_id < 0) {
+guac_user_log(user, GUAC_LOG_INFO, "Unable to read file \"%s\"",
+name);
+return 0;
+}
+
+/* Get opened file */
+guac_rdp_fs_file* file = guac_rdp_fs_get_file(fs, file_id);
+if (file == NULL) {
+guac_client_log(fs->client, GUAC_LOG_DEBUG,
+"%s: Successful open produced bad file_id: %i",
+__func__, file_id);
+return 0;
+}
+
+/* If directory, send contents of directory */
+if (file->attributes & FILE_ATTRIBUTE_DIRECTORY) {
+
+/* Create stream data */
+guac_rdp_ls_status* ls_status = malloc(sizeof(guac_rdp_ls_status));
+ls_status->fs = fs;
+ls_status->file_id = file_id;
+guac_strlcpy(ls_status->directory_name, name,
+sizeof(ls_status->directory_name));
+
+/* Allocate stream for body */
+guac_stream* stream = guac_user_alloc_stream(user);
+stream->ack_handler = guac_rdp_ls_ack_handler;
+stream->data = ls_status;
+
+/* Init JSON object state */
+guac_common_json_begin_object(user, stream,
+&ls_status->json_state);
+
+/* Associate new stream with get request */
+guac_protocol_send_body(user->socket, obj
[GitHub] [guacamole-server] mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate to FreeRDP 2.x
mike-jumper commented on a change in pull request #243: GUACAMOLE-249: Migrate
to FreeRDP 2.x
URL: https://github.com/apache/guacamole-server/pull/243#discussion_r364361909
##
File path: src/protocols/rdp/channels/rail.c
##
@@ -0,0 +1,197 @@
+/*
+ * 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 "channels/rail.h"
+#include "plugins/channels.h"
+#include "rdp.h"
+#include "settings.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+/**
+ * Completes initialization of the RemoteApp session, sending client system
+ * parameters and executing the desired RemoteApp command using the Client
+ * System Parameters Update PDU and Client Execute PDU respectively. These PDUs
+ * MUST be sent for the desired RemoteApp to run, and MUST NOT be sent until
+ * after a Handshake or HandshakeEx PDU has been received. See:
+ *
+ *
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdperp/60344497-883f-4711-8b9a-828d1c580195
(System Parameters Update PDU)
+ *
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdperp/98a6e3c3-c2a9-42cc-ad91-0d9a6c211138
(Client Execute PDU)
+ *
+ * @param rail
+ * The RailClientContext structure used by FreeRDP to handle the RAIL
+ * channel for the current RDP session.
+ *
+ * @return
+ * CHANNEL_RC_OK (zero) if the PDUs were sent successfully, an error code
+ * (non-zero) otherwise.
+ */
+static UINT guac_rdp_rail_complete_handshake(RailClientContext* rail) {
+
+guac_client* client = (guac_client*) rail->custom;
+guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
+
+RAIL_SYSPARAM_ORDER sysparam = {
+.workArea = {
+.left = 0,
+.top= 0,
+.right = rdp_client->settings->width,
+.bottom = rdp_client->settings->height
+},
+.dragFullWindows = FALSE
+};
+
+/* Send client system parameters */
+UINT status = rail->ClientSystemParam(rail, &sysparam);
+if (status != CHANNEL_RC_OK)
+return status;
+
+RAIL_EXEC_ORDER exec = {
+.RemoteApplicationProgram = rdp_client->settings->remote_app,
+.RemoteApplicationWorkingDir = rdp_client->settings->remote_app_dir,
+.RemoteApplicationArguments = rdp_client->settings->remote_app_args,
+};
+
+/* Execute desired RemoteApp command */
+return rail->ClientExecute(rail, &exec);
+
+}
+
+/**
+ * Callback which is invoked when a Handshake PDU is received from the RDP
+ * server. No communication for RemoteApp may occur until the Handshake PDU
+ * (or, alternatively, the HandshakeEx PDU) is received. See:
+ *
+ *
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdperp/cec4eb83-b304-43c9-8378-b5b8f5e7082a
+ *
+ * @param rail
+ * The RailClientContext structure used by FreeRDP to handle the RAIL
+ * channel for the current RDP session.
+ *
+ * @param handshake
Review comment:
Not currently, no. We ignore the contents of the handshake, simply using it
to signal when client system parameters should be sent and execution of the
RemoteApp should be requested.
This is actually in line with the behavior of xfreerdp, which also ignores
the contents of the handshake PDU received from the server:
https://github.com/FreeRDP/FreeRDP/blob/02614cce49ce6ff120a1306962c5d3ff6b05ea75/client/X11/xf_rail.c#L892-L901
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services
