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