]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
add preliminary support for asking for password during boot sequence
authorRay Strode <rstrode@redhat.com>
Thu, 15 May 2008 19:48:59 +0000 (15:48 -0400)
committerRay Strode <rstrode@redhat.com>
Thu, 15 May 2008 19:50:37 +0000 (15:50 -0400)
(Only in text plugin so far)

13 files changed:
scripts/plymouth-update-initrd
src/Makefile.am
src/main.c
src/ply-boot-protocol.h
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/rhgb-client/ply-boot-client.c
src/rhgb-client/ply-boot-client.h
src/rhgb-client/rhgb-client.c
src/splash-plugins/text/text.c

index 98849f06686544fc0e6113931a22fb848bea8b5a..f6198e5c057ba70d45b71ea561bc17eb1f0f00d8 100755 (executable)
@@ -10,6 +10,7 @@ set -e
 [ -z "$SYSTEMMAP" ] && SYSTEM_MAP="/boot/System.map-$(/bin/uname -r)"
 [ -z "$LIB" ] && [ $(head -n1 $SYSTEM_MAP | awk '{print $1}' | wc -c) -lt 16 ] && LIB="lib" || LIB="lib64"
 [ -z "$LIBDIR" ] && LIBDIR="/usr/$LIB"
+[ -z "$BINDIR" ] && BINDIR="/usr/bin"
 [ -z "$GRUB_MENU_TITLE" ] && GRUB_MENU_TITLE="Graphical Bootup"
 
 if [ -z "$NEW_INITRD" ]; then
