Esempio n. 1
0
int guac_rdp_download_ack_handler(guac_client* client, guac_stream* stream,
        char* message, guac_protocol_status status) {

    guac_rdp_stream* rdp_stream = (guac_rdp_stream*) stream->data;

    /* Get filesystem, return error if no filesystem */
    guac_rdp_fs* fs = ((rdp_guac_client_data*) client->data)->filesystem;
    if (fs == NULL) {
        guac_protocol_send_ack(client->socket, stream, "FAIL (NO FS)",
                GUAC_PROTOCOL_STATUS_SERVER_ERROR);
        guac_socket_flush(client->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,
                rdp_stream->download_status.file_id,
                rdp_stream->download_status.offset, buffer, sizeof(buffer));

        /* If bytes read, send as blob */
        if (bytes_read > 0) {
            rdp_stream->download_status.offset += bytes_read;
            guac_protocol_send_blob(client->socket, stream,
                    buffer, bytes_read);
        }

        /* If EOF, send end */
        else if (bytes_read == 0) {
            guac_protocol_send_end(client->socket, stream);
            guac_client_free_stream(client, stream);
            free(rdp_stream);
        }

        /* Otherwise, fail stream */
        else {
            guac_client_log(client, GUAC_LOG_ERROR,
                    "Error reading file for download");
            guac_protocol_send_end(client->socket, stream);
            guac_client_free_stream(client, stream);
            free(rdp_stream);
        }

        guac_socket_flush(client->socket);

    }

    /* Otherwise, return stream to client */
    else
        guac_client_free_stream(client, stream);

    return 0;

}
Esempio n. 2
0
void guac_audio_stream_end(guac_audio_stream* audio) {

    double duration;

    /* Flush stream and finish encoding */
    guac_audio_stream_flush(audio);
    audio->encoder->end_handler(audio);

    /* Calculate duration of PCM data */
    duration = ((double) (audio->pcm_bytes_written * 1000 * 8))
                / audio->rate / audio->channels / audio->bps;

    /* Send audio */
    guac_protocol_send_audio(audio->client->socket, audio->stream,
            audio->stream->index, audio->encoder->mimetype, duration);

    guac_protocol_send_blob(audio->client->socket, audio->stream,
            audio->encoded_data, audio->encoded_data_used);

    guac_protocol_send_end(audio->client->socket, audio->stream);

    /* Clear data */
    audio->encoded_data_used = 0;

}
Esempio n. 3
0
void guac_rdpdr_process_print_job_close(guac_rdpdr_device* device,
        wStream* input_stream, int completion_id) {

    guac_rdpdr_printer_data* printer_data =
        (guac_rdpdr_printer_data*) device->data;

    wStream* output_stream = guac_rdpdr_new_io_completion(device,
            completion_id, STATUS_SUCCESS, 1);

    Stream_Write_UINT32(output_stream, 0); /* padding*/

    /* Close input and wait for output thread to finish */
    close(printer_data->printer_input);
    pthread_join(printer_data->printer_output_thread, NULL);

    /* Close file descriptors */
    close(printer_data->printer_output);

    /* Close file */
    guac_client_log(device->rdpdr->client, GUAC_LOG_INFO, "Print job closed");
    guac_protocol_send_end(device->rdpdr->client->socket, printer_data->stream);

    svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);

}
Esempio n. 4
0
int guac_sftp_ack_handler(guac_client* client, guac_stream* stream,
        char* message, guac_protocol_status status) {

    ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data;
    LIBSSH2_SFTP_HANDLE* file = (LIBSSH2_SFTP_HANDLE*) stream->data;

    /* If successful, read data */
    if (status == GUAC_PROTOCOL_STATUS_SUCCESS) {

        /* Attempt read into buffer */
        char buffer[4096];
        int bytes_read = libssh2_sftp_read(file, buffer, sizeof(buffer)); 

        /* If bytes read, send as blob */
        if (bytes_read > 0)
            guac_protocol_send_blob(client->socket, stream,
                    buffer, bytes_read);

        /* If EOF, send end */
        else if (bytes_read == 0) {
            guac_protocol_send_end(client->socket, stream);
            guac_client_free_stream(client, stream);
        }

        /* Otherwise, fail stream */
        else {
            guac_client_log_error(client, "Error reading file: %s",
                    libssh2_sftp_last_error(client_data->sftp_session));
            guac_protocol_send_end(client->socket, stream);
            guac_client_free_stream(client, stream);
        }

        guac_socket_flush(client->socket);

    }

    /* Otherwise, return stream to client */
    else
        guac_client_free_stream(client, stream);

    return 0;
}
/**
 * Callback for guac_client_foreach_user() which sends clipboard data to each
 * connected client.
 *
 * @param user
 *     The user to send the clipboard data to.
 *
 * @param
 *     A pointer to the guac_common_clipboard structure containing the
 *     clipboard data that should be sent to the given user.
 *
 * @return
 *     Always NULL.
 */
