xref: /openbmc/qemu/ui/ui-qmp-cmds.c (revision 31afe04586efeccb80cc36ffafcd0e32a3245ffb)
1  /*
2   * QMP commands related to UI
3   *
4   * Copyright IBM, Corp. 2011
5   *
6   * Authors:
7   *  Anthony Liguori   <aliguori@us.ibm.com>
8   *
9   * This work is licensed under the terms of the GNU GPL, version 2.  See
10   * the COPYING file in the top-level directory.
11   *
12   * Contributions after 2012-01-13 are licensed under the terms of the
13   * GNU GPL, version 2 or (at your option) any later version.
14   */
15  
16  #include "qemu/osdep.h"
17  #include "monitor/qmp-helpers.h"
18  #include "qapi/qapi-commands-ui.h"
19  #include "qapi/qmp/qerror.h"
20  #include "qemu/cutils.h"
21  #include "ui/console.h"
22  #include "ui/dbus-display.h"
23  #include "ui/qemu-spice.h"
24  
25  void qmp_set_password(SetPasswordOptions *opts, Error **errp)
26  {
27      int rc;
28  
29      if (opts->protocol == DISPLAY_PROTOCOL_SPICE) {
30          if (!qemu_using_spice(errp)) {
31              return;
32          }
33          rc = qemu_spice.set_passwd(opts->password,
34                  opts->connected == SET_PASSWORD_ACTION_FAIL,
35                  opts->connected == SET_PASSWORD_ACTION_DISCONNECT);
36      } else {
37          assert(opts->protocol == DISPLAY_PROTOCOL_VNC);
38          if (opts->connected != SET_PASSWORD_ACTION_KEEP) {
39              /* vnc supports "connected=keep" only */
40              error_setg(errp, QERR_INVALID_PARAMETER, "connected");
41              return;
42          }
43          /*
44           * Note that setting an empty password will not disable login
45           * through this interface.
46           */
47          rc = vnc_display_password(opts->u.vnc.display, opts->password);
48      }
49  
50      if (rc != 0) {
51          error_setg(errp, "Could not set password");
52      }
53  }
54  
55  void qmp_expire_password(ExpirePasswordOptions *opts, Error **errp)
56  {
57      time_t when;
58      int rc;
59      const char *whenstr = opts->time;
60      const char *numstr = NULL;
61      uint64_t num;
62  
63      if (strcmp(whenstr, "now") == 0) {
64          when = 0;
65      } else if (strcmp(whenstr, "never") == 0) {
66          when = TIME_MAX;
67      } else if (whenstr[0] == '+') {
68          when = time(NULL);
69          numstr = whenstr + 1;
70      } else {
71          when = 0;
72          numstr = whenstr;
73      }
74  
75      if (numstr) {
76          if (qemu_strtou64(numstr, NULL, 10, &num) < 0) {
77              error_setg(errp, "Parameter 'time' doesn't take value '%s'",
78                         whenstr);
79              return;
80          }
81          when += num;
82      }
83  
84      if (opts->protocol == DISPLAY_PROTOCOL_SPICE) {
85          if (!qemu_using_spice(errp)) {
86              return;
87          }
88          rc = qemu_spice.set_pw_expire(when);
89      } else {
90          assert(opts->protocol == DISPLAY_PROTOCOL_VNC);
91          rc = vnc_display_pw_expire(opts->u.vnc.display, when);
92      }
93  
94      if (rc != 0) {
95          error_setg(errp, "Could not set password expire time");
96      }
97  }
98  
99  #ifdef CONFIG_VNC
100  void qmp_change_vnc_password(const char *password, Error **errp)
101  {
102      if (vnc_display_password(NULL, password) < 0) {
103          error_setg(errp, "Could not set password");
104      }
105  }
106  #endif
107  
108  bool qmp_add_client_spice(int fd, bool has_skipauth, bool skipauth,
109                            bool has_tls, bool tls, Error **errp)
110  {
111      if (!qemu_using_spice(errp)) {
112          return false;
113      }
114      skipauth = has_skipauth ? skipauth : false;
115      tls = has_tls ? tls : false;
116      if (qemu_spice.display_add_client(fd, skipauth, tls) < 0) {
117          error_setg(errp, "spice failed to add client");
118          return false;
119      }
120      return true;
121  }
122  
123  #ifdef CONFIG_VNC
124  bool qmp_add_client_vnc(int fd, bool has_skipauth, bool skipauth,
125                          bool has_tls, bool tls, Error **errp)
126  {
127      skipauth = has_skipauth ? skipauth : false;
128      vnc_display_add_client(NULL, fd, skipauth);
129      return true;
130  }
131  #endif
132  
133  #ifdef CONFIG_DBUS_DISPLAY
134  bool qmp_add_client_dbus_display(int fd, bool has_skipauth, bool skipauth,
135                                   bool has_tls, bool tls, Error **errp)
136  {
137      if (!qemu_using_dbus_display(errp)) {
138          return false;
139      }
140      if (!qemu_dbus_display.add_client(fd, errp)) {
141          return false;
142      }
143      return true;
144  }
145  #endif
146  
147  void qmp_display_reload(DisplayReloadOptions *arg, Error **errp)
148  {
149      switch (arg->type) {
150      case DISPLAY_RELOAD_TYPE_VNC:
151  #ifdef CONFIG_VNC
152          if (arg->u.vnc.has_tls_certs && arg->u.vnc.tls_certs) {
153              vnc_display_reload_certs(NULL, errp);
154          }
155  #else
156          error_setg(errp, "vnc is invalid, missing 'CONFIG_VNC'");
157  #endif
158          break;
159      default:
160          abort();
161      }
162  }
163  
164  void qmp_display_update(DisplayUpdateOptions *arg, Error **errp)
165  {
166      switch (arg->type) {
167      case DISPLAY_UPDATE_TYPE_VNC:
168  #ifdef CONFIG_VNC
169          vnc_display_update(&arg->u.vnc, errp);
170  #else
171          error_setg(errp, "vnc is invalid, missing 'CONFIG_VNC'");
172  #endif
173          break;
174      default:
175          abort();
176      }
177  }
178  
179  void qmp_client_migrate_info(const char *protocol, const char *hostname,
180                               bool has_port, int64_t port,
181                               bool has_tls_port, int64_t tls_port,
182                               const char *cert_subject,
183                               Error **errp)
184  {
185      if (strcmp(protocol, "spice") == 0) {
186          if (!qemu_using_spice(errp)) {
187              return;
188          }
189  
190          if (!has_port && !has_tls_port) {
191              error_setg(errp, QERR_MISSING_PARAMETER, "port/tls-port");
192              return;
193          }
194  
195          if (qemu_spice.migrate_info(hostname,
196                                      has_port ? port : -1,
197                                      has_tls_port ? tls_port : -1,
198                                      cert_subject)) {
199              error_setg(errp, "Could not set up display for migration");
200              return;
201          }
202          return;
203      }
204  
205      error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "protocol", "'spice'");
206  }
207