@@ -29,7 +30,8 @@ TMPDIR="$(mktemp -d $PWD/initrd.XXXXXXXXXX)"
 
 (cd $TMPDIR
     zcat $INITRD | cpio --quiet -Hnewc -i --make-directories
-    sed -i -e 's@^#!\(.*\)@#!/bin/plymouth \1@' init 
+    sed -i -e 's@^#!\(.*\)@#!/bin/plymouth \1\n@' init 
+    #sed -i -e 's@setquiet@&\n/bin/rhgb-client --ask-for-password@' init 
     (cd $LIBDIR
         DEPS=$(get_lib_deps ${LIBEXECDIR}/plymouth/plymouth ${LIBDIR}/plymouth/fedora-fade-in.so ${LIBDIR}/plymouth/text.so)
         for dep in $DEPS; do
@@ -40,6 +42,7 @@ TMPDIR="$(mktemp -d $PWD/initrd.XXXXXXXXXX)"
     /sbin/ldconfig -n .${LIBDIR}
 
     install -m755 ${LIBEXECDIR}/plymouth/plymouth bin
+    install -m755 ${BINDIR}/rhgb-client bin
 
     mkdir -p ${TMPDIR}$DATADIR/plymouth
 
index c5a3f9eb4f227a8872a9939dfc2034ee3f269cf5..540bf19584a22bd935be8a25a2fe7a75efc163a7 100644 (file)
@@ -14,6 +14,8 @@ plymouth_SOURCES =                                                            \
                    ply-boot-splash-plugin.h                                   \
                    ply-boot-splash.h                                          \
                    ply-boot-splash.c                                          \
+                   ply-window.h                                               \
+                   ply-window.c                                               \
                    main.c
 
 MAINTAINERCLEANFILES = Makefile.in
index 01d82d832267b16f12272a0b9f8aca92036a1661..0f6ba0bdebdb87e0374e05d4d771b099da64073c 100644 (file)
@@ -81,6 +81,12 @@ on_update (state_t     *state,
                                  status);
 }
 
+static char *
+on_ask_for_password (state_t *state)
+{
+  return ply_boot_splash_ask_for_password (state->boot_splash);
+}
+
 static void
 on_system_initialized (state_t *state)
 {
@@ -118,6 +124,7 @@ start_boot_server (state_t *state)
   ply_boot_server_t *server;
 
   server = ply_boot_server_new ((ply_boot_server_update_handler_t) on_update,
+                                (ply_boot_server_ask_for_password_handler_t) on_ask_for_password,
                                 (ply_boot_server_system_initialized_handler_t) on_system_initialized,
                                 (ply_boot_server_quit_handler_t) on_quit,
                                 state);
@@ -331,6 +338,23 @@ copy_data_files (state_t *state)
   return true;
 }
 
+static bool
+set_console_io_to_vt1 (state_t *state)
+{
+  int fd;
+
+  fd = open ("/dev/tty1", O_RDWR | O_APPEND);
+
+  if (fd < 0)
+    return false;
+
+  dup2 (fd, STDIN_FILENO);
+  dup2 (fd, STDOUT_FILENO);
+  dup2 (fd, STDERR_FILENO);
+
+  return true;
+}
+
 static bool
 initialize_environment (state_t *state)
 {
@@ -353,6 +377,9 @@ initialize_environment (state_t *state)
   if (!change_to_working_directory (state))
     return false;
 
+  if (!set_console_io_to_vt1 (state))
+    return false;
+
   ply_trace ("initialized minimal work environment");
   return true;
 }
index b44599afe88e442602a4f4c428ea287e2bce2b81..bdaf4c557ab3854f637c08ecd8200cd8a07e5bc3 100644 (file)
@@ -27,7 +27,9 @@
 #define PLY_BOOT_PROTOCOL_REQUEST_TYPE_UPDATE "U"
 #define PLY_BOOT_PROTOCOL_REQUEST_TYPE_SYSTEM_INITIALIZED "S"
 #define PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUIT "Q"
+#define PLY_BOOT_PROTOCOL_REQUEST_TYPE_PASSWORD "*"
 #define PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK "\x6"
+#define PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER "\x2"
 
 #endif /* PLY_BOOT_PROTOCOL_H */
 /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
index 8896a4bb492639a85fa13a878b473447e604a23b..5d3ecc90206c7ffe3157fae9d0148ce5d222d7ec 100644 (file)
@@ -51,6 +51,7 @@ struct _ply_boot_server
 
   ply_boot_server_update_handler_t update_handler;
   ply_boot_server_system_initialized_handler_t system_initialized_handler;
+  ply_boot_server_ask_for_password_handler_t ask_for_password_handler;
   ply_boot_server_quit_handler_t quit_handler;
   void *user_data;
 
@@ -59,6 +60,7 @@ struct _ply_boot_server
 
 ply_boot_server_t *
 ply_boot_server_new (ply_boot_server_update_handler_t  update_handler,
+                     ply_boot_server_ask_for_password_handler_t ask_for_password_handler,
                      ply_boot_server_system_initialized_handler_t initialized_handler,
                      ply_boot_server_quit_handler_t    quit_handler,
                      void                             *user_data)
@@ -70,6 +72,7 @@ ply_boot_server_new (ply_boot_server_update_handler_t  update_handler,
   server->loop = NULL;
   server->is_listening = false;
   server->update_handler = update_handler;
+  server->ask_for_password_handler = ask_for_password_handler;
   server->system_initialized_handler = initialized_handler;
   server->quit_handler = quit_handler;
   server->user_data = user_data;
@@ -194,6 +197,35 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
       if (server->quit_handler != NULL)
         server->quit_handler (server->user_data, server);
     }
+  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
+       */
+      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_ACK)) ||
+          !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)
     {
       ply_error ("received unknown command '%s' from client", command);
@@ -317,6 +349,14 @@ on_quit (ply_event_loop_t *loop)
   ply_event_loop_exit (loop, 0);
 }
 
+static char *
+on_ask_for_password (ply_event_loop_t *loop)
+{
+  printf ("got password request, returning 'password'...\n");
+
+  return strdup ("password");
+}
+
 int
 main (int    argc,
       char **argv)
