]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
Add second cut at password support
authorRay Strode <rstrode@redhat.com>
Thu, 22 May 2008 02:57:40 +0000 (22:57 -0400)
committerRay Strode <rstrode@redhat.com>
Thu, 22 May 2008 02:57:40 +0000 (22:57 -0400)
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.

TODO
scripts/plymouth-update-initrd
src/main.c
src/ply-boot-server.c
src/ply-boot-server.h
src/ply-boot-splash-plugin.h
src/ply-boot-splash.c
src/ply-boot-splash.h
src/splash-plugins/text/text.c

diff --git a/TODO b/TODO
index b100d375c5300d52406ba6268e469c82d567b6ac..309c7b6a47fe1e058dd0ca2f3f95791810dc961d 100644 (file)
--- 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
index 99032ae351ce5b33d53c39c4f754cf6d8affe23a..2615f54ce4a7a5d08aba5ba658f56d2cedd8d588 100755 (executable)
@@ -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
index 6bfd83981ab6ae7ba268be5a46cd033efd4ecfd7..eb5c724a255248ce7f7f3579b294b25b84fed2f6 100644 (file)
@@ -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
index 5752c253573f50eb4390dd0460e45cd9ab55fc41..84e4ad22562112c9efa82edd88ae5401d376c9d4 100644 (file)
@@ -180,6 +180,31 @@ ply_boot_connection_is_from_root (ply_boot_connection_t *connection)
   return uid == 0;
 }
 
+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)
 {
@@ -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)
index 7ddab15ce837581e046ca975262b4d497f56c549..dd9f386e7806e7916d342b93ca8ed2436db731a8 100644 (file)
@@ -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,
index a93d07fcd438c55834a8a19fb44c0cd91c7f4671..7f18bb148c3147b6195047daabc27df62281a243 100644 (file)
@@ -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);
 
index c24ca64c1c6088cca36475aab56177b2749537e2..3f51755fafd7f16d4e1fbdfaedd5c9cc4e50c195 100644 (file)
@@ -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
index fefb359d1dff5efb2cc92aa2746a56690f0f512b..5c26caf9aeba3ea3294d2c9bc9a32544146ac8bb 100644 (file)
@@ -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);
index d65c0be4c4766e100f32f579d9e7d8021ed8f50f..a40e9450bcf03b1da8fc07ad90378b07e67b24fc 100644 (file)
 #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"
 
 #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 *