[ -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
(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
/sbin/ldconfig -n .${LIBDIR}
install -m755 ${LIBEXECDIR}/plymouth/plymouth bin
+ install -m755 ${BINDIR}/rhgb-client bin
mkdir -p ${TMPDIR}$DATADIR/plymouth
ply-boot-splash-plugin.h \
ply-boot-splash.h \
ply-boot-splash.c \
+ ply-window.h \
+ ply-window.c \
main.c
MAINTAINERCLEANFILES = Makefile.in
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)
{
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);
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)
{
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;
}
#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: */
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;
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)
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;
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);
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)
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);
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);
#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);
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);
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 */
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)
{
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);
{
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");
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)
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,
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);
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,
#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)
{
{
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;
should_ping = false;
should_update = false;
should_quit = false;
+ should_ask_for_password = false;
status = NULL;
for (i = 1; i < argc; i++)
{
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;
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)
#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"
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)
{
.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;