[Spice-commits] Branch '0.8' - 2 commits - server/Makefile.am server/agent-msg-filter.c server/agent-msg-filter.h server/reds.c server/spice.h

Hans de Goede jwrdegoede at kemper.freedesktop.org
Sat Mar 26 01:08:58 PDT 2011


 server/Makefile.am        |    2 +
 server/agent-msg-filter.c |   85 ++++++++++++++++++++++++++++++++++++++++++++++
 server/agent-msg-filter.h |   45 ++++++++++++++++++++++++
 server/reds.c             |   45 ++++++++++++++++++++++--
 server/spice.h            |    3 +
 5 files changed, 176 insertions(+), 4 deletions(-)

New commits:
commit 302ab69f5bab657029cd323385e6aca86e98c2e4
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Thu Mar 24 16:50:45 2011 +0100

    server: Make copy paste support configurable
    
    Also bump SPICE_SERVER_VERSION to 0x000801 as 0.8.1 will be the
    first version with the new API for this, and we need to be able to
    detect the presence of this API in qemu.

diff --git a/server/reds.c b/server/reds.c
index 537420d..a808390 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -103,6 +103,7 @@ spice_wan_compression_t zlib_glz_state = SPICE_WAN_COMPRESSION_AUTO;
 void *red_tunnel = NULL;
 #endif
 int agent_mouse = TRUE;
+int agent_copypaste = TRUE;
 
 static void openssl_init();
 
@@ -3745,8 +3746,8 @@ static void init_vd_agent_resources()
     ring_init(&state->internal_bufs);
     ring_init(&state->write_queue);
     ring_init(&state->read_bufs);
-    agent_msg_filter_init(&state->write_filter, TRUE);
-    agent_msg_filter_init(&state->read_filter, TRUE);
+    agent_msg_filter_init(&state->write_filter, agent_copypaste);
+    agent_msg_filter_init(&state->read_filter, agent_copypaste);
 
     state->read_state = VDI_PORT_READ_STATE_READ_HADER;
     state->recive_pos = (uint8_t *)&state->vdi_chunk_header;
@@ -4154,6 +4155,15 @@ __visible__ int spice_server_set_agent_mouse(SpiceServer *s, int enable)
     return 0;
 }
 
+__visible__ int spice_server_set_agent_copypaste(SpiceServer *s, int enable)
+{
+    ASSERT(reds == s);
+    agent_copypaste = enable;
+    reds->agent_state.write_filter.copy_paste_enabled = agent_copypaste;
+    reds->agent_state.read_filter.copy_paste_enabled = agent_copypaste;
+    return 0;
+}
+
 __visible__ int spice_server_migrate_info(SpiceServer *s, const char* dest,
                                           int port, int secure_port,
                                           const char* cert_subject)
diff --git a/server/spice.h b/server/spice.h
index 2c5aed7..fd281b7 100644
--- a/server/spice.h
+++ b/server/spice.h
@@ -21,7 +21,7 @@
 #include <stdint.h>
 #include <sys/socket.h>
 
-#define SPICE_SERVER_VERSION 0x000800 /* release 0.8.0 */
+#define SPICE_SERVER_VERSION 0x000801 /* release 0.8.1 */
 
 /* interface base type */
 
