spice: add <clipboard copypaste='yes|no'> option

From a security pov copy and paste between the guest and the client is not
always desirable. So we need to be able to enable/disable this. The best place
to do this from an administration pov is on the hypervisor, so the qemu cmdline
is getting a spice disable-copy-paste option, see bug 693645. Example qemu
invocation:
qemu -spice port=5932,disable-ticketing,disable-copy-paste

https://bugzilla.redhat.com/show_bug.cgi?id=693661
This commit is contained in:
Marc-André Lureau 2011-06-14 13:35:48 +02:00 committed by Eric Blake
parent af35cece3b
commit 98bfdff12c
9 changed files with 68 additions and 3 deletions

View File

@ -21,3 +21,4 @@
<wency@cn.fujitsu.com> <wency cn fujitsu com> <wency@cn.fujitsu.com> <wency cn fujitsu com>
<cardoe@cardoe.com> <cardoe@gentoo.org> <cardoe@cardoe.com> <cardoe@gentoo.org>
<fsimonce@redhat.com> <federico.simoncelli@gmail.com> <fsimonce@redhat.com> <federico.simoncelli@gmail.com>
<marcandre.lureau@redhat.com> <marcandre.lureau@gmail.com>

View File

@ -1838,6 +1838,7 @@ qemu-kvm -net nic,model=? /dev/null
&lt;channel name='record' mode='insecure'/&gt; &lt;channel name='record' mode='insecure'/&gt;
&lt;image compression='auto_glz'/&gt; &lt;image compression='auto_glz'/&gt;
&lt;streaming mode='filter'/&gt; &lt;streaming mode='filter'/&gt;
&lt;clipboard copypaste='no'/&gt;
&lt;/graphics&gt;</pre> &lt;/graphics&gt;</pre>
<p> <p>
Spice supports variable compression settings for audio, Spice supports variable compression settings for audio,
@ -1862,6 +1863,14 @@ qemu-kvm -net nic,model=? /dev/null
of <code>filter</code>, <code>all</code> of <code>filter</code>, <code>all</code>
or <code>off</code>, <span class="since">since 0.9.2</span>. or <code>off</code>, <span class="since">since 0.9.2</span>.
</p> </p>
<p>
Copy &amp; Paste functionality (via Spice agent) is set
by the <code>clipboard</code> element. It is enabled by
default, and can be disabled by setting
the <code>copypaste</code> property
to <code>no</code>, <span class="since">since
0.9.3</span>.
</>
</dd> </dd>
<dt><code>"rdp"</code></dt> <dt><code>"rdp"</code></dt>
<dd> <dd>

View File

@ -1379,6 +1379,17 @@
<empty/> <empty/>
</element> </element>
</optional> </optional>
<optional>
<element name="clipboard">
<attribute name="copypaste">
<choice>
<value>yes</value>
<value>no</value>
</choice>
</attribute>
<empty/>
</element>
</optional>
</interleave> </interleave>
</group> </group>
<group> <group>

View File