static void* __send_user_clipboard(guac_user* user, void* data) {

    guac_common_clipboard* clipboard = (guac_common_clipboard*) data;

    char* current = clipboard->buffer;
    int remaining = clipboard->length;

    /* Begin stream */
    guac_stream* stream = guac_user_alloc_stream(user);
    guac_protocol_send_clipboard(user->socket, stream, clipboard->mimetype);

    guac_user_log(user, GUAC_LOG_DEBUG,
            "Created stream %i for %s clipboard data.",
            stream->index, clipboard->mimetype);

    /* Split clipboard into chunks */
    while (remaining > 0) {

        /* Calculate size of next block */
        int block_size = GUAC_COMMON_CLIPBOARD_BLOCK_SIZE;
        if (remaining < block_size)
            block_size = remaining; 

        /* Send block */
        guac_protocol_send_blob(user->socket, stream, current, block_size);
        guac_user_log(user, GUAC_LOG_DEBUG,
                "Sent %i bytes of clipboard data on stream %i.",
                block_size, stream->index);

        /* Next block */
        remaining -= block_size;
        current += block_size;

    }

    guac_user_log(user, GUAC_LOG_DEBUG,
            "Clipboard stream %i complete.",
            stream->index);

    /* End stream */
    guac_protocol_send_end(user->socket, stream);
    guac_user_free_stream(user, stream);

    return NULL;

}
Esempio n. 6
0
void guac_client_stream_jpeg(guac_client* client, guac_socket* socket,
        guac_composite_mode mode, const guac_layer* layer, int x, int y,
        cairo_surface_t* surface, int quality) {

    /* Allocate new stream for image */
    guac_stream* stream = guac_client_alloc_stream(client);

    /* Declare stream as containing image data */
    guac_protocol_send_img(socket, stream, mode, layer, "image/jpeg", x, y);

    /* Write JPEG data */
    guac_jpeg_write(socket, stream, surface, quality);

    /* Terminate stream */
    guac_protocol_send_end(socket, stream);

    /* Free allocated stream */
    guac_client_free_stream(client, stream);

}
Esempio n. 7
0
void guac_client_stream_webp(guac_client* client, guac_socket* socket,
        guac_composite_mode mode, const guac_layer* layer, int x, int y,
        cairo_surface_t* surface, int quality, int lossless) {

#ifdef ENABLE_WEBP
    /* Allocate new stream for image */
    guac_stream* stream = guac_client_alloc_stream(client);

    /* Declare stream as containing image data */
    guac_protocol_send_img(socket, stream, mode, layer, "image/webp", x, y);

    /* Write WebP data */
    guac_webp_write(socket, stream, surface, quality, lossless);

    /* Terminate stream */
    guac_protocol_send_end(socket, stream);

    /* Free allocated stream */
    guac_client_free_stream(client, stream);
#else
    /* Do nothing if WebP support is not built in */
#endif

}
Esempio n. 8
0
int guac_rdp_ls_ack_handler(guac_client* client, guac_stream* stream,
        char* message, guac_protocol_status status) {

    int blob_written = 0;
    const char* filename;

    guac_rdp_stream* rdp_stream = (guac_rdp_stream*) stream->data;

    /* If unsuccessful, free stream and abort */
    if (status != GUAC_PROTOCOL_STATUS_SUCCESS) {
        guac_rdp_fs_close(rdp_stream->ls_status.fs,
                rdp_stream->ls_status.file_id);
        guac_client_free_stream(client, stream);
        free(rdp_stream);
        return 0;
    }

    /* While directory entries remain */
    while ((filename = guac_rdp_fs_read_dir(rdp_stream->ls_status.fs,
                    rdp_stream->ls_status.file_id)) != NULL
            && !blob_written) {

        char absolute_path[GUAC_RDP_FS_MAX_PATH];

        /* Skip current and parent directory entries */
        if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0)
            continue;

        /* Concatenate into absolute path - skip if invalid */
        if (!guac_rdp_fs_append_filename(absolute_path,
                    rdp_stream->ls_status.directory_name, filename)) {

            guac_client_log(client, GUAC_LOG_DEBUG,
                    "Skipping filename \"%s\" - filename is invalid or "
                    "resulting path is too long", filename);

            continue;
        }

        /* Attempt to open file to determine type */
        int file_id = guac_rdp_fs_open(rdp_stream->ls_status.fs, absolute_path,
                ACCESS_GENERIC_READ, 0, DISP_FILE_OPEN, 0);
        if (file_id < 0)
            continue;

        /* Get opened file */
        guac_rdp_fs_file* file = guac_rdp_fs_get_file(rdp_stream->ls_status.fs,
                file_id);
        if (file == NULL) {
            guac_client_log(rdp_stream->ls_status.fs->client, GUAC_LOG_DEBUG,
                    "%s: Successful open produced bad file_id: %i",
                    __func__, file_id);
            return 0;
        }

        /* Determine mimetype */
        const char* mimetype;
        if (file->attributes & FILE_ATTRIBUTE_DIRECTORY)
            mimetype = GUAC_CLIENT_STREAM_INDEX_MIMETYPE;
        else
            mimetype = "application/octet-stream";

        /* Write entry */
        blob_written |= guac_common_json_write_property(client, stream,
                &rdp_stream->ls_status.json_state, absolute_path, mimetype);

        guac_rdp_fs_close(rdp_stream->ls_status.fs, file_id);

    }

    /* Complete JSON and cleanup at end of directory */
    if (filename == NULL) {

        /* Complete JSON object */
        guac_common_json_end_object(client, stream,
                &rdp_stream->ls_status.json_state);
        guac_common_json_flush(client, stream,
                &rdp_stream->ls_status.json_state);

        /* Clean up resources */
        guac_rdp_fs_close(rdp_stream->ls_status.fs,
                rdp_stream->ls_status.file_id);
        free(rdp_stream);

        /* Signal of stream */
        guac_protocol_send_end(client->socket, stream);
        guac_client_free_stream(client, stream);

    }

    guac_socket_flush(client->socket);
    return 0;

}