[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v8 3/3] qapi/monitor: allow VNC display id in set/expire_pass
From: |
Markus Armbruster |
Subject: |
Re: [PATCH v8 3/3] qapi/monitor: allow VNC display id in set/expire_password |
Date: |
Wed, 09 Feb 2022 15:07:46 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) |
Fabian Ebner <f.ebner@proxmox.com> writes:
> From: Stefan Reiter <s.reiter@proxmox.com>
>
> It is possible to specify more than one VNC server on the command line,
> either with an explicit ID or the auto-generated ones à la "default",
> "vnc2", "vnc3", ...
>
> It is not possible to change the password on one of these extra VNC
> displays though. Fix this by adding a "display" parameter to the
> "set_password" and "expire_password" QMP and HMP commands.
>
> For HMP, the display is specified using the "-d" value flag.
>
> For QMP, the schema is updated to explicitly express the supported
> variants of the commands with protocol-discriminated unions.
>
> Suggested-by: Markus Armbruster <armbru@redhat.com>
Did I suggest this feature? I don't remember... Most likely, I merely
suggested using a union. Mind if I drop this tag?
> Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
> [FE: update "Since: " from 6.2 to 7.0
> set {has_}connected for VNC in hmp_set_password]
> Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
> ---
>
> v7 -> v8:
> * add missing # in the description for @ExpirePasswordOptions
> * other changes are already mentioned above
>
> hmp-commands.hx | 24 +++++-----
> monitor/hmp-cmds.c | 39 ++++++++++++----
> monitor/qmp-cmds.c | 34 ++++++--------
> qapi/ui.json | 110 ++++++++++++++++++++++++++++++++++++---------
> 4 files changed, 145 insertions(+), 62 deletions(-)
>
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 70a9136ac2..cc2f4bdeba 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1514,33 +1514,35 @@ ERST
>
> {
> .name = "set_password",
> - .args_type = "protocol:s,password:s,connected:s?",
> - .params = "protocol password action-if-connected",
> + .args_type = "protocol:s,password:s,display:-dV,connected:s?",
> + .params = "protocol password [-d display] [action-if-connected]",
> .help = "set spice/vnc password",
> .cmd = hmp_set_password,
> },
>
> SRST
> -``set_password [ vnc | spice ] password [ action-if-connected ]``
> - Change spice/vnc password. *action-if-connected* specifies what
> - should happen in case a connection is established: *fail* makes the
> - password change fail. *disconnect* changes the password and
> +``set_password [ vnc | spice ] password [ -d display ] [ action-if-connected
> ]``
This is the first flag with an argument in HMP. The alternative is
another optional argument.
PRO optional argument: no need for PATCH 1.
PRO flag with argument: can specify the display without
action-if-connected.
Dave, this is your call to make.
> + Change spice/vnc password. *display* can be used with 'vnc' to specify
> + which display to set the password on. *action-if-connected* specifies
> + what should happen in case a connection is established: *fail* makes
> + the password change fail. *disconnect* changes the password and
> disconnects the client. *keep* changes the password and keeps the
> connection up. *keep* is the default.
> ERST
>
> {
> .name = "expire_password",
> - .args_type = "protocol:s,time:s",
> - .params = "protocol time",
> + .args_type = "protocol:s,time:s,display:-dV",
> + .params = "protocol time [-d display]",
> .help = "set spice/vnc password expire-time",
> .cmd = hmp_expire_password,
> },
>
> SRST
> -``expire_password [ vnc | spice ]`` *expire-time*
> - Specify when a password for spice/vnc becomes
> - invalid. *expire-time* accepts:
> +``expire_password [ vnc | spice ] expire-time [ -d display ]``
> + Specify when a password for spice/vnc becomes invalid.
> + *display* behaves the same as in ``set_password``.
> + *expire-time* accepts:
>
> ``now``
> Invalidate password instantly.
> diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
> index ff78741b75..be0d919b64 100644
> --- a/monitor/hmp-cmds.c
> +++ b/monitor/hmp-cmds.c
> @@ -1396,13 +1396,17 @@ void hmp_set_password(Monitor *mon, const QDict
> *qdict)
> {
> const char *protocol = qdict_get_str(qdict, "protocol");
> const char *password = qdict_get_str(qdict, "password");
> + const char *display = qdict_get_try_str(qdict, "display");
> const char *connected = qdict_get_try_str(qdict, "connected");
> Error *err = NULL;
> - DisplayProtocol proto;
> SetPasswordAction conn;
>
> - proto = qapi_enum_parse(&DisplayProtocol_lookup, protocol,
> - DISPLAY_PROTOCOL_VNC, &err);
> + SetPasswordOptions opts = {
> + .password = (char *)password,
> + };
> +
> + opts.protocol = qapi_enum_parse(&DisplayProtocol_lookup, protocol,
> + DISPLAY_PROTOCOL_VNC, &err);
> if (err) {
> goto out;
> }
> @@ -1413,7 +1417,17 @@ void hmp_set_password(Monitor *mon, const QDict *qdict)
> goto out;
> }
>
> - qmp_set_password(proto, password, !!connected, conn, &err);
> + if (opts.protocol == DISPLAY_PROTOCOL_VNC) {
> + opts.u.vnc.has_display = !!display;
> + opts.u.vnc.display = (char *)display;
> + opts.u.vnc.has_connected = !!connected;
> + opts.u.vnc.connected = conn;
> + } else if (opts.protocol == DISPLAY_PROTOCOL_SPICE) {
> + opts.u.spice.has_connected = !!connected;
> + opts.u.spice.connected = conn;
> + }
> +
> + qmp_set_password(&opts, &err);
>
> out:
> hmp_handle_error(mon, err);
> @@ -1423,16 +1437,25 @@ void hmp_expire_password(Monitor *mon, const QDict
> *qdict)
> {
> const char *protocol = qdict_get_str(qdict, "protocol");
> const char *whenstr = qdict_get_str(qdict, "time");
> + const char *display = qdict_get_try_str(qdict, "display");
> Error *err = NULL;
> - DisplayProtocol proto;
>
> - proto = qapi_enum_parse(&DisplayProtocol_lookup, protocol,
> - DISPLAY_PROTOCOL_VNC, &err);
> + ExpirePasswordOptions opts = {
> + .time = (char *)whenstr,
> + };
> +
> + opts.protocol = qapi_enum_parse(&DisplayProtocol_lookup, protocol,
> + DISPLAY_PROTOCOL_VNC, &err);
> if (err) {
> goto out;
> }
>
> - qmp_expire_password(proto, whenstr, &err);
> + if (opts.protocol == DISPLAY_PROTOCOL_VNC) {
> + opts.u.vnc.has_display = !!display;
> + opts.u.vnc.display = (char *)display;
> + }
> +
> + qmp_expire_password(&opts, &err);
>
> out:
> hmp_handle_error(mon, err);
> diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
> index b6e8b57fcc..37db941fd3 100644
> --- a/monitor/qmp-cmds.c
> +++ b/monitor/qmp-cmds.c
> @@ -168,35 +168,27 @@ void qmp_system_wakeup(Error **errp)
> qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, errp);
> }
>
> -void qmp_set_password(DisplayProtocol protocol, const char *password,
> - bool has_connected, SetPasswordAction connected,
> - Error **errp)
> +void qmp_set_password(SetPasswordOptions *opts, Error **errp)
> {
> - int disconnect_if_connected = 0;
> - int fail_if_connected = 0;
> int rc;
>
> - if (has_connected) {
> - fail_if_connected = connected == SET_PASSWORD_ACTION_FAIL;
> - disconnect_if_connected = connected ==
> SET_PASSWORD_ACTION_DISCONNECT;
> - }
> -
> - if (protocol == DISPLAY_PROTOCOL_SPICE) {
> + if (opts->protocol == DISPLAY_PROTOCOL_SPICE) {
> if (!qemu_using_spice(errp)) {
> return;
> }
> - rc = qemu_spice.set_passwd(password, fail_if_connected,
> - disconnect_if_connected);
> + rc = qemu_spice.set_passwd(opts->password,
> + opts->u.spice.connected == SET_PASSWORD_ACTION_FAIL,
> + opts->u.spice.connected == SET_PASSWORD_ACTION_DISCONNECT);
> } else {
> - assert(protocol == DISPLAY_PROTOCOL_VNC);
> - if (fail_if_connected || disconnect_if_connected) {
> + assert(opts->protocol == DISPLAY_PROTOCOL_VNC);
> + if (opts->u.vnc.connected != SET_PASSWORD_ACTION_KEEP) {
> /* vnc supports "connected=keep" only */
> error_setg(errp, QERR_INVALID_PARAMETER, "connected");
> return;
> }
> /* Note that setting an empty password will not disable login through
> * this interface. */
> - rc = vnc_display_password(NULL, password);
> + rc = vnc_display_password(opts->u.vnc.display, opts->password);
> }
>
> if (rc != 0) {
> @@ -204,11 +196,11 @@ void qmp_set_password(DisplayProtocol protocol, const
> char *password,
> }
> }
>
> -void qmp_expire_password(DisplayProtocol protocol, const char *whenstr,
> - Error **errp)
> +void qmp_expire_password(ExpirePasswordOptions *opts, Error **errp)
> {
> time_t when;
> int rc;
> + const char *whenstr = opts->time;
>
> if (strcmp(whenstr, "now") == 0) {
> when = 0;
> @@ -220,14 +212,14 @@ void qmp_expire_password(DisplayProtocol protocol,
> const char *whenstr,
> when = strtoull(whenstr, NULL, 10);
> }
>
> - if (protocol == DISPLAY_PROTOCOL_SPICE) {
> + if (opts->protocol == DISPLAY_PROTOCOL_SPICE) {
> if (!qemu_using_spice(errp)) {
> return;
> }
> rc = qemu_spice.set_pw_expire(when);
> } else {
> - assert(protocol == DISPLAY_PROTOCOL_VNC);
> - rc = vnc_display_pw_expire(NULL, when);
> + assert(opts->protocol == DISPLAY_PROTOCOL_VNC);
> + rc = vnc_display_pw_expire(opts->u.vnc.display, when);
> }
>
> if (rc != 0) {
> diff --git a/qapi/ui.json b/qapi/ui.json
> index e112409211..089f05c702 100644
> --- a/qapi/ui.json
> +++ b/qapi/ui.json
> @@ -38,20 +38,61 @@
> 'data': [ 'keep', 'fail', 'disconnect' ] }
>
> ##
> -# @set_password:
> +# @SetPasswordOptions:
> #
> -# Sets the password of a remote display session.
> +# General options for set_password.
Actually, all the options there are. Let's drop "General".
> #
> # @protocol: - 'vnc' to modify the VNC server password
> # - 'spice' to modify the Spice server password
> #
> # @password: the new password
> #
> -# @connected: how to handle existing clients when changing the
> -# password. If nothing is specified, defaults to 'keep'
> -# 'fail' to fail the command if clients are connected
> -# 'disconnect' to disconnect existing clients
> -# 'keep' to maintain existing clients
> +# Since: 7.0
> +#
> +##
> +{ 'union': 'SetPasswordOptions',
> + 'base': { 'protocol': 'DisplayProtocol',
> + 'password': 'str' },
> + 'discriminator': 'protocol',
> + 'data': { 'vnc': 'SetPasswordOptionsVnc',
> + 'spice': 'SetPasswordOptionsSpice' } }
> +
> +##
> +# @SetPasswordOptionsSpice:
> +#
> +# Options for set_password specific to the SPICE procotol.
> +#
> +# @connected: How to handle existing clients when changing the
> +# password. If nothing is specified, defaults to 'keep'.
> +#
> +# Since: 7.0
> +#
> +##
> +{ 'struct': 'SetPasswordOptionsSpice',
> + 'data': { '*connected': 'SetPasswordAction' } }
> +
> +##
> +# @SetPasswordOptionsVnc:
> +#
> +# Options for set_password specific to the VNC procotol.
> +#
> +# @display: The id of the display where the password should be changed.
> +# Defaults to the first.
> +#
> +# @connected: How to handle existing clients when changing the
> +# password.
Neglects to document the default, unlike SetPasswordOptionsSpice above.
> +#
> +# Since: 7.0
> +#
> +##
> +{ 'struct': 'SetPasswordOptionsVnc',
> + 'data': { '*display': 'str',
> + '*connected': 'SetPasswordAction' }}
@connected could be made a common member. Untested incremental patch
appended for your consideration.
> +
> +##
> +# @set_password:
> +#
> +# Set the password of a remote display server.
> #
> # Returns: - Nothing on success
> # - If Spice is not enabled, DeviceNotFound
> @@ -65,17 +106,15 @@
> # <- { "return": {} }
> #
> ##
> -{ 'command': 'set_password',
> - 'data': { 'protocol': 'DisplayProtocol',
> - 'password': 'str',
> - '*connected': 'SetPasswordAction' } }
> +{ 'command': 'set_password', 'boxed': true, 'data': 'SetPasswordOptions' }
>
> ##
> -# @expire_password:
> +# @ExpirePasswordOptions:
> #
> -# Expire the password of a remote display server.
> +# General options for expire_password.
> #
> -# @protocol: the name of the remote display protocol 'vnc' or 'spice'
> +# @protocol: - 'vnc' to modify the VNC server expiration
> +# - 'spice' to modify the Spice server expiration
> #
> # @time: when to expire the password.
> #
> @@ -84,16 +123,45 @@
> # - '+INT' where INT is the number of seconds from now (integer)
> # - 'INT' where INT is the absolute time in seconds
> #
> -# Returns: - Nothing on success
> -# - If @protocol is 'spice' and Spice is not active, DeviceNotFound
> -#
> -# Since: 0.14
> -#
> # Notes: Time is relative to the server and currently there is no way to
> # coordinate server time with client time. It is not recommended to
> # use the absolute time version of the @time parameter unless you're
> # sure you are on the same machine as the QEMU instance.
> #
> +# Since: 7.0
> +#
> +##
> +{ 'union': 'ExpirePasswordOptions',
> + 'base': { 'protocol': 'DisplayProtocol',
> + 'time': 'str' },
> + 'discriminator': 'protocol',
> + 'data': { 'vnc': 'ExpirePasswordOptionsVnc' } }
> +
> +##
> +# @ExpirePasswordOptionsVnc:
> +#
> +# Options for expire_password specific to the VNC procotol.
> +#
> +# @display: The id of the display where the expiration should be changed.
> +# Defaults to the first.
> +#
> +# Since: 7.0
> +#
> +##
> +
> +{ 'struct': 'ExpirePasswordOptionsVnc',
> + 'data': { '*display': 'str' } }
> +
> +##
> +# @expire_password:
> +#
> +# Expire the password of a remote display server.
> +#
> +# Returns: - Nothing on success
> +# - If @protocol is 'spice' and Spice is not active, DeviceNotFound
> +#
> +# Since: 0.14
> +#
> # Example:
> #
> # -> { "execute": "expire_password", "arguments": { "protocol": "vnc",
> @@ -101,9 +169,7 @@
> # <- { "return": {} }
> #
> ##
> -{ 'command': 'expire_password',
> - 'data': { 'protocol': 'DisplayProtocol',
> - 'time': 'str' } }
> +{ 'command': 'expire_password', 'boxed': true, 'data':
> 'ExpirePasswordOptions' }
>
> ##
> # @screendump:
diff --git a/qapi/ui.json b/qapi/ui.json
index 089f05c702..bcc69896ed 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -47,29 +47,18 @@
#
# @password: the new password
#
+# @connected: How to handle existing clients when changing the
+# password.
+#
# Since: 7.0
#
##
{ 'union': 'SetPasswordOptions',
'base': { 'protocol': 'DisplayProtocol',
- 'password': 'str' },
+ 'password': 'str',
+ '*connected': 'SetPasswordAction' },
'discriminator': 'protocol',
- 'data': { 'vnc': 'SetPasswordOptionsVnc',
- 'spice': 'SetPasswordOptionsSpice' } }
-
-##
-# @SetPasswordOptionsSpice:
-#
-# Options for set_password specific to the SPICE procotol.
-#
-# @connected: How to handle existing clients when changing the
-# password. If nothing is specified, defaults to 'keep'.
-#
-# Since: 7.0
-#
-##
-{ 'struct': 'SetPasswordOptionsSpice',
- 'data': { '*connected': 'SetPasswordAction' } }
+ 'data': { 'vnc': 'SetPasswordOptionsVnc' } }
##
# @SetPasswordOptionsVnc:
@@ -79,15 +68,11 @@
# @display: The id of the display where the password should be changed.
# Defaults to the first.
#
-# @connected: How to handle existing clients when changing the
-# password.
-#
# Since: 7.0
#
##
{ 'struct': 'SetPasswordOptionsVnc',
- 'data': { '*display': 'str',
- '*connected': 'SetPasswordAction' }}
+ 'data': { '*display': 'str' } }
##
# @set_password:
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index be0d919b64..54762a9396 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -1401,8 +1401,16 @@ void hmp_set_password(Monitor *mon, const QDict *qdict)
Error *err = NULL;
SetPasswordAction conn;
+ conn = qapi_enum_parse(&SetPasswordAction_lookup, connected,
+ SET_PASSWORD_ACTION_KEEP, &err);
+ if (err) {
+ goto out;
+ }
+
SetPasswordOptions opts = {
.password = (char *)password,
+ .has_connected = !!connected,
+ .connected = conn,
};
opts.protocol = qapi_enum_parse(&DisplayProtocol_lookup, protocol,
@@ -1411,20 +1419,9 @@ void hmp_set_password(Monitor *mon, const QDict *qdict)
goto out;
}
- conn = qapi_enum_parse(&SetPasswordAction_lookup, connected,
- SET_PASSWORD_ACTION_KEEP, &err);
- if (err) {
- goto out;
- }
-
if (opts.protocol == DISPLAY_PROTOCOL_VNC) {
opts.u.vnc.has_display = !!display;
opts.u.vnc.display = (char *)display;
- opts.u.vnc.has_connected = !!connected;
- opts.u.vnc.connected = conn;
- } else if (opts.protocol == DISPLAY_PROTOCOL_SPICE) {
- opts.u.spice.has_connected = !!connected;
- opts.u.spice.connected = conn;
}
qmp_set_password(&opts, &err);
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index 37db941fd3..df97582dd4 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -177,11 +177,11 @@ void qmp_set_password(SetPasswordOptions *opts, Error
**errp)
return;
}
rc = qemu_spice.set_passwd(opts->password,
- opts->u.spice.connected == SET_PASSWORD_ACTION_FAIL,
- opts->u.spice.connected == SET_PASSWORD_ACTION_DISCONNECT);
+ opts->connected == SET_PASSWORD_ACTION_FAIL,
+ opts->connected == SET_PASSWORD_ACTION_DISCONNECT);
} else {
assert(opts->protocol == DISPLAY_PROTOCOL_VNC);
- if (opts->u.vnc.connected != SET_PASSWORD_ACTION_KEEP) {
+ if (opts->connected != SET_PASSWORD_ACTION_KEEP) {
/* vnc supports "connected=keep" only */
error_setg(errp, QERR_INVALID_PARAMETER, "connected");
return;
[PATCH v8 3/3] qapi/monitor: allow VNC display id in set/expire_password, Fabian Ebner, 2022/02/04
- Re: [PATCH v8 3/3] qapi/monitor: allow VNC display id in set/expire_password,
Markus Armbruster <=