All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrangé" <berrange@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Daniel P. Berrangé" <berrange@redhat.com>,
	"Markus Armbruster" <armbru@redhat.com>
Subject: [PULL 18/27] ui: add proper error reporting for password changes
Date: Tue,  3 Mar 2026 15:05:55 +0000	[thread overview]
Message-ID: <20260303150604.2402872-19-berrange@redhat.com> (raw)
In-Reply-To: <20260303150604.2402872-1-berrange@redhat.com>

Neither the VNC or SPICE code for password changes provides error
reporting at source, leading the callers to report a largely useless
generic error message.

Fixing this removes one of the two remaining needs for the undesirable
error_printf_unless_qmp() method.

While fixing this the error message hint is improved to recommend the
'password-secret' option which allows securely passing a password at
startup.

Reported-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 include/ui/console.h                 |  2 +-
 include/ui/qemu-spice-module.h       |  3 ++-
 tests/functional/generic/test_vnc.py |  4 ++--
 ui/spice-core.c                      | 25 ++++++++++++++++++-------
 ui/spice-module.c                    |  7 ++++---
 ui/ui-qmp-cmds.c                     | 19 ++++++-------------
 ui/vnc-stubs.c                       |  6 +++---
 ui/vnc.c                             | 10 +++++++---
 8 files changed, 43 insertions(+), 33 deletions(-)

diff --git a/include/ui/console.h b/include/ui/console.h
index 98feaa58bd..3677a9d334 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -457,7 +457,7 @@ void qemu_display_help(void);
 void vnc_display_init(const char *id, Error **errp);
 void vnc_display_open(const char *id, Error **errp);
 void vnc_display_add_client(const char *id, int csock, bool skipauth);
-int vnc_display_password(const char *id, const char *password);
+int vnc_display_password(const char *id, const char *password, Error **errp);
 int vnc_display_pw_expire(const char *id, time_t expires);
 void vnc_parse(const char *str);
 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp);
diff --git a/include/ui/qemu-spice-module.h b/include/ui/qemu-spice-module.h
index 1f22d557ea..072efa0c83 100644
--- a/include/ui/qemu-spice-module.h
+++ b/include/ui/qemu-spice-module.h
@@ -29,7 +29,8 @@ struct QemuSpiceOps {
     void (*display_init)(void);
     int (*migrate_info)(const char *h, int p, int t, const char *s);
     int (*set_passwd)(const char *passwd,
-                      bool fail_if_connected, bool disconnect_if_connected);
+                      bool fail_if_connected, bool disconnect_if_connected,
+                      Error **errp);
     int (*set_pw_expire)(time_t expires);
     int (*display_add_client)(int csock, int skipauth, int tls);
 #ifdef CONFIG_SPICE
diff --git a/tests/functional/generic/test_vnc.py b/tests/functional/generic/test_vnc.py
index f1dd1597cf..097f858ca1 100755
--- a/tests/functional/generic/test_vnc.py
+++ b/tests/functional/generic/test_vnc.py
@@ -48,7 +48,7 @@ def test_no_vnc_change_password(self):
         self.assertEqual(set_password_response['error']['class'],
                          'GenericError')
         self.assertEqual(set_password_response['error']['desc'],
-                         'Could not set password')
+                         'No VNC display is present');
 
     def launch_guarded(self):
         try:
@@ -73,7 +73,7 @@ def test_change_password_requires_a_password(self):
         self.assertEqual(set_password_response['error']['class'],
                          'GenericError')
         self.assertEqual(set_password_response['error']['desc'],
-                         'Could not set password')
+                         'VNC password authentication is disabled')
 
     def test_change_password(self):
         self.set_machine('none')
