http://www.tienza.es/crux/src/www.jwz.org/xscreensaver/xscreensaver-5.05.tar.gz
[xscreensaver] / driver / lock.c
index 4e1d0b547a9193c1d00ed8a72386c07fde200362..e1d29dc92a958b31d8cbf3b6489e5997df8d012b 100644 (file)
 
 #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);
@@ -112,6 +108,7 @@ struct passwd_dialog_data {
   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;
@@ -203,9 +200,6 @@ new_passwd_window (saver_info *si)
   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);
@@ -444,8 +438,9 @@ make_passwd_window (saver_info *si,
 
   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);
@@ -1289,6 +1284,10 @@ destroy_passwd_window (saver_info *si)
 
   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;
     }
@@ -1763,7 +1762,6 @@ passwd_event_loop (saver_info *si)
   saver_preferences *p = &si->prefs;
   char *msg = 0;
   XEvent event;
-  unsigned int caps_p = 0;
 
   passwd_animate_timer ((XtPointer) si, 0);
 
@@ -1775,7 +1773,7 @@ passwd_event_loop (saver_info *si)
       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)
@@ -1797,73 +1795,15 @@ passwd_event_loop (saver_info *si)
     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)
@@ -2050,22 +1990,58 @@ fail:
 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);
 }
@@ -2084,9 +2060,6 @@ unlock_p (saver_info *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);