cscg24-guacamole

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

rdpdr.h (7285B)


      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#ifndef GUAC_RDP_CHANNELS_RDPDR_H
     21#define GUAC_RDP_CHANNELS_RDPDR_H
     22
     23#include "channels/common-svc.h"
     24
     25#include <freerdp/freerdp.h>
     26#include <guacamole/client.h>
     27#include <winpr/stream.h>
     28
     29#include <stdint.h>
     30
     31/**
     32 * The maximum number of bytes to allow for a device read.
     33 */
     34#define GUAC_RDP_MAX_READ_BUFFER 4194304
     35
     36/**
     37 * Arbitrary device forwarded over the RDPDR channel.
     38 */
     39typedef struct guac_rdpdr_device guac_rdpdr_device;
     40
     41/**
     42 * The contents of the header common to all RDPDR Device I/O Requests. See:
     43 *
     44 * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpefs/a087ffa8-d0d5-4874-ac7b-0494f63e2d5d
     45 */
     46typedef struct guac_rdpdr_iorequest {
     47
     48    /**
     49     * The unique ID assigned to the device receiving this I/O request.
     50     */
     51    int device_id;
     52
     53    /**
     54     * The unique ID which identifies the relevant file, as returned when the
     55     * file was opened. This field may not be relevant to all requests.
     56     */
     57    int file_id;
     58
     59    /**
     60     * The unique ID that should be used to refer to this I/O request in future
     61     * responses.
     62     */
     63    int completion_id;
     64
     65    /**
     66     * Integer ID which identifies the function being requested, such as
     67     * IRP_MJ_CREATE (open a file within a shared drive) or IRP_MJ_WRITE (write
     68     * data to an open file).
     69     */
     70    int major_func;
     71
     72    /**
     73     * Integer ID which identifies a variant of the function denoted by
     74     * major_func. This value is only valid for IRP_MJ_DIRECTORY_CONTROL.
     75     */
     76    int minor_func;
     77
     78} guac_rdpdr_iorequest;
     79
     80/**
     81 * Handler for Device I/O Requests. RDPDR devices must provide an
     82 * implementation of this function to be able to handle inbound I/O requests.
     83 *
     84 * @param svc
     85 *     The guac_rdp_common_svc representing the static virtual channel being
     86 *     used for RDPDR.
     87 *
     88 * @param device
     89 *     The guac_rdpdr_device of the relevant device, as dictated by the
     90 *     deviceId field of the common RDPDR header within the received PDU.
     91 *     Within the guac_rdpdr_iorequest structure, the deviceId field is stored
     92 *     within device_id.
     93 *
     94 * @param iorequest
     95 *     The contents of the common RDPDR Device I/O Request header shared by all
     96 *     RDPDR devices.
     97 *
     98 * @param input_stream
     99 *     The remaining data within the received PDU, following the common RDPDR
    100 *     Device I/O Request header.
    101 */
    102typedef void guac_rdpdr_device_iorequest_handler(guac_rdp_common_svc* svc,
    103        guac_rdpdr_device* device, guac_rdpdr_iorequest* iorequest,
    104        wStream* input_stream);
    105
    106/**
    107 * Handler for cleaning up the dynamically-allocated portions of a device.
    108 *
    109 * @param svc
    110 *     The guac_rdp_common_svc representing the static virtual channel being
    111 *     used for RDPDR.
    112 *
    113 * @param device
    114 *     The guac_rdpdr_device of the device being freed.
    115 */
    116typedef void guac_rdpdr_device_free_handler(guac_rdp_common_svc* svc,
    117        guac_rdpdr_device* device);
    118
    119struct guac_rdpdr_device {
    120
    121    /**
    122     * The ID assigned to this device by the RDPDR plugin.
    123     */
    124    int device_id;
    125
    126    /**
    127     * Device name, used for logging and for passthrough to the
    128     * server.
    129     */
    130    const char* device_name;
    131
    132    /**
    133     * The type of RDPDR device that this represents.
    134     */
    135    uint32_t device_type;
    136
    137    /**
    138     * The DOS name of the device. Max 8 bytes, including terminator.
    139     */
    140    const char *dos_name;
    141    
    142    /**
    143     * The stream that stores the RDPDR device announcement for this device.
    144     */
    145    wStream* device_announce;
    146    
    147    /**
    148     * The length of the device_announce wStream.
    149     */
    150    int device_announce_len;
    151
    152    /**
    153     * Handler which should be called for every I/O request received.
    154     */
    155    guac_rdpdr_device_iorequest_handler* iorequest_handler;
    156
    157    /**
    158     * Handler which should be called when the device is being freed.
    159     */
    160    guac_rdpdr_device_free_handler* free_handler;
    161
    162    /**
    163     * Arbitrary data, used internally by the handlers for this device.
    164     */
    165    void* data;
    166
    167};
    168
    169/**
    170 * Structure representing the current state of the Guacamole RDPDR plugin for
    171 * FreeRDP.
    172 */
    173typedef struct guac_rdpdr {
    174
    175    /**
    176     * The number of devices registered within the devices array.
    177     */
    178    int devices_registered;
    179
    180    /**
    181     * Array of registered devices.
    182     */
    183    guac_rdpdr_device devices[8];
    184
    185} guac_rdpdr;
    186
    187/**
    188 * Creates a new stream which contains the common DR_DEVICE_IOCOMPLETION header
    189 * used for virtually all responses. Depending on the specific I/O completion
    190 * being sent, additional space may be reserved within the resulting stream for
    191 * additional fields. See:
    192 *
    193 * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpefs/10ef9ada-cba2-4384-ab60-7b6290ed4a9a
    194 *
    195 * @param device
    196 *     The device that completed the operation requested by a prior I/O
    197 *     request.
    198 *
    199 * @param completion_id
    200 *     The completion ID of the I/O request that requested the operation.
    201 *
    202 * @param status
    203 *     An NTSTATUS code describing the success/failure of the operation that
    204 *     was completed.
    205 *
    206 * @param size
    207 *     The number of additional bytes to reserve at the end of the resulting
    208 *     stream for additional fields to be appended.
    209 *
    210 * @return
    211 *     A new wStream containing an I/O completion header, followed by the
    212 *     requested additional free space.
    213 */
    214wStream* guac_rdpdr_new_io_completion(guac_rdpdr_device* device,
    215        int completion_id, int status, int size);
    216
    217/**
    218 * Initializes device redirection support (file transfer, printing, etc.) for
    219 * RDP and handling of the RDPDR channel. If failures occur, messages noting
    220 * the specifics of those failures will be logged, and the RDP side of
    221 * device redirection support will not be functional.
    222 *
    223 * This MUST be called within the PreConnect callback of the freerdp instance
    224 * for RDPDR support to be loaded.
    225 *
    226 * @param context
    227 *     The rdpContext associated with the FreeRDP side of the RDP connection.
    228 */
    229void guac_rdpdr_load_plugin(rdpContext* context);
    230
    231/**
    232 * Handler which is invoked when the RDPDR channel is connected to the RDP
    233 * server.
    234 */
    235guac_rdp_common_svc_connect_handler guac_rdpdr_process_connect;
    236
    237/**
    238 * Handler which is invoked when the RDPDR channel has received data from the
    239 * RDP server.
    240 */
    241guac_rdp_common_svc_receive_handler guac_rdpdr_process_receive;
    242
    243/**
    244 * Handler which is invoked when the RDPDR channel has disconnected and is
    245 * about to be freed.
    246 */
    247guac_rdp_common_svc_terminate_handler guac_rdpdr_process_terminate;
    248
    249#endif
    250