/* passwd.c --- verifying typed passwords with the OS.
- * xscreensaver, Copyright (c) 1993-2004 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1993-2014 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
+#include <time.h>
+#include <sys/time.h>
#ifndef VMS
# include <pwd.h> /* for getpwuid() */
{
int i, j;
+ si->unlock_state = ul_read;
+
for (i = 0; i < countof(methods); i++)
{
if (!methods[i].initted_p)
check_for_leaks (methods[i].name);
+ /* If password authentication failed, but the password was NULL
+ (meaning the user just hit RET) then treat that as "cancel".
+ This means that if the password is literally NULL, it will
+ work; but if not, then NULL passwords are treated as cancel.
+ */
+ if (si->unlock_state == ul_fail &&
+ si->cached_passwd &&
+ !*si->cached_passwd)
+ {
+ fprintf (stderr, "%s: assuming null password means cancel.\n",
+ blurb());
+ si->unlock_state = ul_cancel;
+ }
+
if (si->unlock_state == ul_success)
{
/* If we successfully authenticated by method N, but attempting
}
goto DONE; /* Successfully authenticated! */
}
+ else if (si->unlock_state == ul_cancel ||
+ si->unlock_state == ul_time)
+ {
+ /* If any auth method gets a cancel or timeout, don't try the
+ next auth method! We're done! */
+ fprintf (stderr,
+ "%s: authentication via %s %s.\n",
+ blurb(), methods[i].name,
+ (si->unlock_state == ul_cancel
+ ? "cancelled" : "timed out"));
+ goto DONE;
+ }
}
if (verbose_p)
if (si->unlock_state == ul_fail)
{
+ /* Note the time of the first failure */
+ if (si->unlock_failures == 0)
+ si->unlock_failure_time = time((time_t *) 0);
si->unlock_failures++;
do_syslog (si, verbose_p);
}