diff options
author | Eamon Walsh <ewalsh@tycho.nsa.gov> | 2011-07-29 15:23:17 -0400 |
---|---|---|
committer | Eamon Walsh <ewalsh@tycho.nsa.gov> | 2011-07-29 15:23:17 -0400 |
commit | 90c24e928f75339767fc76df12ba816cf1ab7795 (patch) | |
tree | 3d3c40b9094169f8e9686e4b3aa235bf93dc683b /src | |
parent | 6c39b8b1adb8da803ff85cfd492129173340abbc (diff) |
Add dynamic guest SAK registration to the server.
Guests will be able to register a SAK code which is mapped to a key
combination. When the key combination is pressed, the server will
switch the display to the guest that has registered. Registration of
a SAK is subject to a permission check.
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/display.c | 58 | ||||
-rw-r--r-- | src/display.h | 1 | ||||
-rw-r--r-- | src/input.c | 12 | ||||
-rw-r--r-- | src/sak.c | 74 | ||||
-rw-r--r-- | src/sak.h | 54 |
6 files changed, 170 insertions, 31 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index a4579da..c8ffb1f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,7 +10,7 @@ linpicker_monitor_LDADD = -lxenlight -lxenguest -lxenctrl -lxenstore \ linpicker_server_SOURCES = server.c fd.c local.c input.c comm.c \ view.c buffer.c client.c display.c \ - sclient.c dclient.c bclient.c \ + sclient.c dclient.c bclient.c sak.c \ xen_backend.c xen_server.c xenfb_server.c linpicker_server_LDADD = ../libvchan/libvchan.la \ -lxenlight -lxenguest -lxenctrl -lxenstore \ diff --git a/src/display.c b/src/display.c index 1623561..a327689 100644 --- a/src/display.c +++ b/src/display.c @@ -53,11 +53,11 @@ #include "client.h" #include "display.h" #include "input.h" +#include "sak.h" #include "sclient.h" -static struct display *server_display; /* display for the server itself */ static struct display *desktop_display; /* display for the combined desktop */ - +struct display *server_display; /* display for the server itself */ struct display *active_display; /* currently active display */ static struct view_list thumbs; /* global list of thumbnails */ @@ -285,6 +285,10 @@ display_secure_enter(int keycode) case LINPICK_LABEL_SAK: view_toggle_labeling(); break; + default: + if (sak_check_keycode(keycode)) + display_switch(sak_get_display(keycode)); + break; } } @@ -300,6 +304,31 @@ display_secure_leave(void) } } +void +display_key_event(struct input_event *e) +{ + if (is_switcher && e->code == LINPICK_SWITCH_SAK && e->value) { + display_switch(CIRCLEQ_LOOP_NEXT(&displays, active_display, display_next)); + server_display->focus_client = active_display->client; + display_update_seclabel(server_display); + show_switcher(); + } + if (!is_switcher && e->code == LINPICK_LABEL_SAK && e->value) + view_toggle_labeling(); +} + +void +display_position_event(int x, int y) +{ + struct display *d; + + CIRCLEQ_FOREACH(d, &displays, display_next) + if (d != active_display) + d->update_position(d, x, y); + + mouselabel->MoveTo(mouselabel, x + MOUSELABEL_OFFSET, y + MOUSELABEL_OFFSET); +} + static void display_view_insert(struct view *v, struct display *d) { @@ -473,31 +502,6 @@ display_buffer_remove(struct buffer *b) free(d); } -void -display_key_event(struct input_event *e) -{ - if (is_switcher && e->code == LINPICK_SWITCH_SAK && e->value) { - display_switch(CIRCLEQ_LOOP_NEXT(&displays, active_display, display_next)); - server_display->focus_client = active_display->client; - display_update_seclabel(server_display); - show_switcher(); - } - if (!is_switcher && e->code == LINPICK_LABEL_SAK && e->value) - view_toggle_labeling(); -} - -void -display_position_event(int x, int y) -{ - struct display *d; - - CIRCLEQ_FOREACH(d, &displays, display_next) - if (d != active_display) - d->update_position(d, x, y); - - mouselabel->MoveTo(mouselabel, x + MOUSELABEL_OFFSET, y + MOUSELABEL_OFFSET); -} - int init_graphics(int *argc, char ***argv) { diff --git a/src/display.h b/src/display.h index 8037f1d..f48b619 100644 --- a/src/display.h +++ b/src/display.h @@ -66,6 +66,7 @@ struct display { CIRCLEQ_HEAD(display_cirq, display); extern struct display *active_display; +extern struct display *server_display; extern IDirectFB *dfb; extern IDirectFBDisplayLayer *dl; diff --git a/src/input.c b/src/input.c index 73a3085..5c7b633 100644 --- a/src/input.c +++ b/src/input.c @@ -33,6 +33,7 @@ #include "client.h" #include "display.h" #include "input.h" +#include "sak.h" #include "fd.h" #define MAX_DEVICES 16 @@ -67,8 +68,13 @@ static int absy; static int is_sak_press(struct input_event *e) { - return (e->code == LINPICK_SWITCH_SAK || e->code == LINPICK_LABEL_SAK) && - e->value; + switch (e->code) { + case LINPICK_SWITCH_SAK: + case LINPICK_LABEL_SAK: + return e->value; + default: + return sak_check_keycode(e->code) ? e->value : 0; + } } static void @@ -94,7 +100,7 @@ key_event(struct input_event *e) alt_down = e->value; /* Check if SAK combination has been entered */ - if (!secure && is_sak_press(e) && ctrl_down && alt_down) { + if (!secure && alt_down && ctrl_down && is_sak_press(e)) { /* SAK entered */ active_display->send_key(active_display, 0, KEY_LEFTCTRL); active_display->send_key(active_display, 0, KEY_LEFTALT); diff --git a/src/sak.c b/src/sak.c new file mode 100644 index 0000000..942468f --- /dev/null +++ b/src/sak.c @@ -0,0 +1,74 @@ +/** + * @file + * @section AUTHORS + * + * Authors: + * Eamon Walsh <ewalsh@tycho.nsa.gov> + * + * @section LICENSE + * + * This file is in the public domain. + * + * @section DESCRIPTION + * + * This is the code that handles secure attention key (SAK) registrations + * from guests. Guests can send a SAK request via track protocol to request + * a SAK assignment. Assignment of SAK's is subject to permission checks to + * verify that the guest has permission to request the SAK. + * + * When the user presses a SAK that has been registered, two things happen: + * 1. Linpicker server immediately switches the display to the guest which + * has registered the SAK. + * 2. A SAK_PRESSED track protocol message is delivered to the guest. + * + * Note that a compromised guest operating system can simulate a SAK press or + * suppress SAK notifications. + */ + +#include <sys/types.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <linux/input.h> + +#include "display.h" +#include "sak.h" + +static struct display *sak_displays[NUM_SAKS]; + +int +sak_register(unsigned sak_code, struct display *d) +{ + if (sak_code > NUM_SAKS) + return -1; + if (sak_displays[sak_code] == d) + return 0; + if (sak_displays[sak_code]) + return -1; + + /* XXX check the client's permission to register the SAK */ + if (sak_code == 2) /* for demonstration purposes */ + return -1; + + sak_displays[sak_code] = d; + return 0; +} + +void +sak_unregister(struct display *d) +{ + int i; + + for (i = 0; i < NUM_SAKS; i++) + if (sak_displays[i] == d) + sak_displays[i] == NULL; +} + +struct display * +sak_get_display(int keycode) +{ + int sak_code = keycode - KEY_F1; + struct display *d = sak_displays[sak_code]; + return d ? d : server_display; +} diff --git a/src/sak.h b/src/sak.h new file mode 100644 index 0000000..f9a872d --- /dev/null +++ b/src/sak.h @@ -0,0 +1,54 @@ +/** + * @file + * @section AUTHORS + * + * Authors: + * Eamon Walsh <ewalsh@tycho.nsa.gov> + * + * @section LICENSE + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef _LINPICKER_SAK_H_ +#define _LINPICKER_SAK_H_ + +#include <linux/input.h> +#include "display.h" + +#define NUM_SAKS 3 + +int +sak_register(unsigned sak_code, struct display *d); + +void +sak_unregister(struct display *d); + +struct display * +sak_get_display(int keycode); + +static inline int +sak_check_keycode(int keycode) +{ + switch (keycode) { + case KEY_F1: + case KEY_F2: + case KEY_F3: + return 1; + default: + return 0; + } +} + +#endif /* _LINPICKER_SAK_H_ */ |