#ifndef NO_LOCKING /* (mostly) whole file */
-#ifdef HAVE_SYSLOG
-# include <syslog.h>
-#endif /* HAVE_SYSLOG */
-
#ifdef HAVE_XHPDISABLERESET
# include <X11/XHPlib.h>
static void hp_lock_reset (saver_info *si, Bool lock_p);
char *date_label;
char *passwd_string;
Bool passwd_changed_p; /* Whether the user entry field needs redrawing */
+ Bool caps_p; /* Whether we saw a keypress with caps-lock on */
char *unlock_label;
char *login_label;
char *uname_label;
pw->passwd_cursor = XCreateFontCursor (si->dpy, XC_top_left_arrow);
pw->prompt_screen = ssi;
- if (si->prefs.verbose_p)
- fprintf (stderr, "%s: %d: creating password dialog.\n",
- blurb(), pw->prompt_screen->number);
screen = pw->prompt_screen->screen;
cmap = DefaultColormapOfScreen (screen);
pw->prompt_screen = ssi;
if (si->prefs.verbose_p)
- fprintf (stderr, "%s: %d: creating password dialog.\n",
- blurb(), pw->prompt_screen->number);
+ fprintf (stderr, "%s: %d: creating password dialog (\"%s\")\n",
+ blurb(), pw->prompt_screen->number,
+ info_msg ? info_msg : "");
screen = pw->prompt_screen->screen;
cmap = DefaultColormapOfScreen (screen);
if (si->passwd_dialog)
{
+ if (si->prefs.verbose_p)
+ fprintf (stderr, "%s: %d: destroying password dialog.\n",
+ blurb(), pw->prompt_screen->number);
+
XDestroyWindow (si->dpy, si->passwd_dialog);
si->passwd_dialog = 0;
}
saver_preferences *p = &si->prefs;
char *msg = 0;
XEvent event;
- unsigned int caps_p = 0;
passwd_animate_timer ((XtPointer) si, 0);
else if (event.xany.type == KeyPress)
{
handle_passwd_key (si, &event.xkey);
- caps_p = (event.xkey.state & LockMask);
+ si->pw_data->caps_p = (event.xkey.state & LockMask);
}
else if (event.xany.type == ButtonPress ||
event.xany.type == ButtonRelease)
default: msg = 0; break;
}
- if (si->unlock_state == ul_fail)
- si->unlock_failures++;
-
if (p->verbose_p)
- switch (si->unlock_state)
- {
- case ul_fail:
- fprintf (stderr, "%s: auth/input incorrect!%s\n", blurb(),
- (caps_p ? " (CapsLock)" : ""));
- break;
- case ul_cancel:
- fprintf (stderr, "%s: input cancelled.\n", blurb()); break;
- case ul_time:
- fprintf (stderr, "%s: input timed out.\n", blurb()); break;
- case ul_finished:
- fprintf (stderr, "%s: input finished.\n", blurb()); break;
- default: break;
- }
-
-#ifdef HAVE_SYSLOG
- if (si->unlock_state == ul_fail)
- {
- /* If they typed a password (as opposed to just hitting return) and
- the password was invalid, log it.
- */
- struct passwd *pw = getpwuid (getuid ());
- char *d = DisplayString (si->dpy);
- char *u = (pw && pw->pw_name ? pw->pw_name : "???");
- int opt = 0;
- int fac = 0;
-
-# ifdef LOG_PID
- opt = LOG_PID;
-# endif
-
-# if defined(LOG_AUTHPRIV)
- fac = LOG_AUTHPRIV;
-# elif defined(LOG_AUTH)
- fac = LOG_AUTH;
-# else
- fac = LOG_DAEMON;
-# endif
-
- if (!d) d = "";
- openlog (progname, opt, fac);
- syslog (LOG_NOTICE, "FAILED LOGIN %d ON DISPLAY \"%s\", FOR \"%s\"",
- si->unlock_failures, d, u);
- closelog ();
- }
-#endif /* HAVE_SYSLOG */
-
- if (si->unlock_state == ul_fail)
- XBell (si->dpy, False);
-
- if (si->unlock_state == ul_success && si->unlock_failures != 0)
- {
- if (si->unlock_failures == 1)
- fprintf (real_stderr,
- "%s: WARNING: 1 failed attempt to unlock the screen.\n",
- blurb());
- else
- fprintf (real_stderr,
- "%s: WARNING: %d failed attempts to unlock the screen.\n",
- blurb(), si->unlock_failures);
- fflush (real_stderr);
-
- si->unlock_failures = 0;
+ switch (si->unlock_state) {
+ case ul_cancel:
+ fprintf (stderr, "%s: input cancelled.\n", blurb()); break;
+ case ul_time:
+ fprintf (stderr, "%s: input timed out.\n", blurb()); break;
+ case ul_finished:
+ fprintf (stderr, "%s: input finished.\n", blurb()); break;
+ default: break;
}
if (msg)
void
auth_finished_cb (saver_info *si)
{
- if (si->unlock_state == ul_fail)
- {
- make_passwd_window (si, "Authentication failed!", NULL, True);
- sleep (2); /* Not very nice, I know */
+ char buf[1024];
+ const char *s;
- /* Swallow any keyboard or mouse events that were received while the
- * dialog was up */
- {
- XEvent e;
- long mask = (KeyPressMask | KeyReleaseMask |
- ButtonPressMask | ButtonReleaseMask);
- while (XCheckMaskEvent (si->dpy, mask, &e))
- ;
- }
+ /* If we have something to say, put the dialog back up for a few seconds
+ to display it. Otherwise, don't bother.
+ */
+
+ if (si->unlock_state == ul_fail && /* failed with caps lock on */
+ si->pw_data && si->pw_data->caps_p)
+ s = "Authentication failed (Caps Lock?)";
+ else if (si->unlock_state == ul_fail) /* failed without caps lock */
+ s = "Authentication failed!";
+ else if (si->unlock_state == ul_success && /* good, but report failures */
+ si->unlock_failures > 0)
+ {
+ if (si->unlock_failures == 1)
+ s = "There has been\n1 failed login attempt.";
+ else
+ {
+ sprintf (buf, "There have been\n%d failed login attempts.",
+ si->unlock_failures);
+ s = buf;
+ }
+ si->unlock_failures = 0;
}
+ else /* good, with no failures, */
+ goto END; /* or timeout, or cancel. */
+
+ make_passwd_window (si, s, NULL, True);
+ XSync (si->dpy, False);
+ {
+ int secs = 4;
+ time_t start = time ((time_t *) 0);
+ XEvent event;
+ while (time ((time_t *) 0) < start + secs)
+ if (XPending (si->dpy))
+ {
+ XNextEvent (si->dpy, &event);
+ if (event.xany.window == si->passwd_dialog &&
+ event.xany.type == Expose)
+ draw_passwd_window (si);
+ else if (event.xany.type == ButtonPress ||
+ event.xany.type == ButtonRelease)
+ break;
+ XSync (si->dpy, False);
+ }
+ else
+ usleep (250000); /* 1/4 second */
+ }
+
+ END:
if (si->pw_data)
destroy_passwd_window (si);
}
raise_window (si, True, True, True);
- if (p->verbose_p)
- fprintf (stderr, "%s: prompting for password.\n", blurb());
-
xss_authenticate(si, p->verbose_p);
return (si->unlock_state == ul_success);