@@ -426,6 +426,7 @@ enum {
 int spice_server_set_streaming_video(SpiceServer *s, int value);
 int spice_server_set_playback_compression(SpiceServer *s, int enable);
 int spice_server_set_agent_mouse(SpiceServer *s, int enable);
+int spice_server_set_agent_copypaste(SpiceServer *s, int enable);
 
 int spice_server_get_sock_info(SpiceServer *s, struct sockaddr *sa, socklen_t *salen);
 int spice_server_get_peer_info(SpiceServer *s, struct sockaddr *sa, socklen_t *salen);
commit 04171174175cc30e71d6ce8ab29ff14d4af2ba24
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Thu Mar 24 16:29:25 2011 +0100

    spice-server: Add the ability to filter agent messages

diff --git a/server/Makefile.am b/server/Makefile.am
index 2c86a2c..2938806 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -92,6 +92,8 @@ SMARTCARD_SRCS =
 endif
 
 libspice_server_la_SOURCES =			\
+	agent-msg-filter.c			\
+	agent-msg-filter.h			\
 	demarshallers.h				\
 	glz_encoder.c				\
 	glz_encoder_config.h			\
diff --git a/server/agent-msg-filter.c b/server/agent-msg-filter.c
new file mode 100644
index 0000000..3867d11
--- /dev/null
+++ b/server/agent-msg-filter.c
@@ -0,0 +1,85 @@
+/*
+   Copyright (C) 2011 Red Hat, Inc.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+
+   Red Hat Authors:
+        hdegoede at redhat.com
+*/
+
+#include <string.h>
+#include "red_common.h"
+#include "agent-msg-filter.h"
+
+void agent_msg_filter_init(struct AgentMsgFilter *filter, int copy_paste)
+{
+    memset(filter, 0, sizeof(*filter));
+    filter->copy_paste_enabled = copy_paste;
+}
+
+int agent_msg_filter_process_data(struct AgentMsgFilter *filter,
+                                  uint8_t *data, uint32_t len)
+{
+    struct VDAgentMessage msg_header;
+
+    if (len > VD_AGENT_MAX_DATA_SIZE) {
+        red_printf("invalid agent message: too large");
+        return AGENT_MSG_FILTER_PROTO_ERROR;
+    }
+
+    /* Are we expecting more data from a previous message? */
+    if (filter->msg_data_to_read) {
+data_to_read:
+        if (len > filter->msg_data_to_read) {
+            red_printf("invalid agent message: data exceeds size from header");
+            return AGENT_MSG_FILTER_PROTO_ERROR;
+        }
+        filter->msg_data_to_read -= len;
+        return filter->result;
+    }
+
+    if (len < sizeof(msg_header)) {
+        red_printf("invalid agent message: incomplete header");
+        return AGENT_MSG_FILTER_PROTO_ERROR;
+    }
+    memcpy(&msg_header, data, sizeof(msg_header));
+    len -= sizeof(msg_header);
+
+    if (msg_header.protocol != VD_AGENT_PROTOCOL) {
+        red_printf("invalid agent protocol: %u", msg_header.protocol);
+        return AGENT_MSG_FILTER_PROTO_ERROR;
+    }
+
+    switch (msg_header.type) {
+    case VD_AGENT_CLIPBOARD:
+    case VD_AGENT_CLIPBOARD_GRAB:
+    case VD_AGENT_CLIPBOARD_REQUEST:
+    case VD_AGENT_CLIPBOARD_RELEASE:
+        if (filter->copy_paste_enabled) {
+            filter->result = AGENT_MSG_FILTER_OK;
+        } else {
+            filter->result = AGENT_MSG_FILTER_DISCARD;
+        }
+        break;
+    default:
+        filter->result = AGENT_MSG_FILTER_OK;
+    }
+
+    filter->msg_data_to_read = msg_header.size;
+    if (filter->msg_data_to_read) {
+        goto data_to_read;
+    }
+
+    return filter->result;
+}
diff --git a/server/agent-msg-filter.h b/server/agent-msg-filter.h
new file mode 100644
index 0000000..99dbb8c
--- /dev/null
+++ b/server/agent-msg-filter.h
@@ -0,0 +1,45 @@
+/*
+   Copyright (C) 2011 Red Hat, Inc.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+
+   Red Hat Authors:
+        hdegoede at redhat.com
+*/
+
+#ifndef _H_AGENT_MSG_FILTER
+#define _H_AGENT_MSG_FILTER
+
+#include <spice/vd_agent.h>
+
+/* Possible return values for agent_msg_filter_process_data */
+enum {
+    AGENT_MSG_FILTER_OK,
+    AGENT_MSG_FILTER_DISCARD,
+    AGENT_MSG_FILTER_PROTO_ERROR,
+    AGENT_MSG_FILTER_END
+};
+
+typedef struct AgentMsgFilter {
+    struct VDAgentMessage msg_header;
+    int msg_data_to_read;
+    int result;
+    int copy_paste_enabled;
+} AgentMsgFilter;
+
+void agent_msg_filter_init(struct AgentMsgFilter *filter, int copy_paste);
+int agent_msg_filter_process_data(struct AgentMsgFilter *filter,
+                                  uint8_t *data, uint32_t len);
+
+#endif
diff --git a/server/reds.c b/server/reds.c
index 508c8ff..537420d 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -44,6 +44,7 @@
 #include "reds.h"
 #include <spice/protocol.h>
 #include <spice/vd_agent.h>
+#include "agent-msg-filter.h"
 
 #include "red_common.h"
 #include "red_dispatcher.h"
@@ -192,6 +193,7 @@ typedef struct VDIPortState {
     Ring external_bufs;
     Ring internal_bufs;
     Ring write_queue;
+    AgentMsgFilter write_filter;
 
     Ring read_bufs;
     uint32_t read_state;
@@ -199,6 +201,7 @@ typedef struct VDIPortState {
     uint8_t *recive_pos;
     uint32_t recive_len;
     VDIReadBuf *current_read_buf;
+    AgentMsgFilter read_filter;
 
     VDIChunkHeader vdi_chunk_header;
 
@@ -1213,9 +1216,24 @@ static void dispatch_vdi_port_data(int port, VDIReadBuf *buf)
 {
     VDIPortState *state = &reds->agent_state;
     RedsOutItem *item;
+    int res;
 
     switch (port) {
     case VDP_CLIENT_PORT: {
+        res = agent_msg_filter_process_data(&state->read_filter,
+                                            buf->data, buf->len);
+        switch (res) {
+        case AGENT_MSG_FILTER_OK:
+            break;
+        case AGENT_MSG_FILTER_DISCARD:
+            ring_add(&state->read_bufs, &buf->link);
+            return;
+        case AGENT_MSG_FILTER_PROTO_ERROR:
+            ring_add(&state->read_bufs, &buf->link);
+            reds_agent_remove();
+            return;
+        }
+
         if (reds->agent_state.connected) {
             item = new_out_item(SPICE_MSG_MAIN_AGENT_DATA);
 
@@ -1666,6 +1684,8 @@ static void main_channel_recive_migrate_data(MainMigrateData *data, uint8_t *end
 
 static void reds_main_handle_message(void *opaque, size_t size, uint32_t type, void *message)
 {
+    int res;
+
     switch (type) {
     case SPICE_MSGC_MAIN_AGENT_START:
         red_printf("agent start");
@@ -1696,10 +1716,17 @@ static void reds_main_handle_message(void *opaque, size_t size, uint32_t type, v
             break;
         }
 
-        if (size > SPICE_AGENT_MAX_DATA_SIZE) {
-            red_printf("invalid agent message");
-            reds_disconnect();
+        res = agent_msg_filter_process_data(&reds->agent_state.write_filter,
+                                            message, size);
+        switch (res) {
+        case AGENT_MSG_FILTER_OK:
             break;
+        case AGENT_MSG_FILTER_DISCARD:
+            add_token();
+            return;
+        case AGENT_MSG_FILTER_PROTO_ERROR:
+            reds_disconnect();
+            return;
         }
 
         if (!(ring_item = ring_get_head(&reds->agent_state.external_bufs))) {
@@ -3718,6 +3745,8 @@ static void init_vd_agent_resources()
     ring_init(&state->internal_bufs);
     ring_init(&state->write_queue);
     ring_init(&state->read_bufs);
+    agent_msg_filter_init(&state->write_filter, TRUE);
+    agent_msg_filter_init(&state->read_filter, TRUE);
 
     state->read_state = VDI_PORT_READ_STATE_READ_HADER;
     state->recive_pos = (uint8_t *)&state->vdi_chunk_header;


More information about the Spice-commits mailing list