diff --git a/ui/spice-core.c b/ui/spice-core.c
index ee13ecc4a5..ef1c00134f 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -757,7 +757,7 @@ static void qemu_spice_init(void)
                              tls_ciphers);
     }
     if (password) {
-        qemu_spice.set_passwd(password, false, false);
+        qemu_spice.set_passwd(password, false, false, NULL);
     }
     if (qemu_opt_get_bool(opts, "sasl", 0)) {
         if (spice_server_set_sasl(spice_server, 1) == -1) {
@@ -920,8 +920,10 @@ int qemu_spice_add_display_interface(QXLInstance *qxlin, QemuConsole *con)
     return qemu_spice_add_interface(&qxlin->base);
 }
 
-static int qemu_spice_set_ticket(bool fail_if_conn, bool disconnect_if_conn)
+static int qemu_spice_set_ticket(bool fail_if_conn, bool disconnect_if_conn,
+                                 Error **errp)
 {
+    int ret;
     time_t lifetime, now = time(NULL);
     char *passwd;
 
@@ -935,26 +937,35 @@ static int qemu_spice_set_ticket(bool fail_if_conn, bool disconnect_if_conn)
         passwd = NULL;
         lifetime = 1;
     }
-    return spice_server_set_ticket(spice_server, passwd, lifetime,
-                                   fail_if_conn, disconnect_if_conn);
+    ret = spice_server_set_ticket(spice_server, passwd, lifetime,
+                                  fail_if_conn, disconnect_if_conn);
+    if (ret < 0) {
+        error_setg(errp, "Unable to set SPICE server ticket");
+        return -1;
+    }
+    return 0;
 }
 
 static int qemu_spice_set_passwd(const char *passwd,
-                                 bool fail_if_conn, bool disconnect_if_conn)
+                                 bool fail_if_conn, bool disconnect_if_conn,
+                                 Error **errp)
 {
     if (strcmp(auth, "spice") != 0) {
+        error_setg(errp, "SPICE authentication is disabled");
+        error_append_hint(errp,
+                          "To enable it use '-spice ...,password-secret=ID'");
         return -1;
     }
 
     g_free(auth_passwd);
     auth_passwd = g_strdup(passwd);
-    return qemu_spice_set_ticket(fail_if_conn, disconnect_if_conn);
+    return qemu_spice_set_ticket(fail_if_conn, disconnect_if_conn, errp);
 }
 
 static int qemu_spice_set_pw_expire(time_t expires)
 {
     auth_expires = expires;
-    return qemu_spice_set_ticket(false, false);
+    return qemu_spice_set_ticket(false, false, NULL);
 }
 
 static int qemu_spice_display_add_client(int csock, int skipauth, int tls)
