SOURCES: kdebase-branch.diff - apply post-3.4.2-kdebase-kcheckpass...

arekm arekm at pld-linux.org
Mon Sep 5 14:04:52 CEST 2005


Author: arekm                        Date: Mon Sep  5 12:04:52 2005 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- apply post-3.4.2-kdebase-kcheckpass.diff security patch

---- Files affected:
SOURCES:
   kdebase-branch.diff (1.18 -> 1.19) 

---- Diffs:

================================================================
Index: SOURCES/kdebase-branch.diff
diff -u SOURCES/kdebase-branch.diff:1.18 SOURCES/kdebase-branch.diff:1.19
--- SOURCES/kdebase-branch.diff:1.18	Mon Sep  5 14:04:18 2005
+++ SOURCES/kdebase-branch.diff	Mon Sep  5 14:04:46 2005
@@ -7825,3 +7825,159 @@
    + admin https://svn.kde.org/home/kde/branches/KDE/3.4/kde-common/admin
 
 
+Index: kcheckpass.c
+===================================================================
+--- kcheckpass/kcheckpass.c	(revision 453871)
++++ kcheckpass/kcheckpass.c	(working copy)
+@@ -14,7 +14,7 @@
+  *
+  * You should have received a copy of the GNU General Public
+  * License along with this program; if not, write to the Free
+- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++ * Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA  02110-1301, USA.
+  *
+  *
+  *	kcheckpass is a simple password checker. Just invoke and
+@@ -264,8 +264,13 @@
+ 
+   va_start(ap, fmt);
+   vfprintf(stderr, fmt, ap);
++  va_end(ap);
+ }
+ 
++#ifndef O_NOFOLLOW
++# define O_NOFOLLOW 0
++#endif
++
+ static void ATTR_NORETURN
+ usage(int exitval)
+ {
+@@ -286,6 +291,14 @@
+   exit(exitval);
+ }
+ 
++static int exclusive_lock(int fd)
++{
++  struct flock lk;
++  lk.l_type = F_WRLCK;
++  lk.l_whence = SEEK_SET;
++  lk.l_start = lk.l_len = 0;
++  return fcntl(fd, F_SETLKW, &lk);
++}
+ 
+ int
+ main(int argc, char **argv)
+@@ -299,10 +312,13 @@
+   char		*p;
+ #endif
+   struct passwd	*pw;
+-  int		c, nfd, lfd, numtries;
++  int		c, nfd, tfd, lfd;
+   uid_t		uid;
+-  long		lasttime;
++  time_t	lasttime;
+   AuthReturn	ret;
++  char tmpname[64], fname[64], fcont[64];
++  time_t left = 3;
++  lfd = tfd = 0;
+ 
+ #ifdef HAVE_OSF_C2_PASSWD
+   initialize_osf_security(argc, argv);
+@@ -371,6 +387,41 @@
+       return AuthError;
+     }
+   }
++
++  /* see if we had already a failed attempt */
++  if ( uid != geteuid() ) {
++    strcpy(tmpname, "/var/lock/kcheckpass.tmp.XXXXXX");
++    if ((tfd=mkstemp(tmpname)) < 0)
++      return AuthError;
++
++    /* try locking out concurrent kcheckpass processes */
++    exclusive_lock(tfd);
++    
++    write(tfd, fcont, sprintf(fcont, "%lu\n", time(0)+left));
++    (void) lseek(tfd, 0, SEEK_SET);
++
++    sprintf(fname, "/var/lock/kcheckpass.%d", uid );
++
++    if ((lfd = open(fname, O_RDWR | O_NOFOLLOW)) >= 0) {
++      if (exclusive_lock(lfd) == 0) {
++        if ((c = read(lfd, fcont, sizeof(fcont)-1)) > 0 &&
++	    (fcont[c] = '\0', sscanf(fcont, "%ld", &lasttime) == 1))
++	  {
++            time_t ct = time(0);
++
++	    /* in case we were killed early, sleep the remaining time
++	     * to properly enforce invocation throttling and make sure
++	     * that users can't use kcheckpass for bruteforcing password
++             */
++            if(lasttime > ct && lasttime < ct + left)
++              sleep (lasttime - ct);
++          }
++      }
++      close(lfd);
++    }
++    rename(tmpname, fname);
++  }
++
+   /* Now do the fandango */
+   ret = Authenticate(
+ #ifdef HAVE_PAM
+@@ -379,35 +430,21 @@
+                      method,
+                      username, 
+                      sfd < 0 ? conv_legacy : conv_server);
++
+   if (ret == AuthOk || ret == AuthBad) {
+     /* Security: Don't undermine the shadow system. */
+     if (uid != geteuid()) {
+-      char fname[32], fcont[32];
+-      sprintf(fname, "/var/lock/kcheckpass.%d", uid);
+-      if ((lfd = open(fname, O_RDWR | O_CREAT)) >= 0) {
+-        struct flock lk;
+-        lk.l_type = F_WRLCK;
+-        lk.l_whence = SEEK_SET;
+-        lk.l_start = lk.l_len = 0;
+-	if (fcntl(lfd, F_SETLKW, &lk))
+-          return AuthError;
+-        if ((c = read(lfd, fcont, sizeof(fcont))) > 0 &&
+-            (fcont[c] = 0, sscanf(fcont, "%ld %d\n", &lasttime, &numtries) == 2))
+-        {
+-          time_t left = lasttime - time(0);
+-          if (numtries < 20)
+-            numtries++;
+-          left += 2 << (numtries > 10 ? numtries - 10 : 0);
+-          if (left > 0)
+-            sleep(left);
+-        } else
+-          numtries = 0;
+-        if (ret == AuthBad) {
+-          lseek(lfd, 0, SEEK_SET);
+-          write(lfd, fcont, sprintf(fcont, "%ld %d\n", time(0), numtries));
+-        } else
+-          unlink(fname);
+-      }
++      if (ret == AuthBad) {
++        write(tfd, fcont, sprintf(fcont, "%lu\n", time(0)+left));
++      } else
++        unlink(fname);
++	
++      unlink(tmpname);
++
++      if (ret == AuthBad)
++        sleep(left);  
++
++      close(tfd);
+     }
+     if (ret == AuthBad) {
+       message("Authentication failure\n");
+@@ -417,6 +454,7 @@
+       }
+     }
+   }
++
+   return ret;
+ }
+ 
================================================================

---- CVS-web:
    http://cvs.pld-linux.org/SOURCES/kdebase-branch.diff?r1=1.18&r2=1.19&f=u




More information about the pld-cvs-commit mailing list