1 /* vlock-main.c -- main routine for vlock,
2 * the VT locking program for linux
4 * This program is copyright (C) 2007 Frank Benkstein, and is free
5 * software which is freely distributable under the terms of the
6 * GNU General Public License version 2, included as the file COPYING in this
7 * distribution. It is NOT public domain software, and any
8 * redistribution not permitted by the GNU General Public License is
9 * expressly forbidden without prior written permission from
22 #include <sys/types.h>
27 #include <glib/gprintf.h>
28 #include <glib-object.h>
32 #include "console_switch.h"
43 static const char *auth_failure_blurb
=
45 "******************************************************************\n"
46 "*** You may not be able to able to unlock your terminal now. ***\n"
48 "*** Log into another terminal and kill the vlock-main process. ***\n"
49 "******************************************************************\n"
53 static int auth_tries
;
55 static void auth_loop(const char *username
)
58 struct timespec
*prompt_timeout
;
59 struct timespec
*wait_timeout
;
61 const char *auth_names
[] = { username
, "root", NULL
};
63 /* If NO_ROOT_PASS is defined or the username is "root" ... */
65 if (strcmp(username
, "root") == 0)
67 /* ... do not fall back to "root". */
70 /* Get the vlock message from the environment. */
71 vlock_message
= getenv("VLOCK_MESSAGE");
73 if (vlock_message
== NULL
) {
74 if (console_switch_locked
)
75 vlock_message
= getenv("VLOCK_ALL_MESSAGE");
77 vlock_message
= getenv("VLOCK_CURRENT_MESSAGE");
80 /* Get the timeouts from the environment. */
81 prompt_timeout
= parse_seconds(getenv("VLOCK_PROMPT_TIMEOUT"));
83 wait_timeout
= parse_seconds(getenv("VLOCK_TIMEOUT"));
91 /* Print vlock message if there is one. */
92 if (vlock_message
&& *vlock_message
) {
93 fputs(vlock_message
, stderr
);
97 /* Wait for enter or escape to be pressed. */
98 c
= wait_for_character("\n\033", wait_timeout
);
100 /* Escape was pressed or the timeout occurred. */
101 if (c
== '\033' || c
== 0) {
103 plugin_hook("vlock_save");
104 /* Wait for any key to be pressed. */
105 c
= wait_for_character(NULL
, NULL
);
106 plugin_hook("vlock_save_abort");
108 /* Do not require enter to be pressed twice. */
116 for (size_t i
= 0; auth_names
[i
] != NULL
; i
++) {
117 if (auth(auth_names
[i
], prompt_timeout
, &err
))
120 g_assert(err
!= NULL
);
122 if (g_error_matches(err
,
124 VLOCK_PROMPT_ERROR_TIMEOUT
))
125 fprintf(stderr
, "Timeout!\n");
127 fprintf(stderr
, "vlock: %s\n", err
->message
);
129 if (g_error_matches(err
,
131 VLOCK_AUTH_ERROR_FAILED
)) {
132 fputs(auth_failure_blurb
, stderr
);
145 /* Free timeouts memory. */
147 free(prompt_timeout
);
150 void display_auth_tries(void)
154 "%d failed authentication %s.\n",
156 auth_tries
> 1 ? "tries" : "try");
160 static void call_end_hook(void)
162 (void) plugin_hook("vlock_end");
167 /* Lock the current terminal until proper authentication is received. */
168 int main(int argc
, char *const argv
[])
170 const char *username
= NULL
;
172 /* Initialize GLib. */
173 g_set_prgname(argv
[0]);
176 /* Initialize logging. */
177 vlock_initialize_logging();
179 install_signal_handlers();
181 /* Get the user name from the environment if started as root. */
183 username
= g_getenv("USER");
185 if (username
== NULL
)
186 username
= g_get_user_name();
188 vlock_atexit(display_auth_tries
);
191 GError
*tmp_error
= NULL
;
193 for (int i
= 1; i
< argc
; i
++) {
194 if (!load_plugin(argv
[i
], &tmp_error
)) {
195 g_assert(tmp_error
!= NULL
);
197 if (g_error_matches(tmp_error
,
199 VLOCK_PLUGIN_ERROR_NOT_FOUND
))
200 g_fprintf(stderr
, "vlock: no such plugin '%s'\n", argv
[i
]);
203 "vlock: loading plugin '%s' failed: %s\n",
207 g_clear_error(&tmp_error
);
212 vlock_atexit(unload_plugins
);
214 if (!resolve_dependencies(&tmp_error
)) {
215 g_assert(tmp_error
!= NULL
);
217 "vlock: error resolving plugin dependencies: %s\n",
219 g_clear_error(&tmp_error
);
223 plugin_hook("vlock_start");
224 vlock_atexit(call_end_hook
);
225 #else /* !USE_PLUGINS */
226 /* Emulate pseudo plugin "all". */
227 if (argc
== 2 && (strcmp(argv
[1], "all") == 0)) {
228 if (!lock_console_switch()) {
231 "vlock: could not disable console switching: %s\n",
237 vlock_atexit((void (*) (void))unlock_console_switch
);
238 } else if (argc
> 1) {
239 g_fprintf(stderr
, "vlock: plugin support disabled\n");
244 if (!isatty(STDIN_FILENO
)) {
245 g_fprintf(stderr
, "vlock: stdin is not a terminal\n");
249 /* Delay securing the terminal until here because one of the plugins might
250 * have changed the active terminal. */
252 vlock_atexit(restore_terminal
);