summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEamon Walsh <ewalsh@tycho.nsa.gov>2011-07-29 15:23:17 -0400
committerEamon Walsh <ewalsh@tycho.nsa.gov>2011-07-29 15:23:17 -0400
commit90c24e928f75339767fc76df12ba816cf1ab7795 (patch)
tree3d3c40b9094169f8e9686e4b3aa235bf93dc683b /src
parent6c39b8b1adb8da803ff85cfd492129173340abbc (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.am2
-rw-r--r--src/display.c58
-rw-r--r--src/display.h1
-rw-r--r--src/input.c12
-rw-r--r--src/sak.c74
-rw-r--r--src/sak.h54
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_ */