@ -364,6 +364,12 @@ VIR_ENUM_IMPL(virDomainGraphicsSpiceStreamingMode,
"all", "all",
"off"); "off");
VIR_ENUM_IMPL(virDomainGraphicsSpiceClipboardCopypaste,
VIR_DOMAIN_GRAPHICS_SPICE_CLIPBOARD_COPYPASTE_LAST,
"default",
"yes",
"no");
VIR_ENUM_IMPL(virDomainHostdevMode, VIR_DOMAIN_HOSTDEV_MODE_LAST, VIR_ENUM_IMPL(virDomainHostdevMode, VIR_DOMAIN_HOSTDEV_MODE_LAST,
"subsystem", "subsystem",
"capabilities") "capabilities")
@ -4287,6 +4293,26 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) {
VIR_FREE(mode); VIR_FREE(mode);
def->data.spice.streaming = modeVal; def->data.spice.streaming = modeVal;
} else if (xmlStrEqual(cur->name, BAD_CAST "clipboard")) {
const char *copypaste = virXMLPropString(cur, "copypaste");
int copypasteVal;
if (!copypaste) {
virDomainReportError(VIR_ERR_XML_ERROR, "%s",
_("spice clipboard missing copypaste"));
goto error;
}
if ((copypasteVal =
virDomainGraphicsSpiceClipboardCopypasteTypeFromString(copypaste)) <= 0) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown copypaste value '%s'"), copypaste);
VIR_FREE(copypaste);
goto error;
}
VIR_FREE(copypaste);
def->data.spice.copypaste = copypasteVal;
} }
} }
cur = cur->next; cur = cur->next;
@ -9212,7 +9238,7 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
} }
if (!children && (def->data.spice.image || def->data.spice.jpeg || if (!children && (def->data.spice.image || def->data.spice.jpeg ||
def->data.spice.zlib || def->data.spice.playback || def->data.spice.zlib || def->data.spice.playback ||
def->data.spice.streaming)) { def->data.spice.streaming || def->data.spice.copypaste)) {
virBufferAddLit(buf, ">\n"); virBufferAddLit(buf, ">\n");
children = 1; children = 1;
} }
@ -9231,6 +9257,9 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
if (def->data.spice.streaming) if (def->data.spice.streaming)
virBufferAsprintf(buf, " <streaming mode='%s'/>\n", virBufferAsprintf(buf, " <streaming mode='%s'/>\n",
virDomainGraphicsSpiceStreamingModeTypeToString(def->data.spice.streaming)); virDomainGraphicsSpiceStreamingModeTypeToString(def->data.spice.streaming));
if (def->data.spice.copypaste)
virBufferAsprintf(buf, " <clipboard copypaste='%s'/>\n",
virDomainGraphicsSpiceClipboardCopypasteTypeToString(def->data.spice.copypaste));
} }
if (children) { if (children) {

View File

@ -715,6 +715,14 @@ enum virDomainGraphicsSpiceStreamingMode {
VIR_DOMAIN_GRAPHICS_SPICE_STREAMING_MODE_LAST VIR_DOMAIN_GRAPHICS_SPICE_STREAMING_MODE_LAST
}; };
enum virDomainGraphicsSpiceClipboardCopypaste {
VIR_DOMAIN_GRAPHICS_SPICE_CLIPBOARD_COPYPASTE_DEFAULT = 0,
VIR_DOMAIN_GRAPHICS_SPICE_CLIPBOARD_COPYPASTE_YES,
VIR_DOMAIN_GRAPHICS_SPICE_CLIPBOARD_COPYPASTE_NO,
VIR_DOMAIN_GRAPHICS_SPICE_CLIPBOARD_COPYPASTE_LAST
};
typedef struct _virDomainGraphicsDef virDomainGraphicsDef; typedef struct _virDomainGraphicsDef virDomainGraphicsDef;
typedef virDomainGraphicsDef *virDomainGraphicsDefPtr; typedef virDomainGraphicsDef *virDomainGraphicsDefPtr;
struct _virDomainGraphicsDef { struct _virDomainGraphicsDef {
@ -757,6 +765,7 @@ struct _virDomainGraphicsDef {
int zlib; int zlib;
int playback; int playback;
int streaming; int streaming;
int copypaste;
} spice; } spice;
} data; } data;
}; };
@ -1553,6 +1562,7 @@ VIR_ENUM_DECL(virDomainGraphicsSpiceJpegCompression)
VIR_ENUM_DECL(virDomainGraphicsSpiceZlibCompression) VIR_ENUM_DECL(virDomainGraphicsSpiceZlibCompression)
VIR_ENUM_DECL(virDomainGraphicsSpicePlaybackCompression) VIR_ENUM_DECL(virDomainGraphicsSpicePlaybackCompression)
VIR_ENUM_DECL(virDomainGraphicsSpiceStreamingMode) VIR_ENUM_DECL(virDomainGraphicsSpiceStreamingMode)
VIR_ENUM_DECL(virDomainGraphicsSpiceClipboardCopypaste)
/* from libvirt.h */ /* from libvirt.h */
VIR_ENUM_DECL(virDomainState) VIR_ENUM_DECL(virDomainState)
VIR_ENUM_DECL(virDomainNostateReason) VIR_ENUM_DECL(virDomainNostateReason)

