mirror of https://github.com/xemu-project/xemu.git
curses: wide char input support.
vnc: acl update, stall fix. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJchht0AAoJEEy22O7T6HE4ufcP/R4pUrdXIRVI6VyD4puBIGYQ wxyt2Lx7DXtc7nA3q4iBTAH0oCxWCiIqYRbxCbO8zrMd6FSUf8LxIq5rkVF4amHA G/EE6VE360to+hcF+y9uK4oQHq3X3JiVWkBqT/8zTjQb3GsL5MR7C0u5zq7+Jvvj gtETaH7cm4yYqBvZVQeAlnG0J9pkdTuCqJYJdCIbNwMwM4ogcEqvRikPWFKBnf9q 5O/yrP7K3eqLLGWOERUET6hacJyCGAnSRZIHuRwZ27bmlJ9NAjC48MD0zSCicJqK B9AvkICFMSgcfBxSbyVP45KHFqPasq65YWe7ixqBtsuBRNWDJh550dX49Ym1cOWB fonyjBnODqi/NU/nca4zmsWDbZScHVBk66MAfckJu9s6CTFqy2fVZYJKt1IASgta Ltk4ETWPzIuJLrDqGUUH8OhAynrmcAa6GCbSn5LADqvH1iabORpJDCCOgaAqRmm9 aYMayaQ0aEnmbHPTFBp2uyqFKnVmwE9ObTS5e7cTogH0noIZcwIkhDbSD+MV7lhy qvVFhkqzfSeTTS9wbVw+d3P8gaKjnrLuOCJFh6fWKj2s9Df41sSif1R4hDGOWsqX jYgxzZDGN3ss3SfVyZO0BX3FbS0U3FGuoVP0dpl7O3/lYDxUHHL8srbqlwK4ofuq c6yue+7xfNdgwByLtm+r =/2zN -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/ui-20190311-v2-pull-request' into staging curses: wide char input support. vnc: acl update, stall fix. # gpg: Signature made Mon 11 Mar 2019 08:25:24 GMT # gpg: using RSA key 4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full] # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full] # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full] # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/ui-20190311-v2-pull-request: monitor: deprecate acl_show, acl_reset, acl_policy, acl_add, acl_remove vnc: allow specifying a custom authorization object name vnc: fix update stalls curses: support wide input Reduce curses escdelay from 1s to 25ms Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
79d8b1dc5b
23
monitor.c
23
monitor.c
|
@ -2032,6 +2032,19 @@ static QAuthZList *find_auth(Monitor *mon, const char *name)
|
|||
return QAUTHZ_LIST(obj);
|
||||
}
|
||||
|
||||
static bool warn_acl;
|
||||
static void hmp_warn_acl(void)
|
||||
{
|
||||
if (warn_acl) {
|
||||
return;
|
||||
}
|
||||
error_report("The acl_show, acl_reset, acl_policy, acl_add, acl_remove "
|
||||
"commands are deprecated with no replacement. Authorization "
|
||||
"for VNC should be performed using the pluggable QAuthZ "
|
||||
"objects");
|
||||
warn_acl = true;
|
||||
}
|
||||
|
||||
static void hmp_acl_show(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *aclname = qdict_get_str(qdict, "aclname");
|
||||
|
@ -2039,6 +2052,8 @@ static void hmp_acl_show(Monitor *mon, const QDict *qdict)
|
|||
QAuthZListRuleList *rules;
|
||||
size_t i = 0;
|
||||
|
||||
hmp_warn_acl();
|
||||
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
|
@ -2062,6 +2077,8 @@ static void hmp_acl_reset(Monitor *mon, const QDict *qdict)
|
|||
const char *aclname = qdict_get_str(qdict, "aclname");
|
||||
QAuthZList *auth = find_auth(mon, aclname);
|
||||
|
||||
hmp_warn_acl();
|
||||
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
|
@ -2080,6 +2097,8 @@ static void hmp_acl_policy(Monitor *mon, const QDict *qdict)
|
|||
int val;
|
||||
Error *err = NULL;
|
||||
|
||||
hmp_warn_acl();
|
||||
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
|
@ -2124,6 +2143,8 @@ static void hmp_acl_add(Monitor *mon, const QDict *qdict)
|
|||
QAuthZListFormat format;
|
||||
size_t i = 0;
|
||||
|
||||
hmp_warn_acl();
|
||||
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
|
@ -2169,6 +2190,8 @@ static void hmp_acl_remove(Monitor *mon, const QDict *qdict)
|
|||
QAuthZList *auth = find_auth(mon, aclname);
|
||||
ssize_t i = 0;
|
||||
|
||||
hmp_warn_acl();
|
||||
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -60,6 +60,11 @@ Support for invalid topologies will be removed, the user must ensure
|
|||
topologies described with -smp include all possible cpus, i.e.
|
||||
@math{@var{sockets} * @var{cores} * @var{threads} = @var{maxcpus}}.
|
||||
|
||||
@subsection -vnc acl (since 4.0.0)
|
||||
|
||||
The @code{acl} option to the @code{-vnc} argument has been replaced
|
||||
by the @code{tls-authz} and @code{sasl-authz} options.
|
||||
|
||||
@section QEMU Machine Protocol (QMP) commands
|
||||
|
||||
@subsection block-dirty-bitmap-add "autoload" parameter (since 2.12.0)
|
||||
|
@ -99,6 +104,12 @@ The @option{[hub_id name]} parameter tuple of the 'hostfwd_add' and
|
|||
Use ``device_add'' for hotplugging vCPUs instead of ``cpu-add''. See
|
||||
documentation of ``query-hotpluggable-cpus'' for additional details.
|
||||
|
||||
@subsection acl_show, acl_reset, acl_policy, acl_add, acl_remove (since 4.0.0)
|
||||
|
||||
The ``acl_show'', ``acl_reset'', ``acl_policy'', ``acl_add'', and
|
||||
``acl_remove'' commands are deprecated with no replacement. Authorization
|
||||
for VNC should be performed using the pluggable QAuthZ objects.
|
||||
|
||||
@section System emulator devices
|
||||
|
||||
@subsection bluetooth (since 3.1)
|
||||
|
|
|
@ -1624,6 +1624,14 @@ will cause the VNC server socket to enable the VeNCrypt auth
|
|||
mechanism. The credentials should have been previously created
|
||||
using the @option{-object tls-creds} argument.
|
||||
|
||||
@item tls-authz=@var{ID}
|
||||
|
||||
Provides the ID of the QAuthZ authorization object against which
|
||||
the client's x509 distinguished name will validated. This object is
|
||||
only resolved at time of use, so can be deleted and recreated on the
|
||||
fly while the VNC server is active. If missing, it will default
|
||||
to denying access.
|
||||
|
||||
@item sasl
|
||||
|
||||
Require that the client use SASL to authenticate with the VNC server.
|
||||
|
@ -1639,18 +1647,25 @@ ensures a data encryption preventing compromise of authentication
|
|||
credentials. See the @ref{vnc_security} section for details on using
|
||||
SASL authentication.
|
||||
|
||||
@item sasl-authz=@var{ID}
|
||||
|
||||
Provides the ID of the QAuthZ authorization object against which
|
||||
the client's SASL username will validated. This object is
|
||||
only resolved at time of use, so can be deleted and recreated on the
|
||||
fly while the VNC server is active. If missing, it will default
|
||||
to denying access.
|
||||
|
||||
@item acl
|
||||
|
||||
Turn on access control lists for checking of the x509 client certificate
|
||||
and SASL party. For x509 certs, the ACL check is made against the
|
||||
certificate's distinguished name. This is something that looks like
|
||||
@code{C=GB,O=ACME,L=Boston,CN=bob}. For SASL party, the ACL check is
|
||||
made against the username, which depending on the SASL plugin, may
|
||||
include a realm component, eg @code{bob} or @code{bob@@EXAMPLE.COM}.
|
||||
When the @option{acl} flag is set, the initial access list will be
|
||||
empty, with a @code{deny} policy. Thus no one will be allowed to
|
||||
use the VNC server until the ACLs have been loaded. This can be
|
||||
achieved using the @code{acl} monitor command.
|
||||
Legacy method for enabling authorization of clients against the
|
||||
x509 distinguished name and SASL username. It results in the creation
|
||||
of two @code{authz-list} objects with IDs of @code{vnc.username} and
|
||||
@code{vnc.x509dname}. The rules for these objects must be configured
|
||||
with the HMP ACL commands.
|
||||
|
||||
This option is deprecated and should no longer be used. The new
|
||||
@option{sasl-authz} and @option{tls-authz} options are a
|
||||
replacement.
|
||||
|
||||
@item lossy
|
||||
|
||||
|
|
79
ui/curses.c
79
ui/curses.c
|
@ -42,6 +42,12 @@
|
|||
#define FONT_HEIGHT 16
|
||||
#define FONT_WIDTH 8
|
||||
|
||||
enum maybe_keycode {
|
||||
CURSES_KEYCODE,
|
||||
CURSES_CHAR,
|
||||
CURSES_CHAR_OR_KEYCODE,
|
||||
};
|
||||
|
||||
static DisplayChangeListener *dcl;
|
||||
static console_ch_t screen[160 * 100];
|
||||
static WINDOW *screenpad = NULL;
|
||||
|
@ -194,9 +200,54 @@ static void curses_cursor_position(DisplayChangeListener *dcl,
|
|||
|
||||
static kbd_layout_t *kbd_layout = NULL;
|
||||
|
||||
static wint_t console_getch(enum maybe_keycode *maybe_keycode)
|
||||
{
|
||||
wint_t ret;
|
||||
switch (get_wch(&ret)) {
|
||||
case KEY_CODE_YES:
|
||||
*maybe_keycode = CURSES_KEYCODE;
|
||||
break;
|
||||
case OK:
|
||||
*maybe_keycode = CURSES_CHAR;
|
||||
break;
|
||||
case ERR:
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int curses2foo(const int _curses2foo[], const int _curseskey2foo[],
|
||||
int chr, enum maybe_keycode maybe_keycode)
|
||||
{
|
||||
int ret = -1;
|
||||
if (maybe_keycode == CURSES_CHAR) {
|
||||
if (chr < CURSES_CHARS) {
|
||||
ret = _curses2foo[chr];
|
||||
}
|
||||
} else {
|
||||
if (chr < CURSES_KEYS) {
|
||||
ret = _curseskey2foo[chr];
|
||||
}
|
||||
if (ret == -1 && maybe_keycode == CURSES_CHAR_OR_KEYCODE &&
|
||||
chr < CURSES_CHARS) {
|
||||
ret = _curses2foo[chr];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define curses2keycode(chr, maybe_keycode) \
|
||||
curses2foo(_curses2keycode, _curseskey2keycode, chr, maybe_keycode)
|
||||
#define curses2keysym(chr, maybe_keycode) \
|
||||
curses2foo(_curses2keysym, _curseskey2keysym, chr, maybe_keycode)
|
||||
#define curses2qemu(chr, maybe_keycode) \
|
||||
curses2foo(_curses2qemu, _curseskey2qemu, chr, maybe_keycode)
|
||||
|
||||
static void curses_refresh(DisplayChangeListener *dcl)
|
||||
{
|
||||
int chr, keysym, keycode, keycode_alt;
|
||||
enum maybe_keycode maybe_keycode;
|
||||
|
||||
curses_winch_check();
|
||||
|
||||
|
@ -212,14 +263,14 @@ static void curses_refresh(DisplayChangeListener *dcl)
|
|||
|
||||
while (1) {
|
||||
/* while there are any pending key strokes to process */
|
||||
chr = getch();
|
||||
chr = console_getch(&maybe_keycode);
|
||||
|
||||
if (chr == ERR)
|
||||
if (chr == -1)
|
||||
break;
|
||||
|
||||
#ifdef KEY_RESIZE
|
||||
/* this shouldn't occur when we use a custom SIGWINCH handler */
|
||||
if (chr == KEY_RESIZE) {
|
||||
if (maybe_keycode != CURSES_CHAR && chr == KEY_RESIZE) {
|
||||
clear();
|
||||
refresh();
|
||||
curses_calc_pad();
|
||||
|
@ -228,17 +279,19 @@ static void curses_refresh(DisplayChangeListener *dcl)
|
|||
}
|
||||
#endif
|
||||
|
||||
keycode = curses2keycode[chr];
|
||||
keycode = curses2keycode(chr, maybe_keycode);
|
||||
keycode_alt = 0;
|
||||
|
||||
/* alt key */
|
||||
/* alt or esc key */
|
||||
if (keycode == 1) {
|
||||
int nextchr = getch();
|
||||
enum maybe_keycode next_maybe_keycode;
|
||||
int nextchr = console_getch(&next_maybe_keycode);
|
||||
|
||||
if (nextchr != ERR) {
|
||||
if (nextchr != -1) {
|
||||
chr = nextchr;
|
||||
maybe_keycode = next_maybe_keycode;
|
||||
keycode_alt = ALT;
|
||||
keycode = curses2keycode[chr];
|
||||
keycode = curses2keycode(chr, maybe_keycode);
|
||||
|
||||
if (keycode != -1) {
|
||||
keycode |= ALT;
|
||||
|
@ -258,9 +311,7 @@ static void curses_refresh(DisplayChangeListener *dcl)
|
|||
}
|
||||
|
||||
if (kbd_layout) {
|
||||
keysym = -1;
|
||||
if (chr < CURSES_KEYS)
|
||||
keysym = curses2keysym[chr];
|
||||
keysym = curses2keysym(chr, maybe_keycode);
|
||||
|
||||
if (keysym == -1) {
|
||||
if (chr < ' ') {
|
||||
|
@ -326,10 +377,7 @@ static void curses_refresh(DisplayChangeListener *dcl)
|
|||
qemu_input_event_send_key_delay(0);
|
||||
}
|
||||
} else {
|
||||
keysym = -1;
|
||||
if (chr < CURSES_KEYS) {
|
||||
keysym = curses2qemu[chr];
|
||||
}
|
||||
keysym = curses2qemu(chr, maybe_keycode);
|
||||
if (keysym == -1)
|
||||
keysym = chr;
|
||||
|
||||
|
@ -361,6 +409,7 @@ static void curses_setup(void)
|
|||
initscr(); noecho(); intrflush(stdscr, FALSE);
|
||||
nodelay(stdscr, TRUE); nonl(); keypad(stdscr, TRUE);
|
||||
start_color(); raw(); scrollok(stdscr, FALSE);
|
||||
set_escdelay(25);
|
||||
|
||||
/* Make color pair to match color format (3bits bg:3bits fg) */
|
||||
for (i = 0; i < 64; i++) {
|
||||
|
|
113
ui/curses_keys.h
113
ui/curses_keys.h
|
@ -49,22 +49,28 @@
|
|||
/* curses won't detect a Control + Alt + 1, so use Alt + 1 */
|
||||
#define QEMU_KEY_CONSOLE0 (2 | ALT) /* (curses2keycode['1'] | ALT) */
|
||||
|
||||
#define CURSES_CHARS 0x100 /* Support latin1 only */
|
||||
#define CURSES_KEYS KEY_MAX /* KEY_MAX defined in <curses.h> */
|
||||
|
||||
static const int curses2keysym[CURSES_KEYS] = {
|
||||
[0 ... (CURSES_KEYS - 1)] = -1,
|
||||
static const int _curses2keysym[CURSES_CHARS] = {
|
||||
[0 ... (CURSES_CHARS - 1)] = -1,
|
||||
|
||||
[0x7f] = KEY_BACKSPACE,
|
||||
['\r'] = KEY_ENTER,
|
||||
['\n'] = KEY_ENTER,
|
||||
[27] = 27,
|
||||
};
|
||||
|
||||
static const int _curseskey2keysym[CURSES_KEYS] = {
|
||||
[0 ... (CURSES_KEYS - 1)] = -1,
|
||||
|
||||
[KEY_BTAB] = '\t' | KEYSYM_SHIFT,
|
||||
[KEY_SPREVIOUS] = KEY_PPAGE | KEYSYM_SHIFT,
|
||||
[KEY_SNEXT] = KEY_NPAGE | KEYSYM_SHIFT,
|
||||
};
|
||||
|
||||
static const int curses2keycode[CURSES_KEYS] = {
|
||||
[0 ... (CURSES_KEYS - 1)] = -1,
|
||||
static const int _curses2keycode[CURSES_CHARS] = {
|
||||
[0 ... (CURSES_CHARS - 1)] = -1,
|
||||
|
||||
[0x01b] = 1, /* Escape */
|
||||
['1'] = 2,
|
||||
|
@ -80,7 +86,6 @@ static const int curses2keycode[CURSES_KEYS] = {
|
|||
['-'] = 12,
|
||||
['='] = 13,
|
||||
[0x07f] = 14, /* Backspace */
|
||||
[KEY_BACKSPACE] = 14, /* Backspace */
|
||||
|
||||
['\t'] = 15, /* Tab */
|
||||
['q'] = 16,
|
||||
|
@ -97,7 +102,6 @@ static const int curses2keycode[CURSES_KEYS] = {
|
|||
[']'] = 27,
|
||||
['\n'] = 28, /* Return */
|
||||
['\r'] = 28, /* Return */
|
||||
[KEY_ENTER] = 28, /* Return */
|
||||
|
||||
['a'] = 30,
|
||||
['s'] = 31,
|
||||
|
@ -126,33 +130,6 @@ static const int curses2keycode[CURSES_KEYS] = {
|
|||
|
||||
[' '] = 57,
|
||||
|
||||
[KEY_F(1)] = 59, /* Function Key 1 */
|
||||
[KEY_F(2)] = 60, /* Function Key 2 */
|
||||
[KEY_F(3)] = 61, /* Function Key 3 */
|
||||
[KEY_F(4)] = 62, /* Function Key 4 */
|
||||
[KEY_F(5)] = 63, /* Function Key 5 */
|
||||
[KEY_F(6)] = 64, /* Function Key 6 */
|
||||
[KEY_F(7)] = 65, /* Function Key 7 */
|
||||
[KEY_F(8)] = 66, /* Function Key 8 */
|
||||
[KEY_F(9)] = 67, /* Function Key 9 */
|
||||
[KEY_F(10)] = 68, /* Function Key 10 */
|
||||
[KEY_F(11)] = 87, /* Function Key 11 */
|
||||
[KEY_F(12)] = 88, /* Function Key 12 */
|
||||
|
||||
[KEY_HOME] = 71 | GREY, /* Home */
|
||||
[KEY_UP] = 72 | GREY, /* Up Arrow */
|
||||
[KEY_PPAGE] = 73 | GREY, /* Page Up */
|
||||
[KEY_LEFT] = 75 | GREY, /* Left Arrow */
|
||||
[KEY_RIGHT] = 77 | GREY, /* Right Arrow */
|
||||
[KEY_END] = 79 | GREY, /* End */
|
||||
[KEY_DOWN] = 80 | GREY, /* Down Arrow */
|
||||
[KEY_NPAGE] = 81 | GREY, /* Page Down */
|
||||
[KEY_IC] = 82 | GREY, /* Insert */
|
||||
[KEY_DC] = 83 | GREY, /* Delete */
|
||||
|
||||
[KEY_SPREVIOUS] = 73 | GREY | SHIFT, /* Shift + Page Up */
|
||||
[KEY_SNEXT] = 81 | GREY | SHIFT, /* Shift + Page Down */
|
||||
|
||||
['!'] = 2 | SHIFT,
|
||||
['@'] = 3 | SHIFT,
|
||||
['#'] = 4 | SHIFT,
|
||||
|
@ -166,7 +143,6 @@ static const int curses2keycode[CURSES_KEYS] = {
|
|||
['_'] = 12 | SHIFT,
|
||||
['+'] = 13 | SHIFT,
|
||||
|
||||
[KEY_BTAB] = 15 | SHIFT, /* Shift + Tab */
|
||||
['Q'] = 16 | SHIFT,
|
||||
['W'] = 17 | SHIFT,
|
||||
['E'] = 18 | SHIFT,
|
||||
|
@ -205,19 +181,6 @@ static const int curses2keycode[CURSES_KEYS] = {
|
|||
['>'] = 52 | SHIFT,
|
||||
['?'] = 53 | SHIFT,
|
||||
|
||||
[KEY_F(13)] = 59 | SHIFT, /* Shift + Function Key 1 */
|
||||
[KEY_F(14)] = 60 | SHIFT, /* Shift + Function Key 2 */
|
||||
[KEY_F(15)] = 61 | SHIFT, /* Shift + Function Key 3 */
|
||||
[KEY_F(16)] = 62 | SHIFT, /* Shift + Function Key 4 */
|
||||
[KEY_F(17)] = 63 | SHIFT, /* Shift + Function Key 5 */
|
||||
[KEY_F(18)] = 64 | SHIFT, /* Shift + Function Key 6 */
|
||||
[KEY_F(19)] = 65 | SHIFT, /* Shift + Function Key 7 */
|
||||
[KEY_F(20)] = 66 | SHIFT, /* Shift + Function Key 8 */
|
||||
[KEY_F(21)] = 67 | SHIFT, /* Shift + Function Key 9 */
|
||||
[KEY_F(22)] = 68 | SHIFT, /* Shift + Function Key 10 */
|
||||
[KEY_F(23)] = 69 | SHIFT, /* Shift + Function Key 11 */
|
||||
[KEY_F(24)] = 70 | SHIFT, /* Shift + Function Key 12 */
|
||||
|
||||
['Q' - '@'] = 16 | CNTRL, /* Control + q */
|
||||
['W' - '@'] = 17 | CNTRL, /* Control + w */
|
||||
['E' - '@'] = 18 | CNTRL, /* Control + e */
|
||||
|
@ -249,13 +212,67 @@ static const int curses2keycode[CURSES_KEYS] = {
|
|||
|
||||
};
|
||||
|
||||
static const int curses2qemu[CURSES_KEYS] = {
|
||||
static const int _curseskey2keycode[CURSES_KEYS] = {
|
||||
[0 ... (CURSES_KEYS - 1)] = -1,
|
||||
|
||||
[KEY_BACKSPACE] = 14, /* Backspace */
|
||||
|
||||
[KEY_ENTER] = 28, /* Return */
|
||||
|
||||
[KEY_F(1)] = 59, /* Function Key 1 */
|
||||
[KEY_F(2)] = 60, /* Function Key 2 */
|
||||
[KEY_F(3)] = 61, /* Function Key 3 */
|
||||
[KEY_F(4)] = 62, /* Function Key 4 */
|
||||
[KEY_F(5)] = 63, /* Function Key 5 */
|
||||
[KEY_F(6)] = 64, /* Function Key 6 */
|
||||
[KEY_F(7)] = 65, /* Function Key 7 */
|
||||
[KEY_F(8)] = 66, /* Function Key 8 */
|
||||
[KEY_F(9)] = 67, /* Function Key 9 */
|
||||
[KEY_F(10)] = 68, /* Function Key 10 */
|
||||
[KEY_F(11)] = 87, /* Function Key 11 */
|
||||
[KEY_F(12)] = 88, /* Function Key 12 */
|
||||
|
||||
[KEY_HOME] = 71 | GREY, /* Home */
|
||||
[KEY_UP] = 72 | GREY, /* Up Arrow */
|
||||
[KEY_PPAGE] = 73 | GREY, /* Page Up */
|
||||
[KEY_LEFT] = 75 | GREY, /* Left Arrow */
|
||||
[KEY_RIGHT] = 77 | GREY, /* Right Arrow */
|
||||
[KEY_END] = 79 | GREY, /* End */
|
||||
[KEY_DOWN] = 80 | GREY, /* Down Arrow */
|
||||
[KEY_NPAGE] = 81 | GREY, /* Page Down */
|
||||
[KEY_IC] = 82 | GREY, /* Insert */
|
||||
[KEY_DC] = 83 | GREY, /* Delete */
|
||||
|
||||
[KEY_SPREVIOUS] = 73 | GREY | SHIFT, /* Shift + Page Up */
|
||||
[KEY_SNEXT] = 81 | GREY | SHIFT, /* Shift + Page Down */
|
||||
|
||||
[KEY_BTAB] = 15 | SHIFT, /* Shift + Tab */
|
||||
|
||||
[KEY_F(13)] = 59 | SHIFT, /* Shift + Function Key 1 */
|
||||
[KEY_F(14)] = 60 | SHIFT, /* Shift + Function Key 2 */
|
||||
[KEY_F(15)] = 61 | SHIFT, /* Shift + Function Key 3 */
|
||||
[KEY_F(16)] = 62 | SHIFT, /* Shift + Function Key 4 */
|
||||
[KEY_F(17)] = 63 | SHIFT, /* Shift + Function Key 5 */
|
||||
[KEY_F(18)] = 64 | SHIFT, /* Shift + Function Key 6 */
|
||||
[KEY_F(19)] = 65 | SHIFT, /* Shift + Function Key 7 */
|
||||
[KEY_F(20)] = 66 | SHIFT, /* Shift + Function Key 8 */
|
||||
[KEY_F(21)] = 67 | SHIFT, /* Shift + Function Key 9 */
|
||||
[KEY_F(22)] = 68 | SHIFT, /* Shift + Function Key 10 */
|
||||
[KEY_F(23)] = 69 | SHIFT, /* Shift + Function Key 11 */
|
||||
[KEY_F(24)] = 70 | SHIFT, /* Shift + Function Key 12 */
|
||||
};
|
||||
|
||||
static const int _curses2qemu[CURSES_CHARS] = {
|
||||
[0 ... (CURSES_CHARS - 1)] = -1,
|
||||
|
||||
['\n'] = '\n',
|
||||
['\r'] = '\n',
|
||||
|
||||
[0x07f] = QEMU_KEY_BACKSPACE,
|
||||
};
|
||||
|
||||
static const int _curseskey2qemu[CURSES_KEYS] = {
|
||||
[0 ... (CURSES_KEYS - 1)] = -1,
|
||||
|
||||
[KEY_DOWN] = QEMU_KEY_DOWN,
|
||||
[KEY_UP] = QEMU_KEY_UP,
|
||||
|
|
64
ui/vnc.c
64
ui/vnc.c
|
@ -700,6 +700,12 @@ static void vnc_abort_display_jobs(VncDisplay *vd)
|
|||
}
|
||||
QTAILQ_FOREACH(vs, &vd->clients, next) {
|
||||
vnc_lock_output(vs);
|
||||
if (vs->update == VNC_STATE_UPDATE_NONE &&
|
||||
vs->job_update != VNC_STATE_UPDATE_NONE) {
|
||||
/* job aborted before completion */
|
||||
vs->update = vs->job_update;
|
||||
vs->job_update = VNC_STATE_UPDATE_NONE;
|
||||
}
|
||||
vs->abort = false;
|
||||
vnc_unlock_output(vs);
|
||||
}
|
||||
|
@ -3357,6 +3363,12 @@ static QemuOptsList qemu_vnc_opts = {
|
|||
},{
|
||||
.name = "acl",
|
||||
.type = QEMU_OPT_BOOL,
|
||||
},{
|
||||
.name = "tls-authz",
|
||||
.type = QEMU_OPT_STRING,
|
||||
},{
|
||||
.name = "sasl-authz",
|
||||
.type = QEMU_OPT_STRING,
|
||||
},{
|
||||
.name = "lossy",
|
||||
.type = QEMU_OPT_BOOL,
|
||||
|
@ -3796,6 +3808,8 @@ void vnc_display_open(const char *id, Error **errp)
|
|||
const char *credid;
|
||||
bool sasl = false;
|
||||
int acl = 0;
|
||||
const char *tlsauthz;
|
||||
const char *saslauthz;
|
||||
int lock_key_sync = 1;
|
||||
int key_delay_ms;
|
||||
|
||||
|
@ -3867,7 +3881,33 @@ void vnc_display_open(const char *id, Error **errp)
|
|||
goto fail;
|
||||
}
|
||||
}
|
||||
if (qemu_opt_get(opts, "acl")) {
|
||||
error_report("The 'acl' option to -vnc is deprecated. "
|
||||
"Please use the 'tls-authz' and 'sasl-authz' "
|
||||
"options instead");
|
||||
}
|
||||
acl = qemu_opt_get_bool(opts, "acl", false);
|
||||
tlsauthz = qemu_opt_get(opts, "tls-authz");
|
||||
if (acl && tlsauthz) {
|
||||
error_setg(errp, "'acl' option is mutually exclusive with the "
|
||||
"'tls-authz' option");
|
||||
goto fail;
|
||||
}
|
||||
if (tlsauthz && !vd->tlscreds) {
|
||||
error_setg(errp, "'tls-authz' provided but TLS is not enabled");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
saslauthz = qemu_opt_get(opts, "sasl-authz");
|
||||
if (acl && saslauthz) {
|
||||
error_setg(errp, "'acl' option is mutually exclusive with the "
|
||||
"'sasl-authz' option");
|
||||
goto fail;
|
||||
}
|
||||
if (saslauthz && !sasl) {
|
||||
error_setg(errp, "'sasl-authz' provided but SASL auth is not enabled");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
share = qemu_opt_get(opts, "share");
|
||||
if (share) {
|
||||
|
@ -3897,7 +3937,9 @@ void vnc_display_open(const char *id, Error **errp)
|
|||
vd->non_adaptive = true;
|
||||
}
|
||||
|
||||
if (acl) {
|
||||
if (tlsauthz) {
|
||||
vd->tlsauthzid = g_strdup(tlsauthz);
|
||||
} else if (acl) {
|
||||
if (strcmp(vd->id, "default") == 0) {
|
||||
vd->tlsauthzid = g_strdup("vnc.x509dname");
|
||||
} else {
|
||||
|
@ -3908,15 +3950,19 @@ void vnc_display_open(const char *id, Error **errp)
|
|||
&error_abort));
|
||||
}
|
||||
#ifdef CONFIG_VNC_SASL
|
||||
if (acl && sasl) {
|
||||
if (strcmp(vd->id, "default") == 0) {
|
||||
vd->sasl.authzid = g_strdup("vnc.username");
|
||||
} else {
|
||||
vd->sasl.authzid = g_strdup_printf("vnc.%s.username", vd->id);
|
||||
if (sasl) {
|
||||
if (saslauthz) {
|
||||
vd->sasl.authzid = g_strdup(saslauthz);
|
||||
} else if (acl) {
|
||||
if (strcmp(vd->id, "default") == 0) {
|
||||
vd->sasl.authzid = g_strdup("vnc.username");
|
||||
} else {
|
||||
vd->sasl.authzid = g_strdup_printf("vnc.%s.username", vd->id);
|
||||
}
|
||||
vd->sasl.authz = QAUTHZ(qauthz_list_new(vd->sasl.authzid,
|
||||
QAUTHZ_LIST_POLICY_DENY,
|
||||
&error_abort));
|
||||
}
|
||||
vd->sasl.authz = QAUTHZ(qauthz_list_new(vd->sasl.authzid,
|
||||
QAUTHZ_LIST_POLICY_DENY,
|
||||
&error_abort));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue