qemu_command_builder/vnc.rs
1use crate::common::OnOff;
2use crate::to_command::ToArg;
3use crate::to_command::ToCommand;
4use bon::Builder;
5use std::path::PathBuf;
6
7pub enum VNCDisplay {
8 To(usize),
9 Host(usize),
10 Unix(PathBuf),
11 None,
12}
13
14pub enum AllowExclusiveForceSharedIgnore {
15 AllowExclusive,
16 ForceShared,
17 Ignore,
18}
19
20impl ToArg for AllowExclusiveForceSharedIgnore {
21 fn to_arg(&self) -> &str {
22 match self {
23 AllowExclusiveForceSharedIgnore::AllowExclusive => "allow-exclusive",
24 AllowExclusiveForceSharedIgnore::ForceShared => "force-shared",
25 AllowExclusiveForceSharedIgnore::Ignore => "ignore",
26 }
27 }
28}
29#[derive(Builder)]
30pub struct VNC {
31 display: VNCDisplay,
32
33 /// Connect to a listening VNC client via a "reverse" connection.
34 /// The client is specified by the display. For reverse network
35 /// connections (host:d,``reverse``), the d argument is a TCP port
36 /// number, not a display number.
37 reverse: Option<OnOff>,
38
39 /// Opens an additional TCP listening port dedicated to VNC
40 /// Websocket connections. If a bare websocket option is given, the
41 /// Websocket port is 5700+display. An alternative port can be
42 /// specified with the syntax ``websocket``\ =port.
43 ///
44 /// If host is specified connections will only be allowed from this
45 /// host. It is possible to control the websocket listen address
46 /// independently, using the syntax ``websocket``\ =host:port.
47 ///
48 /// Websocket could be allowed over UNIX domain socket, using the syntax
49 /// ``websocket``\ =unix:path, where path is the location of a unix socket
50 /// to listen for connections on.
51 ///
52 /// If no TLS credentials are provided, the websocket connection
53 /// runs in unencrypted mode. If TLS credentials are provided, the
54 /// websocket connection requires encrypted client connections.
55 websocket: Option<OnOff>,
56
57 /// Require that password based authentication is used for client
58 /// connections.
59 ///
60 /// The password must be set separately using the ``set_password``
61 /// command in the :ref:`QEMU monitor`. The
62 /// syntax to change your password is:
63 /// ``set_password <protocol> <password>`` where <protocol> could be
64 /// either "vnc" or "spice".
65 ///
66 /// If you would like to change <protocol> password expiration, you
67 /// should use ``expire_password <protocol> <expiration-time>``
68 /// where expiration time could be one of the following options:
69 /// now, never, +seconds or UNIX time of expiration, e.g. +60 to
70 /// make password expire in 60 seconds, or 1335196800 to make
71 /// password expire on "Mon Apr 23 12:00:00 EDT 2012" (UNIX time for
72 /// this date and time).
73 ///
74 /// You can also use keywords "now" or "never" for the expiration
75 /// time to allow <protocol> password to expire immediately or never
76 /// expire.
77 password: Option<OnOff>,
78
79 /// Require that password based authentication is used for client
80 /// connections, using the password provided by the ``secret``
81 /// object identified by ``secret-id``.
82 password_secret: Option<String>,
83
84 /// Provides the ID of a set of TLS credentials to use to secure the
85 /// VNC server. They will apply to both the normal VNC server socket
86 /// and the websocket socket (if enabled). Setting TLS credentials
87 /// will cause the VNC server socket to enable the VeNCrypt auth
88 /// mechanism. The credentials should have been previously created
89 /// using the ``-object tls-creds`` argument.
90 tls_creds: Option<String>,
91
92 /// Provides the ID of the QAuthZ authorization object against which
93 /// the client's x509 distinguished name will validated. This object
94 /// is only resolved at time of use, so can be deleted and recreated
95 /// on the fly while the VNC server is active. If missing, it will
96 /// default to denying access.
97 tls_authz: Option<String>,
98
99 /// Require that the client use SASL to authenticate with the VNC
100 /// server. The exact choice of authentication method used is
101 /// controlled from the system / user's SASL configuration file for
102 /// the 'qemu' service. This is typically found in
103 /// /etc/sasl2/qemu.conf. If running QEMU as an unprivileged user,
104 /// an environment variable SASL\_CONF\_PATH can be used to make it
105 /// search alternate locations for the service config. While some
106 /// SASL auth methods can also provide data encryption (eg GSSAPI),
107 /// it is recommended that SASL always be combined with the 'tls'
108 /// and 'x509' settings to enable use of SSL and server
109 /// certificates. This ensures a data encryption preventing
110 /// compromise of authentication credentials. See the
111 /// :ref:`VNC security` section in the System Emulation Users Guide
112 /// for details on using SASL authentication.
113 sasl: Option<OnOff>,
114
115 /// Provides the ID of the QAuthZ authorization object against which
116 /// the client's SASL username will validated. This object is only
117 /// resolved at time of use, so can be deleted and recreated on the
118 /// fly while the VNC server is active. If missing, it will default
119 /// to denying access.
120 sasl_authz: Option<String>,
121
122 /// Legacy method for enabling authorization of clients against the
123 /// x509 distinguished name and SASL username. It results in the
124 /// creation of two ``authz-list`` objects with IDs of
125 /// ``vnc.username`` and ``vnc.x509dname``. The rules for these
126 /// objects must be configured with the HMP ACL commands.
127 ///
128 /// This option is deprecated and should no longer be used. The new
129 /// ``sasl-authz`` and ``tls-authz`` options are a replacement.
130 acl: Option<OnOff>,
131
132 /// Enable lossy compression methods (gradient, JPEG, ...). If this
133 /// option is set, VNC client may receive lossy framebuffer updates
134 /// depending on its encoding settings. Enabling this option can
135 /// save a lot of bandwidth at the expense of quality.
136 lossy: Option<OnOff>,
137
138 /// Disable adaptive encodings. Adaptive encodings are enabled by
139 /// default. An adaptive encoding will try to detect frequently
140 /// updated screen regions, and send updates in these regions using
141 /// a lossy encoding (like JPEG). This can be really helpful to save
142 /// bandwidth when playing videos. Disabling adaptive encodings
143 /// restores the original static behavior of encodings like Tight.
144 non_adaptive: Option<OnOff>,
145
146 /// Set display sharing policy. 'allow-exclusive' allows clients to
147 /// ask for exclusive access. As suggested by the rfb spec this is
148 /// implemented by dropping other connections. Connecting multiple
149 /// clients in parallel requires all clients asking for a shared
150 /// session (vncviewer: -shared switch). This is the default.
151 /// 'force-shared' disables exclusive client access. Useful for
152 /// shared desktop sessions, where you don't want someone forgetting
153 /// specify -shared disconnect everybody else. 'ignore' completely
154 /// ignores the shared flag and allows everybody connect
155 /// unconditionally. Doesn't conform to the rfb spec but is
156 /// traditional QEMU behavior.
157 share: Option<AllowExclusiveForceSharedIgnore>,
158
159 /// Set keyboard delay, for key down and key up events, in
160 /// milliseconds. Default is 10. Keyboards are low-bandwidth
161 /// devices, so this slowdown can help the device and guest to keep
162 /// up and not lose events in case events are arriving in bulk.
163 /// Possible causes for the latter are flaky network connections, or
164 /// scripts for automated testing.
165 key_delay_ms: Option<usize>,
166
167 /// Use the specified audiodev when the VNC client requests audio
168 /// transmission. When not using an -audiodev argument, this option
169 /// must be omitted, otherwise is must be present and specify a
170 /// valid audiodev.
171 audiodev: Option<String>,
172
173 /// Permit the remote client to issue shutdown, reboot or reset power
174 /// control requests.
175 power_control: Option<OnOff>,
176}
177
178impl ToCommand for VNC {
179 fn to_command(&self) -> Vec<String> {
180 let mut cmd = vec![];
181
182 cmd.push("-vnc".to_string());
183
184 let mut args = vec![];
185 match &self.display {
186 VNCDisplay::To(l) => {
187 args.push(format!("to={}", l));
188 }
189 VNCDisplay::Host(d) => {
190 args.push(format!("host={}", d));
191 }
192 VNCDisplay::Unix(path) => {
193 args.push(format!("unix={}", path.display()));
194 }
195 VNCDisplay::None => {
196 args.push("none".to_string());
197 }
198 }
199
200 if let Some(reverse) = &self.reverse {
201 args.push(format!("reverse={}", reverse.to_arg()));
202 }
203 if let Some(websocket) = &self.websocket {
204 args.push(format!("websocket={}", websocket.to_arg()));
205 }
206 if let Some(password) = &self.password {
207 args.push(format!("password={}", password.to_arg()));
208 }
209 if let Some(password_secret) = &self.password_secret {
210 args.push(format!("password-secret={}", password_secret));
211 }
212 if let Some(tls_creds) = &self.tls_creds {
213 args.push(format!("tls-creds={}", tls_creds));
214 }
215 if let Some(tls_authz) = &self.tls_authz {
216 args.push(format!("tls-authz={}", tls_authz));
217 }
218 if let Some(sasl) = &self.sasl {
219 args.push(format!("sasl={}", sasl.to_arg()));
220 }
221 if let Some(sasl_authz) = &self.sasl_authz {
222 args.push(format!("sasl-authz={}", sasl_authz));
223 }
224 if let Some(acl) = &self.acl {
225 args.push(format!("acl={}", acl.to_arg()));
226 }
227 if let Some(lossy) = &self.lossy {
228 args.push(format!("lossy={}", lossy.to_arg()));
229 }
230 if let Some(non_adaptive) = &self.non_adaptive {
231 args.push(format!("non-adaptive={}", non_adaptive.to_arg()));
232 }
233 if let Some(share) = &self.share {
234 args.push(format!("share={}", share.to_arg()));
235 }
236 if let Some(key_delay_ms) = &self.key_delay_ms {
237 args.push(format!("key-delay-ms={}", key_delay_ms));
238 }
239 if let Some(audiodev) = &self.audiodev {
240 args.push(format!("audiodev={}", audiodev));
241 }
242 if let Some(power_control) = &self.power_control {
243 args.push(format!("power-control={}", power_control.to_arg()));
244 }
245
246 cmd.push(args.join(","));
247
248 cmd
249 }
250}