cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

common-svc.c (4045B)


      1/*
      2 * Licensed to the Apache Software Foundation (ASF) under one
      3 * or more contributor license agreements.  See the NOTICE file
      4 * distributed with this work for additional information
      5 * regarding copyright ownership.  The ASF licenses this file
      6 * to you under the Apache License, Version 2.0 (the
      7 * "License"); you may not use this file except in compliance
      8 * with the License.  You may obtain a copy of the License at
      9 *
     10 *   http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing,
     13 * software distributed under the License is distributed on an
     14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     15 * KIND, either express or implied.  See the License for the
     16 * specific language governing permissions and limitations
     17 * under the License.
     18 */
     19
     20#include "channels/common-svc.h"
     21#include "plugins/channels.h"
     22#include "rdp.h"
     23
     24#include <freerdp/settings.h>
     25#include <guacamole/client.h>
     26#include <guacamole/mem.h>
     27#include <guacamole/string.h>
     28#include <winpr/stream.h>
     29#include <winpr/wtsapi.h>
     30#include <winpr/wtypes.h>
     31
     32#include <stdlib.h>
     33
     34int guac_rdp_common_svc_load_plugin(rdpContext* context,
     35        char* name, ULONG channel_options,
     36        guac_rdp_common_svc_connect_handler* connect_handler,
     37        guac_rdp_common_svc_receive_handler* receive_handler,
     38        guac_rdp_common_svc_terminate_handler* terminate_handler) {
     39
     40    guac_client* client = ((rdp_freerdp_context*) context)->client;
     41
     42    guac_rdp_common_svc* svc = guac_mem_zalloc(sizeof(guac_rdp_common_svc));
     43    svc->client = client;
     44    svc->name = svc->_channel_def.name;
     45    svc->_connect_handler = connect_handler;
     46    svc->_receive_handler = receive_handler;
     47    svc->_terminate_handler = terminate_handler;
     48
     49    /* Init FreeRDP channel definition */
     50    int name_length = guac_strlcpy(svc->_channel_def.name, name, GUAC_RDP_SVC_MAX_LENGTH);
     51    svc->_channel_def.options =
     52          CHANNEL_OPTION_INITIALIZED
     53        | CHANNEL_OPTION_ENCRYPT_RDP
     54        | channel_options;
     55
     56    /* Warn about name length */
     57    if (name_length >= GUAC_RDP_SVC_MAX_LENGTH)
     58        guac_client_log(client, GUAC_LOG_WARNING,
     59                "Static channel name \"%s\" exceeds maximum length of %i "
     60                "characters and will be truncated to \"%s\".",
     61                name, GUAC_RDP_SVC_MAX_LENGTH - 1, svc->name);
     62
     63    /* Attempt to load the common SVC plugin for new static channel */
     64    int result = guac_freerdp_channels_load_plugin(context, "guac-common-svc", svc);
     65    if (result) {
     66        guac_client_log(client, GUAC_LOG_WARNING, "Cannot create static "
     67                "channel \"%s\": failed to load \"guac-common-svc\" plugin "
     68                "for FreeRDP.", svc->name);
     69        guac_mem_free(svc);
     70    }
     71
     72    /* Store and log on success (SVC structure will be freed on channel termination) */
     73    else
     74        guac_client_log(client, GUAC_LOG_DEBUG, "Support for static channel "
     75                "\"%s\" loaded.", svc->name);
     76
     77    return result;
     78
     79}
     80
     81void guac_rdp_common_svc_write(guac_rdp_common_svc* svc,
     82        wStream* output_stream) {
     83
     84    /* Do not write if plugin not associated */
     85    if (!svc->_open_handle) {
     86        guac_client_log(svc->client, GUAC_LOG_WARNING, "%i bytes of data "
     87                "written to SVC \"%s\" are being dropped because the remote "
     88                "desktop side of that SVC is not yet connected.",
     89                Stream_Length(output_stream), svc->name);
     90        return;
     91    }
     92
     93    guac_rdp_client* rdp_client = (guac_rdp_client*) svc->client->data;
     94
     95    /* NOTE: The wStream sent via pVirtualChannelWriteEx will automatically be
     96     * freed later with a call to Stream_Free() when handling the
     97     * corresponding write cancel/completion event. */
     98    pthread_mutex_lock(&(rdp_client->message_lock));
     99    svc->_entry_points.pVirtualChannelWriteEx(svc->_init_handle,
    100            svc->_open_handle, Stream_Buffer(output_stream),
    101            Stream_GetPosition(output_stream), output_stream);
    102    pthread_mutex_unlock(&(rdp_client->message_lock));
    103
    104}
    105