diff --git a/ui/spice-module.c b/ui/spice-module.c
index 3222335872..7651c85885 100644
--- a/ui/spice-module.c
+++ b/ui/spice-module.c
@@ -45,14 +45,15 @@ static int qemu_spice_migrate_info_stub(const char *h, int p, int t,
 
 static int qemu_spice_set_passwd_stub(const char *passwd,
                                       bool fail_if_connected,
-                                      bool disconnect_if_connected)
+                                      bool disconnect_if_connected,
+                                      Error **errp)
 {
-    return -1;
+    g_assert_not_reached();
 }
 
 static int qemu_spice_set_pw_expire_stub(time_t expires)
 {
-    return -1;
+    g_assert_not_reached();
 }
 
 static int qemu_spice_display_add_client_stub(int csock, int skipauth,
diff --git a/ui/ui-qmp-cmds.c b/ui/ui-qmp-cmds.c
index b49b636152..1173c82cf7 100644
--- a/ui/ui-qmp-cmds.c
+++ b/ui/ui-qmp-cmds.c
@@ -31,15 +31,14 @@
 
 void qmp_set_password(SetPasswordOptions *opts, Error **errp)
 {
-    int rc;
-
     if (opts->protocol == DISPLAY_PROTOCOL_SPICE) {
         if (!qemu_using_spice(errp)) {
             return;
         }
-        rc = qemu_spice.set_passwd(opts->password,
-                opts->connected == SET_PASSWORD_ACTION_FAIL,
-                opts->connected == SET_PASSWORD_ACTION_DISCONNECT);
+        qemu_spice.set_passwd(opts->password,
+                              opts->connected == SET_PASSWORD_ACTION_FAIL,
+                              opts->connected == SET_PASSWORD_ACTION_DISCONNECT,
+                              errp);
     } else {
         assert(opts->protocol == DISPLAY_PROTOCOL_VNC);
         if (opts->connected != SET_PASSWORD_ACTION_KEEP) {
@@ -52,11 +51,7 @@ void qmp_set_password(SetPasswordOptions *opts, Error **errp)
          * Note that setting an empty password will not disable login
          * through this interface.
          */
-        rc = vnc_display_password(opts->u.vnc.display, opts->password);
-    }
-
-    if (rc != 0) {
-        error_setg(errp, "Could not set password");
+        vnc_display_password(opts->u.vnc.display, opts->password, errp);
     }
 }
 
@@ -107,9 +102,7 @@ void qmp_expire_password(ExpirePasswordOptions *opts, Error **errp)
 #ifdef CONFIG_VNC
 void qmp_change_vnc_password(const char *password, Error **errp)
 {
-    if (vnc_display_password(NULL, password) < 0) {
-        error_setg(errp, "Could not set password");
-    }
+    vnc_display_password(NULL, password, errp);
 }
 #endif
 
diff --git a/ui/vnc-stubs.c b/ui/vnc-stubs.c
index a96bc86236..5de9bf9d70 100644
--- a/ui/vnc-stubs.c
+++ b/ui/vnc-stubs.c
@@ -2,11 +2,11 @@
 #include "ui/console.h"
 #include "qapi/error.h"
 
-int vnc_display_password(const char *id, const char *password)
+int vnc_display_password(const char *id, const char *password, Error **errp)
 {
-    return -ENODEV;
+    g_assert_not_reached();
 }
 int vnc_display_pw_expire(const char *id, time_t expires)
 {
-    return -ENODEV;
+    g_assert_not_reached();
 };
diff --git a/ui/vnc.c b/ui/vnc.c
index daf5b01d34..8bf14cf9a7 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3526,16 +3526,20 @@ static void vnc_display_close(VncDisplay *vd)
 #endif
 }
 
-int vnc_display_password(const char *id, const char *password)
+int vnc_display_password(const char *id, const char *password, Error **errp)
 {
     VncDisplay *vd = vnc_display_find(id);
 
     if (!vd) {
+        error_setg(errp, "No VNC display is present");
+        error_append_hint(errp,
+                          "To enable it, use '-vnc ...'");
         return -EINVAL;
     }
     if (vd->auth == VNC_AUTH_NONE) {
-        error_printf_unless_qmp("If you want use passwords please enable "
-                                "password auth using '-vnc ${dpy},password'.\n");
+        error_setg(errp, "VNC password authentication is disabled");
+        error_append_hint(errp,
+                          "To enable it, use '-vnc ...,password-secret=ID'");
         return -EINVAL;
     }
 
-- 
2.53.0



  parent reply	other threads:[~2026-03-03 15:07 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-03 15:05 [PULL 00/27] Misc patches queue Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 01/27] scripts: detect another GPL license boilerplate variant Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 02/27] io: separate freeing of tasks from marking them as complete Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 03/27] io: fix cleanup for TLS I/O source data on cancellation Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 04/27] io: fix cleanup for websock " Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 05/27] docs: simplify DiamondRapids CPU docs Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 06/27] qemu-options: remove extraneous [] around arg values Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 07/27] include: define constant for early constructor priority Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 08/27] monitor: initialize global data from a constructor Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 09/27] system: unconditionally enable thread naming Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 10/27] util: fix race setting thread name on Win32 Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 11/27] util: expose qemu_thread_set_name Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 12/27] audio: make jackaudio use qemu_thread_set_name Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 13/27] util: set the name for the 'main' thread on Windows Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 14/27] util: add API to fetch the current thread name Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 15/27] util: introduce some API docs for logging APIs Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 16/27] util: avoid repeated prefix on incremental qemu_log calls Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 17/27] util/log: add missing error reporting in qemu_log_trylock_with_err Daniel P. Berrangé
2026-03-03 15:05 ` Daniel P. Berrangé [this message]
2026-03-03 15:05 ` [PULL 19/27] ui: remove redundant use of error_printf_unless_qmp() Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 20/27] monitor: remove redundant error_[v]printf_unless_qmp Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 21/27] monitor: refactor error_vprintf() Daniel P. Berrangé
2026-03-03 15:05 ` [PULL 22/27] monitor: move error_vprintf back to error-report.c Daniel P. Berrangé
2026-03-03 15:06 ` [PULL 23/27] util: fix interleaving of error & trace output Daniel P. Berrangé
2026-03-03 15:06 ` [PULL 24/27] util: don't skip error prefixes when QMP is active Daniel P. Berrangé
2026-03-03 15:06 ` [PULL 25/27] util: fix interleaving of error prefixes Daniel P. Berrangé
2026-03-03 15:06 ` [PULL 26/27] scripts/checkpatch: Fix MAINTAINERS update warning with --terse Daniel P. Berrangé
2026-03-03 15:06 ` [PULL 27/27] util/oslib-posix: increase memprealloc thread count to 32 Daniel P. Berrangé
2026-03-05 14:47 ` [PULL 00/27] Misc patches queue Peter Maydell
2026-03-05 15:15   ` Daniel P. Berrangé
2026-03-05 17:48     ` Daniel P. Berrangé
  -- strict thread matches above, loose matches on Subject: below --
2026-03-05 17:47 [PULL v2 " Daniel P. Berrangé
2026-03-05 17:47 ` [PULL 18/27] ui: add proper error reporting for password changes Daniel P. Berrangé

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260303150604.2402872-19-berrange@redhat.com \
    --to=berrange@redhat.com \
    --cc=armbru@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.