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;
}