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
=
44 "******************************************************************\n"
45 "*** You may not be able to able to unlock your terminal now. ***\n"
47 "*** Log into another terminal and kill the vlock-main process. ***\n"
48 "******************************************************************\n"
51 static int auth_tries
;
53 static void auth_loop(const char *username
)
56 struct timespec
*prompt_timeout
;
57 struct timespec
*wait_timeout
;
59 const char *auth_names
[] = { username
, "root", NULL
};
61 /* If NO_ROOT_PASS is defined or the username is "root" ... */
63 if (strcmp(username
, "root") == 0)
65 /* ... do not fall back to "root". */
68 /* Get the vlock message from the environment. */
69 vlock_message
= getenv("VLOCK_MESSAGE");
71 if (vlock_message
== NULL
) {
72 if (console_switch_locked
)
73 vlock_message
= getenv("VLOCK_ALL_MESSAGE");
75 vlock_message
= getenv("VLOCK_CURRENT_MESSAGE");
78 /* Get the timeouts from the environment. */
79 prompt_timeout
= parse_seconds(getenv("VLOCK_PROMPT_TIMEOUT"));
81 wait_timeout
= parse_seconds(getenv("VLOCK_TIMEOUT"));
89 /* Print vlock message if there is one. */
90 if (vlock_message
&& *vlock_message
) {
91 fputs(vlock_message
, stderr
);
95 /* Wait for enter or escape to be pressed. */
96 c
= wait_for_character("\n\033", wait_timeout
);
98 /* Escape was pressed or the timeout occurred. */
99 if (c
== '\033' || c
== 0) {
101 plugin_hook("vlock_save");
102 /* Wait for any key to be pressed. */
103 c
= wait_for_character(NULL
, NULL
);
104 plugin_hook("vlock_save_abort");
106 /* Do not require enter to be pressed twice. */
114 for (size_t i
= 0; auth_names
[i
] != NULL
; i
++) {
115 if (auth(auth_names
[i
], prompt_timeout
, &err
))
118 g_assert(err
!= NULL
);
120 if (g_error_matches(err
,
122 VLOCK_PROMPT_ERROR_TIMEOUT
))
123 fprintf(stderr
, "Timeout!\n");
125 fprintf(stderr
, "vlock: %s\n", err
->message
);
127 if (g_error_matches(err
,
129 VLOCK_AUTH_ERROR_FAILED
)) {
131 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 ensure_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
);