summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2008-05-21 22:57:40 -0400
committerRay Strode <rstrode@redhat.com>2008-05-21 22:57:40 -0400
commitb8624e3cd05258a81a7e3cf4d95e2dcd81fe0aa4 (patch)
treeb9026ccd834ec9887de61b6c23e3776493ce5665
parentb5b6fb666d44738296b7cb1c0950ee2226493e34 (diff)
downloadplymouth-b8624e3cd05258a81a7e3cf4d95e2dcd81fe0aa4.tar.gz
plymouth-b8624e3cd05258a81a7e3cf4d95e2dcd81fe0aa4.tar.xz
plymouth-b8624e3cd05258a81a7e3cf4d95e2dcd81fe0aa4.zip
Add second cut at password support
This version works even in raw mode, by buffering key presses passed from the window object, and replying to the client after the user presses enter. There are a lot of layers of function pointers getting passed around, so it may make sense to introduce an opaque type for holding the password and triggering the reply.
-rw-r--r--TODO3
-rwxr-xr-xscripts/plymouth-update-initrd2
-rw-r--r--src/main.c31
-rw-r--r--src/ply-boot-server.c53
-rw-r--r--src/ply-boot-server.h7
-rw-r--r--src/ply-boot-splash-plugin.h6
-rw-r--r--src/ply-boot-splash.c9
-rw-r--r--src/ply-boot-splash.h5
-rw-r--r--src/splash-plugins/text/text.c72
9 files changed, 131 insertions, 57 deletions
diff --git a/TODO b/TODO
index b100d37..309c7b6 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,6 @@
- fix the tests so that they work better with "make check"
- Allow plymouth to be started from nash instead of the other way around
- Drop all the make ram disk and copy code. That was just to make bolting things on easier. We can integrate now.
+- allow longer than 255 byte replies from server to client
+- make server send immediate ACK for password request and then ANSWER later with a link back to original request in ANSWER
+- add ask-for-password support to fedora-fade-in and details plugins
diff --git a/scripts/plymouth-update-initrd b/scripts/plymouth-update-initrd
index 99032ae..2615f54 100755
--- a/scripts/plymouth-update-initrd
+++ b/scripts/plymouth-update-initrd
@@ -31,7 +31,7 @@ TMPDIR="$(mktemp -d $PWD/initrd.XXXXXXXXXX)"
(cd $TMPDIR
zcat $INITRD | cpio --quiet -Hnewc -i --make-directories
sed -i -e 's@^#!\(.*\)@#!/bin/plymouthd \1\n@' init
- sed -i -e 's@setquiet@&\n/bin/plymouth --show-splash@' init
+ sed -i -e 's@setquiet@&\n/bin/plymouth --show-splash\n/bin/plymouth --ask-for-password@' init
(cd $LIBDIR
DEPS=$(get_lib_deps ${LIBEXECDIR}/plymouth/plymouth ${LIBDIR}/plymouth/fedora-fade-in.so ${LIBDIR}/plymouth/text.so ${LIBDIR}/plymouth/details.so)
for dep in $DEPS; do
diff --git a/src/main.c b/src/main.c
index 6bfd839..eb5c724 100644
--- a/src/main.c
+++ b/src/main.c
@@ -99,10 +99,35 @@ on_update (state_t *state,
status);
}
-static char *
-on_ask_for_password (state_t *state)
+typedef struct
+{
+ ply_boot_server_password_answer_handler_t handler;
+ void *data;
+ state_t *state;
+} password_answer_closure_t;
+
+static void
+on_password_answer (password_answer_closure_t *closure,
+ const char *password)
+{
+ closure->handler (closure->data, password, closure->state->boot_server);
+}
+
+static void
+on_ask_for_password (state_t *state,
+ ply_boot_server_password_answer_handler_t answer_handler,
+ void *answer_data)
{
- return ply_boot_splash_ask_for_password (state->boot_splash);
+ password_answer_closure_t *closure;
+
+ closure = malloc (sizeof (password_answer_closure_t));
+ closure->handler = answer_handler;
+ closure->data = answer_data;
+ closure->state = state;
+
+ ply_boot_splash_ask_for_password (state->boot_splash,
+ (ply_boot_splash_password_answer_handler_t)
+ on_password_answer, closure);
}
static void
diff --git a/src/ply-boot-server.c b/src/ply-boot-server.c
index 5752c25..84e4ad2 100644
--- a/src/ply-boot-server.c
+++ b/src/ply-boot-server.c
@@ -181,6 +181,31 @@ ply_boot_connection_is_from_root (ply_boot_connection_t *connection)
}
static void
+ply_boot_connection_on_password_answer (ply_boot_connection_t *connection,
+ const char *password,
+ ply_boot_server_t *server)
+{
+
+ size_t size;
+
+ /* FIXME: support up to 4 billion
+ */
+ if (strlen (password) > 255)
+ ply_error ("password to long to fit in buffer");
+
+ size = (uint8_t) strlen (password);
+
+ if (!ply_write (connection->fd,
+ PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER,
+ strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER)) ||
+ !ply_write (connection->fd,
+ &size, sizeof (uint8_t)) ||
+ !ply_write (connection->fd,
+ password, size))
+ ply_error ("could not write bytes: %m");
+}
+
+static void
ply_boot_connection_on_request (ply_boot_connection_t *connection)
{
ply_boot_server_t *server;
@@ -231,31 +256,13 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
}
else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PASSWORD) == 0)
{
- char *password;
- uint8_t size;
-
- password = NULL;
-
if (server->ask_for_password_handler != NULL)
- password = server->ask_for_password_handler (server->user_data, server);
-
- /* FIXME: support up to 4 billion
+ server->ask_for_password_handler (server->user_data,
+ ply_boot_connection_on_password_answer,
+ connection,
+ server);
+ /* will reply later
*/
- if (strlen (password) > 255)
- ply_error ("password to long to fit in buffer");
-
- size = (uint8_t) strlen (password);
-
- if (!ply_write (connection->fd,
- PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER,
- strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER)) ||
- !ply_write (connection->fd,
- &size, sizeof (uint8_t)) ||
- !ply_write (connection->fd,
- password, size))
- ply_error ("could not write bytes: %m");
-
- free (password);
return;
}
else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PING) != 0)
diff --git a/src/ply-boot-server.h b/src/ply-boot-server.h
index 7ddab15..dd9f386 100644
--- a/src/ply-boot-server.h
+++ b/src/ply-boot-server.h
@@ -38,7 +38,12 @@ typedef void (* ply_boot_server_update_handler_t) (void *user_data,
typedef void (* ply_boot_server_show_splash_handler_t) (void *user_data,
ply_boot_server_t *server);
-typedef char * (* ply_boot_server_ask_for_password_handler_t) (void *user_data,
+typedef void (* ply_boot_server_password_answer_handler_t) (void *answer_data,
+ const char *password,
+ ply_boot_server_t *server);
+typedef void (* ply_boot_server_ask_for_password_handler_t) (void *user_data,
+ ply_boot_server_password_answer_handler_t on_answer_handler,
+ void *answer_data,
ply_boot_server_t *server);
typedef void (* ply_boot_server_system_initialized_handler_t) (void *user_data,
diff --git a/src/ply-boot-splash-plugin.h b/src/ply-boot-splash-plugin.h
index a93d07f..7f18bb1 100644
--- a/src/ply-boot-splash-plugin.h
+++ b/src/ply-boot-splash-plugin.h
@@ -32,6 +32,8 @@
typedef struct _ply_boot_splash_plugin ply_boot_splash_plugin_t;
+typedef void (* ply_boot_splash_password_answer_handler_t) (void *answer_data, const char *password);
+
typedef struct
{
ply_boot_splash_plugin_t * (* create_plugin) (void);
@@ -50,7 +52,9 @@ typedef struct
ply_event_loop_t *loop,
ply_window_t *window);
- char * (* ask_for_password) (ply_boot_splash_plugin_t *plugin);
+ void (* ask_for_password) (ply_boot_splash_plugin_t *plugin,
+ ply_boot_splash_password_answer_handler_t answer_handler,
+ void *answer_data);
void (* on_keyboard_input) (ply_boot_splash_plugin_t *plugin,
const char *keyboard_input);
diff --git a/src/ply-boot-splash.c b/src/ply-boot-splash.c
index c24ca64..3f51755 100644
--- a/src/ply-boot-splash.c
+++ b/src/ply-boot-splash.c
@@ -226,8 +226,10 @@ ply_boot_splash_update_output (ply_boot_splash_t *splash,
splash->plugin_interface->on_boot_output (splash->plugin, output, size);
}
-char *
-ply_boot_splash_ask_for_password (ply_boot_splash_t *splash)
+void
+ply_boot_splash_ask_for_password (ply_boot_splash_t *splash,
+ ply_boot_splash_password_answer_handler_t *answer_handler,
+ void *answer_data)
{
assert (splash != NULL);
@@ -236,7 +238,8 @@ ply_boot_splash_ask_for_password (ply_boot_splash_t *splash)
assert (splash->plugin_interface->ask_for_password != NULL);
assert (splash->is_shown);
- return splash->plugin_interface->ask_for_password (splash->plugin);
+ splash->plugin_interface->ask_for_password (splash->plugin,
+ answer_handler, answer_data);
}
static void
diff --git a/src/ply-boot-splash.h b/src/ply-boot-splash.h
index fefb359..5c26caf 100644
--- a/src/ply-boot-splash.h
+++ b/src/ply-boot-splash.h
@@ -29,6 +29,7 @@
#include "ply-event-loop.h"
#include "ply-window.h"
#include "ply-buffer.h"
+#include "ply-boot-splash-plugin.h"
typedef struct _ply_boot_splash ply_boot_splash_t;
@@ -44,7 +45,9 @@ void ply_boot_splash_update_output (ply_boot_splash_t *splash,
const char *output,
size_t size);
-char *ply_boot_splash_ask_for_password (ply_boot_splash_t *splash);
+void ply_boot_splash_ask_for_password (ply_boot_splash_t *splash,
+ ply_boot_splash_password_answer_handler_t *answer_handler,
+ void *answer_data);
void ply_boot_splash_hide (ply_boot_splash_t *splash);
void ply_boot_splash_attach_to_event_loop (ply_boot_splash_t *splash,
ply_event_loop_t *loop);
diff --git a/src/splash-plugins/text/text.c b/src/splash-plugins/text/text.c
index d65c0be..a40e945 100644
--- a/src/splash-plugins/text/text.c
+++ b/src/splash-plugins/text/text.c
@@ -38,8 +38,10 @@
#include <termios.h>
#include <unistd.h>
#include <values.h>
+#include <wchar.h>
#include "ply-boot-splash-plugin.h"
+#include "ply-buffer.h"
#include "ply-event-loop.h"
#include "ply-list.h"
#include "ply-logger.h"
@@ -50,11 +52,18 @@
#include <linux/kd.h>
+#define CLEAR_LINE_SEQUENCE "\033[2K"
+
struct _ply_boot_splash_plugin
{
ply_event_loop_t *loop;
int console_fd;
+ ply_boot_splash_password_answer_handler_t password_answer_handler;
+ void *password_answer_data;
+
+ ply_buffer_t *keyboard_input_buffer;
+ uint32_t keyboard_input_is_hidden : 1;
};
ply_boot_splash_plugin_t *
@@ -65,6 +74,7 @@ create_plugin (void)
ply_trace ("creating plugin");
plugin = calloc (1, sizeof (ply_boot_splash_plugin_t));
+ plugin->keyboard_input_buffer = ply_buffer_new ();
plugin->console_fd = -1;
return plugin;
@@ -78,6 +88,8 @@ destroy_plugin (ply_boot_splash_plugin_t *plugin)
if (plugin == NULL)
return;
+ ply_buffer_free (plugin->keyboard_input_buffer);
+
free (plugin);
}
@@ -151,38 +163,50 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin,
}
}
-char *
-ask_for_password (ply_boot_splash_plugin_t *plugin)
+void
+ask_for_password (ply_boot_splash_plugin_t *plugin,
+ ply_boot_splash_password_answer_handler_t answer_handler,
+ void *answer_data)
{
- char answer[1024];
- struct termios initial_term_attributes;
- struct termios noecho_term_attributes;
-
- tcgetattr (STDIN_FILENO, &initial_term_attributes);
- noecho_term_attributes = initial_term_attributes;
- noecho_term_attributes.c_lflag &= ~ECHO;
-
- printf ("Password: ");
-
- if (tcsetattr (STDIN_FILENO, TCSAFLUSH, &noecho_term_attributes) != 0) {
- fprintf (stderr, "Could not set terminal attributes\n");
- return NULL;
- }
-
- fgets (answer, sizeof (answer), stdin);
- answer[strlen (answer) - 1] = '\0';
-
- tcsetattr (STDIN_FILENO, TCSANOW, &initial_term_attributes);
+ plugin->password_answer_handler = answer_handler;
+ plugin->password_answer_data = answer_data;
- printf ("\n");
-
- return strdup (answer);
+ write (STDOUT_FILENO, "\nPassword: ", strlen ("\nPassword: "));
+ plugin->keyboard_input_is_hidden = true;
}
void
on_keyboard_input (ply_boot_splash_plugin_t *plugin,
const char *keyboard_input)
{
+ ssize_t character_size;
+
+ character_size = (ssize_t) mbrlen (keyboard_input, MB_CUR_MAX, NULL);
+
+ if (character_size < 0)
+ return;
+
+ if (plugin->password_answer_handler != NULL)
+ {
+ if (character_size == 1 && keyboard_input[0] == '\r')
+ {
+ plugin->password_answer_handler (plugin->password_answer_data,
+ ply_buffer_get_bytes (plugin->keyboard_input_buffer));
+ plugin->keyboard_input_is_hidden = false;
+ ply_buffer_clear (plugin->keyboard_input_buffer);
+ plugin->password_answer_handler = NULL;
+ write (STDOUT_FILENO, CLEAR_LINE_SEQUENCE, strlen (CLEAR_LINE_SEQUENCE));
+ return;
+ }
+ }
+
+ ply_buffer_append_bytes (plugin->keyboard_input_buffer,
+ keyboard_input, character_size);
+
+ if (plugin->keyboard_input_is_hidden)
+ write (STDOUT_FILENO, "•", strlen ("•"));
+ else
+ write (STDOUT_FILENO, keyboard_input, character_size);
}
ply_boot_splash_plugin_interface_t *