On Thu, May 29, 2003 at 03:34:30PM +0200, Oliver Graf wrote:
> On Thu, May 29, 2003 at 03:19:59PM +0300, Kostas Kalevras wrote:
> > > It now locks while using crypt. This is only good, if this is the only
> > > use of crypt. If pap (for example) is also used, it should use the
> > > same mutex to lock while doing an crypt (as should do any other
> > > freeradius code using crypt).
> > >
> > > The server seems running und is responsive :) the next hours will show
> > > if the problem is fixed with this.
> > 
> > OK, then declare a new function radius_crypt() with a mutex in it, put it
> > somewhere in src/lib and change all calls  to crypt() to call radius_crypt()
> > instead.
> 
> Yep, I had something like this in mind. But now I will fetch me some
> beer, fire the barbecue and have a nice Vatertag :)
> 
> I'll write the clean version tomorrow.

Ok, here it is. I have now one radiusd with the old version, and one with
this version running (both production systems :) ).

The function lrad_crypt_check does crypt and check in one, cause the
return value of crypt might be a reused string buffer...

Is this a good place for the mutex? Or is it better to have some init
function for the mutex which is called from threads.c?

Oliver.

--- src/lib/crypt.c.orig        2003-05-30 09:40:29.000000000 +0200
+++ src/lib/crypt.c     2003-05-30 09:29:16.000000000 +0200
@@ -0,0 +1,61 @@
+/*
+ * a thread-safe crypt wrapper
+ */
+
+#include "libradius.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#if HAVE_PTHREAD_H
+#include       <pthread.h>
+#endif
+
+static int lrad_crypt_init=0;
+static pthread_mutex_t lrad_crypt_mutex;
+
+/*
+ * initializes authcrypt_mutex
+ */
+
+
+/*
+ * performs a crypt password check in an thread-safe way.
+ *
+ * returns:  0 -- check succeeded
+ *          -1 -- failed to crypt
+ *           1 -- check failed
+ */
+int lrad_crypt_check(const char *key, const char *crypted) {
+  char *libc_crypted=NULL, *our_crypted=NULL;
+  int result=0;
+
+#if HAVE_PTHREAD_H
+  if (!lrad_crypt_init == 0) {
+       pthread_mutex_init(&lrad_crypt_mutex, NULL);
+       lrad_crypt_init=1;
+  }
+
+  pthread_mutex_lock(&lrad_crypt_mutex);
+#endif
+
+  libc_crypted=crypt(key,crypted);
+  if (libc_crypted)
+       our_crypted=strdup(libc_crypted);
+
+#if HAVE_PTHREAD_H
+  pthread_mutex_unlock(&lrad_crypt_mutex);
+#endif
+
+  if (our_crypted == NULL)
+       return -1;
+
+  if (strcmp(crypted, our_crypted) == 0)
+       result = 0;
+  else
+       result = 1;
+
+  free(our_crypted);
+
+  return result;
+}
Index: src/lib/Makefile
===================================================================
RCS file: /source/radiusd/src/lib/Makefile,v
retrieving revision 1.14
diff -u -r1.14 Makefile
--- src/lib/Makefile    3 Mar 2003 19:48:06 -0000       1.14
+++ src/lib/Makefile    30 May 2003 08:03:54 -0000
@@ -3,7 +3,7 @@
 
 SRCS           = dict.c print.c radius.c valuepair.c token.c misc.c \
                log.c filters.c missing.c md4.c md5.c sha1.c hmac.c \
-               snprintf.c isaac.c smbdes.c
+               snprintf.c isaac.c smbdes.c crypt.c
 
 INCLUDES       = ../include/radius.h ../include/libradius.h \
                  ../include/missing.h ../include/autoconf.h
Index: src/include/libradius.h
===================================================================
RCS file: /source/radiusd/src/include/libradius.h,v
retrieving revision 1.58
diff -u -r1.58 libradius.h
--- src/include/libradius.h     21 Apr 2003 20:39:57 -0000      1.58
+++ src/include/libradius.h     30 May 2003 08:03:54 -0000
@@ -298,4 +298,7 @@
                 const unsigned char *challenge, unsigned char *response);
 
 
