From c2db6d1066bcb73c5ddf9e38c4ef30545706eae9 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 24 Mar 2011 16:29:25 +0100 Subject: spice-server: Add the ability to filter agent messages --- server/agent-msg-filter.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 server/agent-msg-filter.c (limited to 'server/agent-msg-filter.c') diff --git a/server/agent-msg-filter.c b/server/agent-msg-filter.c new file mode 100644 index 00000000..3867d11e --- /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 . + + Red Hat Authors: + hdegoede@redhat.com +*/ + +#include +#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; +} -- cgit