View File

@ -274,8 +274,10 @@ virDomainGraphicsSpiceChannelModeTypeFromString;
virDomainGraphicsSpiceChannelModeTypeToString; virDomainGraphicsSpiceChannelModeTypeToString;
virDomainGraphicsSpiceChannelNameTypeFromString; virDomainGraphicsSpiceChannelNameTypeFromString;
virDomainGraphicsSpiceChannelNameTypeToString; virDomainGraphicsSpiceChannelNameTypeToString;
virDomainGraphicsSpiceImageCompressionTypeToString; virDomainGraphicsSpiceClipboardCopypasteFromString;
virDomainGraphicsSpiceClipboardCopypasteToString;
virDomainGraphicsSpiceImageCompressionTypeFromString; virDomainGraphicsSpiceImageCompressionTypeFromString;
virDomainGraphicsSpiceImageCompressionTypeToString;
virDomainGraphicsSpiceJpegCompressionTypeFromString; virDomainGraphicsSpiceJpegCompressionTypeFromString;
virDomainGraphicsSpiceJpegCompressionTypeToString; virDomainGraphicsSpiceJpegCompressionTypeToString;
virDomainGraphicsSpicePlaybackCompressionTypeFromString; virDomainGraphicsSpicePlaybackCompressionTypeFromString;

View File

@ -4161,6 +4161,8 @@ qemuBuildCommandLine(virConnectPtr conn,
if (def->graphics[0]->data.spice.streaming) if (def->graphics[0]->data.spice.streaming)
virBufferAsprintf(&opt, ",streaming-video=%s", virBufferAsprintf(&opt, ",streaming-video=%s",
virDomainGraphicsSpiceStreamingModeTypeToString(def->graphics[0]->data.spice.streaming)); virDomainGraphicsSpiceStreamingModeTypeToString(def->graphics[0]->data.spice.streaming));
if (def->graphics[0]->data.spice.copypaste == VIR_DOMAIN_GRAPHICS_SPICE_CLIPBOARD_COPYPASTE_NO)
virBufferAddLit(&opt, ",disable-copy-paste");
virCommandAddArg(cmd, "-spice"); virCommandAddArg(cmd, "-spice");
virCommandAddArgBuffer(cmd, &opt); virCommandAddArgBuffer(cmd, &opt);

View File

@ -4,6 +4,6 @@ unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda \
/dev/HostVG/QEMUGuest1 -usb -spice port=5903,tls-port=5904,addr=127.0.0.1,\ /dev/HostVG/QEMUGuest1 -usb -spice port=5903,tls-port=5904,addr=127.0.0.1,\
x509-dir=/etc/pki/libvirt-spice,tls-channel=main,plaintext-channel=inputs,\ x509-dir=/etc/pki/libvirt-spice,tls-channel=main,plaintext-channel=inputs,\
image-compression=auto_glz,jpeg-wan-compression=auto,zlib-glz-wan-compression=auto,\ image-compression=auto_glz,jpeg-wan-compression=auto,zlib-glz-wan-compression=auto,\
playback-compression=on,streaming-video=filter -vga \ playback-compression=on,streaming-video=filter,disable-copy-paste -vga \
qxl -global qxl.vram_size=18874368 -device qxl,id=video1,vram_size=33554432,bus=pci.0,addr=0x4 \ qxl -global qxl.vram_size=18874368 -device qxl,id=video1,vram_size=33554432,bus=pci.0,addr=0x4 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3

View File

@ -29,6 +29,7 @@
<zlib compression='auto'/> <zlib compression='auto'/>
<playback compression='on'/> <playback compression='on'/>
<streaming mode='filter'/> <streaming mode='filter'/>
<clipboard copypaste='no'/>
</graphics> </graphics>
<video> <video>
<model type='qxl' vram='18432' heads='1'/> <model type='qxl' vram='18432' heads='1'/>