@@ -330,6 +370,7 @@ main (int    argc,
   loop = ply_event_loop_new ();
 
   server = ply_boot_server_new ((ply_boot_server_update_handler_t) on_update,
+                                (ply_boot_server_ask_for_password_handler_t) on_ask_for_password,
                                 (ply_boot_server_system_initialized_handler_t) on_system_initialized,
                                 (ply_boot_server_quit_handler_t) on_quit,
                                 loop);
index eb72fa739c2d0cad9183cdb1e67980bba16c39b8..f809af004e4acef7228599078cadc728016d0b4a 100644 (file)
@@ -35,6 +35,9 @@ typedef void (* ply_boot_server_update_handler_t) (void              *user_data,
                                                    const char        *status,
                                                    ply_boot_server_t *server);
 
+typedef char * (* ply_boot_server_ask_for_password_handler_t) (void              *user_data,
+                                                             ply_boot_server_t *server);
+
 typedef void (* ply_boot_server_system_initialized_handler_t) (void              *user_data,
                                                         ply_boot_server_t *server);
 
@@ -43,10 +46,11 @@ typedef void (* ply_boot_server_quit_handler_t) (void              *user_data,
 
 #ifndef PLY_HIDE_FUNCTION_DECLARATIONS
 ply_boot_server_t *ply_boot_server_new (ply_boot_server_update_handler_t update_handler,
+                                        ply_boot_server_ask_for_password_handler_t ask_for_password_handler,
                                         ply_boot_server_system_initialized_handler_t initialized_handler,
                                         ply_boot_server_quit_handler_t quit_handler,
                                         void                        *user_data);
-                                                  
+
 void ply_boot_server_free (ply_boot_server_t *server);
 bool ply_boot_server_listen (ply_boot_server_t *server);
 void ply_boot_server_stop_listening (ply_boot_server_t *server);
index 6bb8c2daaca32c316e8870a6fc02aaa91356262f..3b54dfa9f3a56ffa8fa420a24cc78ae7475a6ebd 100644 (file)
@@ -30,7 +30,7 @@
 
 typedef struct _ply_boot_splash_plugin ply_boot_splash_plugin_t;
 
-typedef struct 
+typedef struct
 {
   ply_boot_splash_plugin_t * (* create_plugin) (void);
   void (* destroy_plugin) (ply_boot_splash_plugin_t *plugin);
@@ -42,6 +42,8 @@ typedef struct
   void (* attach_to_event_loop) (ply_boot_splash_plugin_t *plugin,
                                  ply_event_loop_t         *loop);
 
+  char * (* ask_for_password) (ply_boot_splash_plugin_t *plugin);
+
 } ply_boot_splash_plugin_interface_t;
 
 #endif /* PLY_BOOT_SPLASH_PLUGIN_H */
index 3a6009341bdcfe9cfcaf6b5866adb28176b75501..86e806b388bd5311e4a717262e8204b67da772ce 100644 (file)
@@ -176,6 +176,19 @@ ply_boot_splash_update_status (ply_boot_splash_t *splash,
   splash->plugin_interface->update_status (splash->plugin, status);
 }
 
+char *
+ply_boot_splash_ask_for_password (ply_boot_splash_t *splash)
+{
+
+  assert (splash != NULL);
+  assert (splash->plugin_interface != NULL);
+  assert (splash->plugin != NULL);
+  assert (splash->plugin_interface->ask_for_password != NULL);
+  assert (splash->is_shown);
+
+  return splash->plugin_interface->ask_for_password (splash->plugin);
+}
+
 void
 ply_boot_splash_hide (ply_boot_splash_t *splash)
 {
index 6ccdb15ea45c0a74dac5a1719866801e4c135978..79b09b041492e49f0bcf05f58e6c7b76aad41a3c 100644 (file)
@@ -36,6 +36,8 @@ void ply_boot_splash_free (ply_boot_splash_t *splash);
 bool ply_boot_splash_show (ply_boot_splash_t *splash);
 void ply_boot_splash_update_status (ply_boot_splash_t *splash,
                                     const char        *status);
+
+char *ply_boot_splash_ask_for_password (ply_boot_splash_t *splash);
 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 28a285d8692c4572519a3299991906692ddd63b0..08eb6b973ec680cd147468670c7b2ccb08e6eafe 100644 (file)
@@ -231,10 +231,13 @@ ply_boot_client_process_incoming_replies (ply_boot_client_t *client)
 {
   ply_list_node_t *request_node;
   ply_boot_client_request_t *request;
+  bool processed_reply;
   uint8_t byte[2] = "";
+  uint8_t size;
 
   assert (client != NULL);
 
+  processed_reply = false;
   if (ply_list_get_length (client->requests_waiting_for_replies) == 0)
     {
       ply_error ("received unexpected response from boot status daemon");
@@ -248,22 +251,36 @@ ply_boot_client_process_incoming_replies (ply_boot_client_t *client)
   assert (request != NULL);
 
   if (!ply_read (client->socket_fd, byte, sizeof (uint8_t)))
+    goto out;
+
+  if (memcmp (byte, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK, sizeof (uint8_t)) == 0)
+      request->handler (request->user_data, client);
+  else if (memcmp (byte, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER, sizeof (uint8_t)) == 0)
     {
-      if (request->failed_handler != NULL)
-        request->failed_handler (request->user_data, client);
-      ply_list_remove_node (client->requests_waiting_for_replies, request_node);
-      return;
+      char answer[257] = "";
+
+      /* FIXME: should make this 4 bytes instead of 1
+       */
+      if (!ply_read (client->socket_fd, &size, sizeof (uint8_t)))
+        goto out;
+
+      if (!ply_read (client->socket_fd, answer, size))
+        goto out;
+
+      ((ply_boot_client_answer_handler_t) request->handler) (request->user_data, answer, client);
     }
+  else
+    goto out;
+
+  processed_reply = true;
 
-  if (memcmp (byte, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK, sizeof (uint8_t)) != 0)
+out:
+  if (!processed_reply)
     {
       if (request->failed_handler != NULL)
         request->failed_handler (request->user_data, client);
-      ply_list_remove_node (client->requests_waiting_for_replies, request_node);
-      return;
     }
 
-  request->handler (request->user_data, client);
   ply_list_remove_node (client->requests_waiting_for_replies, request_node);
 
   if (ply_list_get_length (client->requests_waiting_for_replies) == 0)
@@ -437,6 +454,19 @@ ply_boot_client_tell_daemon_system_is_initialized (ply_boot_client_t
                                  NULL, handler, failed_handler, user_data);
 }
 
+void
+ply_boot_client_ask_daemon_for_password (ply_boot_client_t                  *client,
+                                         ply_boot_client_answer_handler_t    handler,
+                                         ply_boot_client_response_handler_t  failed_handler,
+                                         void                               *user_data)
+{
+  assert (client != NULL);
+
+  ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PASSWORD,
+                                 NULL, (ply_boot_client_response_handler_t)
+                                 handler, failed_handler, user_data);
+}
+
 void
 ply_boot_client_tell_daemon_to_quit (ply_boot_client_t                  *client,
                                      ply_boot_client_response_handler_t  handler,
index 0a24a08d14a72bb4124b405bc386f0c716dca626..4c72db242e3cf05c637af303c37a52ccf29472b0 100644 (file)
@@ -32,6 +32,9 @@
 typedef struct _ply_boot_client ply_boot_client_t;
 typedef void (* ply_boot_client_response_handler_t) (void              *user_data,
                                                      ply_boot_client_t *client);
+typedef void (* ply_boot_client_answer_handler_t) (void              *user_data,
+                                                   const char        *answer,
+                                                   ply_boot_client_t *client);
 typedef void (* ply_boot_client_disconnect_handler_t) (void              *user_data,
                                                        ply_boot_client_t *client);
 
@@ -51,6 +54,10 @@ void ply_boot_client_update_daemon (ply_boot_client_t                  *client,
                                     ply_boot_client_response_handler_t  handler,
                                     ply_boot_client_response_handler_t  failed_handler,
                                     void                               *user_data);
+void ply_boot_client_ask_daemon_for_password (ply_boot_client_t                  *client,
+                                         ply_boot_client_answer_handler_t    handler,
+                                         ply_boot_client_response_handler_t  failed_handler,
+                                         void                               *user_data);
 void ply_boot_client_tell_daemon_system_is_initialized (ply_boot_client_t                  *client,
                                                         ply_boot_client_response_handler_t  handler,
                                                         ply_boot_client_response_handler_t  failed_handler,
index c03c21006d9ce04f58b02669b777363b6e4a640c..048563d8a0f70e63c9c58e8e218c7a1c0f1ef1d7 100644 (file)
 #include "ply-logger.h"
 #include "ply-utils.h"
 
+static void
+on_answer (ply_event_loop_t *loop,
+           const char       *answer)
+{
+  write (STDOUT_FILENO, answer, strlen (answer));
+  ply_event_loop_exit (loop, 0);
+}
+
 static void
 on_success (ply_event_loop_t *loop)
 {
@@ -61,7 +69,7 @@ main (int    argc,
 {
   ply_event_loop_t *loop;
   ply_boot_client_t *client;
-  bool should_quit, should_ping, should_update, should_sysinit;
+  bool should_quit, should_ping, should_update, should_sysinit, should_ask_for_password;
   char *status;
   int exit_code;
   int i;
@@ -80,6 +88,7 @@ main (int    argc,
   should_ping = false;
   should_update = false;
   should_quit = false;
+  should_ask_for_password = false;
   status = NULL;
   for (i = 1; i < argc; i++)
     {
@@ -94,6 +103,8 @@ main (int    argc,
         should_ping = true;
       else if (strstr (argv[i], "--sysinit") != NULL)
         should_sysinit = true;
+      else if (strstr (argv[i], "--ask-for-password") != NULL)
+        should_ask_for_password = true;
       else if (strstr (argv[i], "--update") != NULL)
         {
           const char *update_argument;
@@ -149,6 +160,12 @@ main (int    argc,
                                    on_success, 
                                    (ply_boot_client_response_handler_t)
                                    on_failure, loop);
+  else if (should_ask_for_password)
+    ply_boot_client_ask_daemon_for_password (client,
+                                   (ply_boot_client_answer_handler_t)
+                                   on_answer,
+                                   (ply_boot_client_response_handler_t)
+                                   on_failure, loop);
   else if (should_sysinit)
     ply_boot_client_tell_daemon_system_is_initialized (client,
                                    (ply_boot_client_response_handler_t)
index fc76817cb7d7038079da700dd6647160bc0149d2..d2f9b99244f2b6cbcc7b864c7041f2b6b6b9d481 100644 (file)
@@ -35,8 +35,9 @@
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/types.h>
-#include <values.h>
+#include <termios.h>
 #include <unistd.h>
+#include <values.h>
 
 #include "ply-boot-splash-plugin.h"
 #include "ply-event-loop.h"
@@ -157,6 +158,34 @@ attach_to_event_loop (ply_boot_splash_plugin_t *plugin,
                                  plugin);
 }
 
+char *
+ask_for_password (ply_boot_splash_plugin_t *plugin)
+{
+  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);
+
+  printf ("\n");
+
+  return strdup (answer);
+}
+
 ply_boot_splash_plugin_interface_t *
 ply_boot_splash_plugin_get_interface (void)
 {
@@ -167,7 +196,8 @@ ply_boot_splash_plugin_get_interface (void)
       .show_splash_screen = show_splash_screen,
       .update_status = update_status,
       .hide_splash_screen = hide_splash_screen,
-      .attach_to_event_loop = attach_to_event_loop
+      .attach_to_event_loop = attach_to_event_loop,
+      .ask_for_password = ask_for_password,
     };
 
   return &plugin_interface;