Exemplo n.º 1
0
int guac_rdp_upload_end_handler(guac_client* client, guac_stream* stream) {

    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;
    }

    /* Close file */
    guac_rdp_fs_close(fs, rdp_stream->upload_status.file_id);

    /* Acknowledge stream end */
    guac_protocol_send_ack(client->socket, stream, "OK (STREAM END)",
            GUAC_PROTOCOL_STATUS_SUCCESS);
    guac_socket_flush(client->socket);

    free(rdp_stream);
    return 0;

}
Exemplo n.º 2
0
int guac_sftp_blob_handler(guac_client* client, guac_stream* stream,
        void* data, int length) {

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

    /* Attempt write */
    if (libssh2_sftp_write(file, data, length) == length) {
        guac_protocol_send_ack(client->socket, stream, "SFTP: OK",
                GUAC_PROTOCOL_STATUS_SUCCESS);
        guac_socket_flush(client->socket);
    }

    /* Inform of any errors */
    else {
        guac_client_log_error(client, "Unable to write to file: %s",
                libssh2_sftp_last_error(client_data->sftp_session));
        guac_protocol_send_ack(client->socket, stream, "SFTP: Write failed",
                GUAC_PROTOCOL_STATUS_INTERNAL_ERROR);
        guac_socket_flush(client->socket);
    }

    return 0;

}
Exemplo n.º 3
0
int guac_rdp_svc_pipe_handler(guac_client* client, guac_stream* stream,
        char* mimetype, char* name) {

    guac_rdp_stream* rdp_stream;
    guac_rdp_svc* svc = guac_rdp_get_svc(client, name);

    /* Fail if no such SVC */
    if (svc == NULL) {
        guac_client_log(client, GUAC_LOG_ERROR,
                "Requested non-existent pipe: \"%s\".",
                name);
        guac_protocol_send_ack(client->socket, stream, "FAIL (NO SUCH PIPE)",
                GUAC_PROTOCOL_STATUS_CLIENT_BAD_REQUEST);
        guac_socket_flush(client->socket);
        return 0;
    }
    else
        guac_client_log(client, GUAC_LOG_ERROR,
                "Inbound half of channel \"%s\" connected.",
                name);

    /* Init stream data */
    stream->data = rdp_stream = malloc(sizeof(guac_rdp_stream));
    stream->blob_handler = guac_rdp_svc_blob_handler;
    rdp_stream->type = GUAC_RDP_INBOUND_SVC_STREAM;
    rdp_stream->svc = svc;
    svc->input_pipe = stream;

    return 0;

}
Exemplo n.º 4
0
int guac_rdp_user_file_handler(guac_user* user, guac_stream* stream,
        char* mimetype, char* filename) {

    guac_rdp_client* rdp_client = (guac_rdp_client*) user->client->data;

#ifdef ENABLE_COMMON_SSH
    guac_rdp_settings* settings = rdp_client->settings;

    /* If SFTP is enabled, it should be used for default uploads only if RDPDR
     * is not enabled or its upload directory has been set */
    if (rdp_client->sftp_filesystem != NULL) {
        if (!settings->drive_enabled || settings->sftp_directory != NULL)
            return guac_rdp_sftp_file_handler(user, stream, mimetype, filename);
    }
#endif

    /* Default to using RDPDR uploads (if enabled) */
    if (rdp_client->filesystem != NULL)
        return guac_rdp_upload_file_handler(user, stream, mimetype, filename);

    /* File transfer not enabled */
    guac_protocol_send_ack(user->socket, stream, "File transfer disabled",
            GUAC_PROTOCOL_STATUS_UNSUPPORTED);
    guac_socket_flush(user->socket);

    return 0;
}
Exemplo n.º 5
0
int guac_rdp_upload_blob_handler(guac_client* client, guac_stream* stream,
        void* data, int length) {

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

    /* Get filesystem, return error if no filesystem 0*/
    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;
    }

    /* Write entire block */
    while (length > 0) {

        /* Attempt write */
        bytes_written = guac_rdp_fs_write(fs,
                rdp_stream->upload_status.file_id,
                rdp_stream->upload_status.offset,
                data, length);

        /* On error, abort */
        if (bytes_written < 0) {
            guac_protocol_send_ack(client->socket, stream,
                    "FAIL (BAD WRITE)",
                    GUAC_PROTOCOL_STATUS_CLIENT_FORBIDDEN);
            guac_socket_flush(client->socket);
            return 0;
        }

        /* Update counters */
        rdp_stream->upload_status.offset += bytes_written;
        data += bytes_written;
        length -= bytes_written;

    }

    guac_protocol_send_ack(client->socket, stream, "OK (DATA RECEIVED)",
            GUAC_PROTOCOL_STATUS_SUCCESS);
    guac_socket_flush(client->socket);
    return 0;

}
Exemplo n.º 6
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;

}
Exemplo n.º 7
0
int guac_rdp_upload_file_handler(guac_client* client, guac_stream* stream,
        char* mimetype, char* filename) {

    int file_id;
    guac_rdp_stream* rdp_stream;
    char file_path[GUAC_RDP_FS_MAX_PATH];

    /* 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;
    }

    /* Translate name */
    __generate_upload_path(filename, file_path);

    /* Open file */
    file_id = guac_rdp_fs_open(fs, file_path, ACCESS_GENERIC_WRITE, 0,
            DISP_FILE_OVERWRITE_IF, 0);
    if (file_id < 0) {
        guac_protocol_send_ack(client->socket, stream, "FAIL (CANNOT OPEN)",
                GUAC_PROTOCOL_STATUS_CLIENT_FORBIDDEN);
        guac_socket_flush(client->socket);
        return 0;
    }

    /* Init upload status */
    rdp_stream = malloc(sizeof(guac_rdp_stream));
    rdp_stream->type = GUAC_RDP_UPLOAD_STREAM;
    rdp_stream->upload_status.offset = 0;
    rdp_stream->upload_status.file_id = file_id;
    stream->data = rdp_stream;
    stream->blob_handler = guac_rdp_upload_blob_handler;
    stream->end_handler = guac_rdp_upload_end_handler;

    guac_protocol_send_ack(client->socket, stream, "OK (STREAM BEGIN)",
            GUAC_PROTOCOL_STATUS_SUCCESS);
    guac_socket_flush(client->socket);
    return 0;

}
Exemplo n.º 8
0
int guac_sftp_end_handler(guac_client* client, guac_stream* stream) {

    /* Pull file from stream */
    LIBSSH2_SFTP_HANDLE* file = (LIBSSH2_SFTP_HANDLE*) stream->data;

    /* Attempt to close file */
    if (libssh2_sftp_close(file) == 0) {
        guac_protocol_send_ack(client->socket, stream, "SFTP: OK", GUAC_PROTOCOL_STATUS_SUCCESS);
        guac_socket_flush(client->socket);
    }
    else {
        guac_client_log_error(client, "Unable to close file");
        guac_protocol_send_ack(client->socket, stream, "SFTP: Close failed", GUAC_PROTOCOL_STATUS_SERVER_ERROR);
        guac_socket_flush(client->socket);
    }

    return 0;

}
Exemplo n.º 9
0
int guac_rdp_upload_put_handler(guac_client* client, guac_object* object,
        guac_stream* stream, char* mimetype, char* name) {

    /* 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;
    }

    /* Open file */
    int file_id = guac_rdp_fs_open(fs, name, ACCESS_GENERIC_WRITE, 0,
            DISP_FILE_OVERWRITE_IF, 0);

    /* Abort on failure */
    if (file_id < 0) {
        guac_protocol_send_ack(client->socket, stream, "FAIL (CANNOT OPEN)",
                GUAC_PROTOCOL_STATUS_CLIENT_FORBIDDEN);
        guac_socket_flush(client->socket);
        return 0;
    }

    /* Init upload stream data */
    guac_rdp_stream* rdp_stream = malloc(sizeof(guac_rdp_stream));
    rdp_stream->type = GUAC_RDP_UPLOAD_STREAM;
    rdp_stream->upload_status.offset = 0;
    rdp_stream->upload_status.file_id = file_id;

    /* Allocate stream, init for file upload */
    stream->data = rdp_stream;
    stream->blob_handler = guac_rdp_upload_blob_handler;
    stream->end_handler = guac_rdp_upload_end_handler;

    /* Acknowledge stream creation */
    guac_protocol_send_ack(client->socket, stream, "OK (STREAM BEGIN)",
            GUAC_PROTOCOL_STATUS_SUCCESS);
    guac_socket_flush(client->socket);
    return 0;
}
Exemplo n.º 10
0
int guac_rdp_svc_blob_handler(guac_client* client, guac_stream* stream,
        void* data, int length) {

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

    /* Write blob data to SVC directly */
    guac_rdp_svc_write(rdp_stream->svc, data, length);

    guac_protocol_send_ack(client->socket, stream, "OK (DATA RECEIVED)",
            GUAC_PROTOCOL_STATUS_SUCCESS);
    guac_socket_flush(client->socket);
    return 0;

}
Exemplo n.º 11
0
int guac_sftp_file_handler(guac_client* client, guac_stream* stream,
        char* mimetype, char* filename) {

    ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data;
    char fullpath[GUAC_SFTP_MAX_PATH];
    LIBSSH2_SFTP_HANDLE* file;
    int i;

    /* Ensure filename is a valid filename and not a path */
    if (!__ssh_guac_valid_filename(filename)) {
        guac_protocol_send_ack(client->socket, stream, "SFTP: Illegal filename",
                GUAC_PROTOCOL_STATUS_CLIENT_BAD_REQUEST);
        guac_socket_flush(client->socket);
        return 0;
    }

    /* Copy upload path, append trailing slash */
    for (i=0; i<GUAC_SFTP_MAX_PATH; i++) {
        char c = client_data->sftp_upload_path[i];
        if (c == '\0') {
            fullpath[i++] = '/';
            break;
        }

        fullpath[i] = c;
    }

    /* Append filename */
    for (; i<GUAC_SFTP_MAX_PATH; i++) {
        char c = *(filename++);
        if (c == '\0')
            break;

        fullpath[i] = c;
    }

    /* If path + filename exceeds max length, abort */
    if (i == GUAC_SFTP_MAX_PATH) {
        guac_protocol_send_ack(client->socket, stream, "SFTP: Name too long", GUAC_PROTOCOL_STATUS_CLIENT_OVERRUN);
        guac_socket_flush(client->socket);
        return 0;
    }

    /* Terminate path string */
    fullpath[i] = '\0';

    /* Open file via SFTP */
    file = libssh2_sftp_open(client_data->sftp_session, fullpath,
            LIBSSH2_FXF_WRITE | LIBSSH2_FXF_CREAT | LIBSSH2_FXF_TRUNC,
            S_IRUSR | S_IWUSR);

    /* Inform of status */
    if (file != NULL) {
        guac_protocol_send_ack(client->socket, stream, "SFTP: File opened", GUAC_PROTOCOL_STATUS_SUCCESS);
        guac_socket_flush(client->socket);
    }
    else {
        guac_client_log_error(client, "Unable to open file \"%s\": %s",
                fullpath, libssh2_sftp_last_error(client_data->sftp_session));
        guac_protocol_send_ack(client->socket, stream, "SFTP: Open failed", GUAC_PROTOCOL_STATUS_RESOURCE_NOT_FOUND);
        guac_socket_flush(client->socket);
    }

    /* Set handlers for file stream */
    stream->blob_handler = guac_sftp_blob_handler;
    stream->end_handler = guac_sftp_end_handler;

    /* Store file within stream */
    stream->data = file;
    return 0;

}