diff options
-rw-r--r-- | TODO | 3 | ||||
-rwxr-xr-x | scripts/plymouth-update-initrd | 2 | ||||
-rw-r--r-- | src/main.c | 31 | ||||
-rw-r--r-- | src/ply-boot-server.c | 53 | ||||
-rw-r--r-- | src/ply-boot-server.h | 7 | ||||
-rw-r--r-- | src/ply-boot-splash-plugin.h | 6 | ||||
-rw-r--r-- | src/ply-boot-splash.c | 9 | ||||
-rw-r--r-- | src/ply-boot-splash.h | 5 | ||||
-rw-r--r-- | src/splash-plugins/text/text.c | 72 |
9 files changed, 131 insertions, 57 deletions
@@ -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 @@ -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 * |