+/* crypt wrapper from crypt.c */
+int lrad_crypt_check(const char *key, const char *crypted);
+
 #endif /*LIBRADIUS_H*/
Index: src/main/auth.c
===================================================================
RCS file: /source/radiusd/src/main/auth.c,v
retrieving revision 1.125
diff -u -r1.125 auth.c
--- src/main/auth.c     10 Apr 2003 18:09:03 -0000      1.125
+++ src/main/auth.c     30 May 2003 08:03:55 -0000
@@ -31,10 +31,6 @@
 #include <string.h>
 #include <ctype.h>
 
-#if HAVE_CRYPT_H
-#      include <crypt.h>
-#endif
-
 #if HAVE_NETINET_IN_H
 #      include <netinet/in.h>
 #endif
@@ -190,7 +186,6 @@
        VALUE_PAIR *password_pair;
        VALUE_PAIR *auth_item;
        char string[MAX_STRING_LEN];
-       const char *crypted_password;
        int auth_type = -1;
        int result;
        int auth_type_count = 0;
@@ -276,16 +271,13 @@
                                return -1;
                        }
                                        
-                       crypted_password = crypt((char *)auth_item->strvalue,
-                                                (char *)password_pair->strvalue);
-                       if (!crypted_password) {
-                               rad_authlog("Login incorrect "
-                                           "(system failed to supply an encrypted 
password for comparison)", request, 0);
-                               return -1;
-                       }
-                       if (strcmp((char *)password_pair->strvalue,
-                                  crypted_password) != 0) {
-                               return -1;
+                       switch (lrad_crypt_check((char *)auth_item->strvalue,
+                                                                        (char 
*)password_pair->strvalue)) {
+                       case -1:
+                         rad_authlog("Login incorrect "
+                                                 "(system failed to supply an 
encrypted password for comparison)", request, 0);
+                       case 1:
+                         return -1;
                        }
                        break;
                case PW_AUTHTYPE_LOCAL:
Index: src/modules/rlm_pap/rlm_pap.c
===================================================================
RCS file: /source/radiusd/src/modules/rlm_pap/rlm_pap.c,v
retrieving revision 1.11
diff -u -r1.11 rlm_pap.c
--- src/modules/rlm_pap/rlm_pap.c       23 Jan 2003 20:54:46 -0000      1.11
+++ src/modules/rlm_pap/rlm_pap.c       30 May 2003 08:03:55 -0000
@@ -58,9 +58,6 @@
 typedef struct rlm_pap_t {
         char *scheme;  /* password encryption scheme */
        int sch;
-#if HAVE_PTHREAD_H
-       pthread_mutex_t mutex;  
-#endif
 } rlm_pap_t;
 
 /*
@@ -124,9 +121,6 @@
                inst->sch = PAP_ENC_CLEAR;
        else if (strcasecmp(inst->scheme,"crypt") == 0){
                inst->sch = PAP_ENC_CRYPT;
-#if HAVE_PTHREAD_H
-               pthread_mutex_init(&inst->mutex, NULL);
-#endif
        }
        else if (strcasecmp(inst->scheme,"md5") == 0)
                inst->sch = PAP_ENC_MD5;
@@ -221,25 +215,14 @@
                        break;
                case PAP_ENC_CRYPT:
                        DEBUG("rlm_pap: Using CRYPT encryption.");
-#if HAVE_PTHREAD_H
-                       pthread_mutex_lock(&inst->mutex);
-#endif
-                       if (strcmp((char *) passwd_item->strvalue,
-                                  crypt((char *) request->password->strvalue,
-                                        (char *) passwd_item->strvalue)) != 0) {
-#if HAVE_PTHREAD_H
-                               pthread_mutex_unlock(&inst->mutex);
-#endif
+                       if (lrad_crypt_check((char *) request->password->strvalue,
+                                                                (char *) 
passwd_item->strvalue) != 0) {
                                DEBUG("rlm_pap: Passwords don't match");
                                snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: 
CRYPT password check failed");
                                module_fmsg_vp = 
pairmake("Module-Failure-Message",module_fmsg, T_OP_EQ);
                                pairadd(&request->packet->vps, module_fmsg_vp);
                                return RLM_MODULE_REJECT;
                        }
-#if HAVE_PTHREAD_H
-                       else
-                               pthread_mutex_unlock(&inst->mutex);
-#endif
                        break;
                case PAP_ENC_MD5:
                        DEBUG("rlm_pap: Using MD5 encryption.");
@@ -301,10 +284,6 @@
 {
        rlm_pap_t *inst = (rlm_pap_t *) instance;
 
-#if HAVE_PTHREAD_H
-       if (inst->sch == PAP_ENC_CRYPT)
-               pthread_mutex_destroy(&inst->mutex);
-#endif
        PAP_INST_FREE(inst);
        return 0;
 }
Index: src/modules/rlm_unix/cache.c
===================================================================
RCS file: /source/radiusd/src/modules/rlm_unix/cache.c,v
retrieving revision 1.21
diff -u -r1.21 cache.c
--- src/modules/rlm_unix/cache.c        2 Jan 2002 17:41:45 -0000       1.21
+++ src/modules/rlm_unix/cache.c        30 May 2003 08:03:55 -0000
@@ -50,10 +50,6 @@
 #  include <shadow.h>
 #endif
 
-#if HAVE_CRYPT_H
-#  include <crypt.h>
-#endif 
-
 #include "radiusd.h"
 #include "cache.h"
 #include "compat.h"
@@ -458,7 +454,6 @@
 {
        struct mypasswd *pwd;
        char *encrypted_pass;
-       char *encpw;
 
        /*
         *      Get encrypted password from password file
@@ -491,11 +486,10 @@
                                return 0;
                        }
        
-                       encpw = (char *)crypt(passwd, encrypted_pass);
                        /* 
                         * Check password
                         */
-                       if(strcmp(encpw, encrypted_pass) == 0) {
+                       if(lrad_crypt_check(passwd, encrypted_pass) == 0) {
                                /* 
                                 * Add 'Class' pair here with value of full
                                 * name from passwd
@@ -515,9 +509,7 @@
                /*
                 *      Check encrypted password.
                 */
-               encpw = (char *)crypt(passwd, encrypted_pass);
-
-               if (strcmp(encpw, encrypted_pass))
+               if (lrad_crypt_check(passwd, encrypted_pass))
                        return -1;
 
                return 0;
Index: src/modules/rlm_unix/rlm_unix.c
===================================================================
RCS file: /source/radiusd/src/modules/rlm_unix/rlm_unix.c,v
retrieving revision 1.55
diff -u -r1.55 rlm_unix.c
--- src/modules/rlm_unix/rlm_unix.c     14 May 2003 08:49:15 -0000      1.55
+++ src/modules/rlm_unix/rlm_unix.c     30 May 2003 08:03:55 -0000
@@ -41,10 +41,6 @@
 #  include     <shadow.h>
 #endif
 
-#if HAVE_CRYPT_H
-#  include <crypt.h>
-#endif
-
 #ifdef OSFC2
 #  include     <sys/security.h>
 #  include     <prot.h>
@@ -365,7 +361,6 @@
 #define inst ((struct unix_instance *)instance)
        char *name, *passwd;
        struct passwd   *pwd;
-       char            *encpw;
        const char      *encrypted_pass;
        int             ret;
 #if HAVE_GETSPNAM
@@ -601,8 +596,7 @@
        /*
         *      Check encrypted password.
         */
-       encpw = crypt(passwd, encrypted_pass);
-       if (strcmp(encpw, encrypted_pass)) {
+       if (lrad_crypt_check(passwd, encrypted_pass)) {
                radlog(L_AUTH, "rlm_unix: [%s]: invalid password", name);
                return RLM_MODULE_REJECT;
        }

Reply via email to