diff options
author | Stefan Fritsch <sf@apache.org> | 2012-07-05 18:02:28 +0000 |
---|---|---|
committer | Stefan Fritsch <sf@apache.org> | 2012-07-05 18:02:28 +0000 |
commit | 4ca99696c1bed1e31343175d37c87ea77758293a (patch) | |
tree | ffa478ec459f79cdefcb963073af9158c9c64275 | |
parent | 5199258e1388517e2324144c2605cd0145af3a36 (diff) | |
download | apr-4ca99696c1bed1e31343175d37c87ea77758293a.tar.gz |
Move non-MD5-related things from apr_md5.c to new file apr_passwd.c
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1357772 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | build.conf | 1 | ||||
-rw-r--r-- | crypto/apr_md5.c | 145 | ||||
-rw-r--r-- | crypto/apr_passwd.c | 169 |
3 files changed, 171 insertions, 144 deletions
diff --git a/build.conf b/build.conf index 4933d15cd..fc110e2eb 100644 --- a/build.conf +++ b/build.conf @@ -13,6 +13,7 @@ paths = crypto/apr_crypto.c crypto/apr_md4.c crypto/apr_md5.c + crypto/apr_passwd.c crypto/apr_sha1.c crypto/getuuid.c crypto/uuid.c diff --git a/crypto/apr_md5.c b/crypto/apr_md5.c index d618a459b..d685322c0 100644 --- a/crypto/apr_md5.c +++ b/crypto/apr_md5.c @@ -61,20 +61,10 @@ #include "apr_md5.h" #include "apr_lib.h" #include "apr_private.h" -#include "apr_sha1.h" #if APR_HAVE_STRING_H #include <string.h> #endif -#if APR_HAVE_CRYPT_H -#include <crypt.h> -#endif -#if APR_HAVE_UNISTD_H -#include <unistd.h> -#endif -#if APR_HAVE_PTHREAD_H -#include <pthread.h> -#endif /* Constants for MD5Transform routine. */ @@ -478,7 +468,7 @@ APR_DECLARE(apr_status_t) apr_MD5InitEBCDIC(apr_xlate_t *xlate) * Define the Magic String prefix that identifies a password as being * hashed using our algorithm. */ -static const char *apr1_id = "$apr1$"; +static const char const *apr1_id = "$apr1$"; /* * The following MD5 password encryption code was largely borrowed from @@ -660,136 +650,3 @@ APR_DECLARE(apr_status_t) apr_md5_encode(const char *pw, const char *salt, apr_cpystrn(result, passwd, nbytes - 1); return APR_SUCCESS; } - -#if !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) -#if defined(APU_CRYPT_THREADSAFE) || !APR_HAS_THREADS || \ - defined(CRYPT_R_CRYPTD) || defined(CRYPT_R_STRUCT_CRYPT_DATA) - -#define crypt_mutex_lock() -#define crypt_mutex_unlock() - -#elif APR_HAVE_PTHREAD_H && defined(PTHREAD_MUTEX_INITIALIZER) - -static pthread_mutex_t crypt_mutex = PTHREAD_MUTEX_INITIALIZER; -static void crypt_mutex_lock(void) -{ - pthread_mutex_lock(&crypt_mutex); -} - -static void crypt_mutex_unlock(void) -{ - pthread_mutex_unlock(&crypt_mutex); -} - -#elif defined(OS2) - -static HMTX crypt_mutex = 0; -static void crypt_mutex_lock() -{ - if (crypt_mutex == 0) { - /* Prevent race condition where two threads could try to create the - * mutex concurrently - */ - DosEnterCritSec(); - - if (crypt_mutex == 0) { - DosCreateMutexSem(NULL, &crypt_mutex, 0, FALSE); - } - - DosExitCritSec(); - } - - DosRequestMutexSem(crypt_mutex, SEM_INDEFINITE_WAIT); -} - -static void crypt_mutex_unlock() -{ - DosReleaseMutexSem(crypt_mutex); -} - -#else - -#error apr_password_validate() is not threadsafe. rebuild APR without thread support. - -#endif -#endif - -/* - * Validate a plaintext password against a smashed one. Uses either - * crypt() (if available) or apr_md5_encode() or apr_sha1_base64(), depending - * upon the format of the smashed input password. Returns APR_SUCCESS if - * they match, or APR_EMISMATCH if they don't. If the platform doesn't - * support crypt, then the default check is against a clear text string. - */ -APR_DECLARE(apr_status_t) apr_password_validate(const char *passwd, - const char *hash) -{ - char sample[120]; -#if !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) - char *crypt_pw; -#endif - if (!strncmp(hash, apr1_id, strlen(apr1_id))) { - /* - * The hash was created using our custom algorithm. - */ - apr_md5_encode(passwd, hash, sample, sizeof(sample)); - } - else if (!strncmp(hash, APR_SHA1PW_ID, APR_SHA1PW_IDLEN)) { - apr_sha1_base64(passwd, (int)strlen(passwd), sample); - } - else { - /* - * It's not our algorithm, so feed it to crypt() if possible. - */ -#if defined(WIN32) || defined(BEOS) || defined(NETWARE) - apr_cpystrn(sample, passwd, sizeof(sample) - 1); -#elif defined(CRYPT_R_CRYPTD) - CRYPTD buffer; - - crypt_pw = crypt_r(passwd, hash, &buffer); - if (!crypt_pw) { - return APR_EMISMATCH; - } - apr_cpystrn(sample, crypt_pw, sizeof(sample) - 1); -#elif defined(CRYPT_R_STRUCT_CRYPT_DATA) - struct crypt_data buffer; - -#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2,4) - buffer.initialized = 0; -#else - /* - * glibc before 2.3.2 had a bug that required clearing the - * whole struct - */ - memset(&buffer, 0, sizeof(buffer)); -#endif - crypt_pw = crypt_r(passwd, hash, &buffer); - if (!crypt_pw) { - return APR_EMISMATCH; - } - apr_cpystrn(sample, crypt_pw, sizeof(sample) - 1); -#else - /* Do a bit of sanity checking since we know that crypt_r() - * should always be used for threaded builds on AIX, and - * problems in configure logic can result in the wrong - * choice being made. - */ -#if defined(_AIX) && APR_HAS_THREADS -#error Configuration error! crypt_r() should have been selected! -#endif - - /* Handle thread safety issues by holding a mutex around the - * call to crypt(). - */ - crypt_mutex_lock(); - crypt_pw = crypt(passwd, hash); - if (!crypt_pw) { - crypt_mutex_unlock(); - return APR_EMISMATCH; - } - apr_cpystrn(sample, crypt_pw, sizeof(sample) - 1); - crypt_mutex_unlock(); -#endif - } - return (strcmp(sample, hash) == 0) ? APR_SUCCESS : APR_EMISMATCH; -} diff --git a/crypto/apr_passwd.c b/crypto/apr_passwd.c new file mode 100644 index 000000000..7b236c599 --- /dev/null +++ b/crypto/apr_passwd.c @@ -0,0 +1,169 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_strings.h" +#include "apr_md5.h" +#include "apr_lib.h" +#include "apr_private.h" +#include "apr_sha1.h" + +#if APR_HAVE_STRING_H +#include <string.h> +#endif +#if APR_HAVE_CRYPT_H +#include <crypt.h> +#endif +#if APR_HAVE_UNISTD_H +#include <unistd.h> +#endif +#if APR_HAVE_PTHREAD_H +#include <pthread.h> +#endif + +static const char const *apr1_id = "$apr1$"; + +#if !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) +#if defined(APU_CRYPT_THREADSAFE) || !APR_HAS_THREADS || \ + defined(CRYPT_R_CRYPTD) || defined(CRYPT_R_STRUCT_CRYPT_DATA) + +#define crypt_mutex_lock() +#define crypt_mutex_unlock() + +#elif APR_HAVE_PTHREAD_H && defined(PTHREAD_MUTEX_INITIALIZER) + +static pthread_mutex_t crypt_mutex = PTHREAD_MUTEX_INITIALIZER; +static void crypt_mutex_lock(void) +{ + pthread_mutex_lock(&crypt_mutex); +} + +static void crypt_mutex_unlock(void) +{ + pthread_mutex_unlock(&crypt_mutex); +} + +#elif defined(OS2) + +static HMTX crypt_mutex = 0; +static void crypt_mutex_lock() +{ + if (crypt_mutex == 0) { + /* Prevent race condition where two threads could try to create the + * mutex concurrently + */ + DosEnterCritSec(); + + if (crypt_mutex == 0) { + DosCreateMutexSem(NULL, &crypt_mutex, 0, FALSE); + } + + DosExitCritSec(); + } + + DosRequestMutexSem(crypt_mutex, SEM_INDEFINITE_WAIT); +} + +static void crypt_mutex_unlock() +{ + DosReleaseMutexSem(crypt_mutex); +} + +#else + +#error apr_password_validate() is not threadsafe. rebuild APR without thread support. + +#endif +#endif + +/* + * Validate a plaintext password against a smashed one. Uses either + * crypt() (if available) or apr_md5_encode() or apr_sha1_base64(), depending + * upon the format of the smashed input password. Returns APR_SUCCESS if + * they match, or APR_EMISMATCH if they don't. If the platform doesn't + * support crypt, then the default check is against a clear text string. + */ +APR_DECLARE(apr_status_t) apr_password_validate(const char *passwd, + const char *hash) +{ + char sample[120]; +#if !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) + char *crypt_pw; +#endif + if (!strncmp(hash, apr1_id, strlen(apr1_id))) { + /* + * The hash was created using our custom algorithm. + */ + apr_md5_encode(passwd, hash, sample, sizeof(sample)); + } + else if (!strncmp(hash, APR_SHA1PW_ID, APR_SHA1PW_IDLEN)) { + apr_sha1_base64(passwd, (int)strlen(passwd), sample); + } + else { + /* + * It's not our algorithm, so feed it to crypt() if possible. + */ +#if defined(WIN32) || defined(BEOS) || defined(NETWARE) + apr_cpystrn(sample, passwd, sizeof(sample) - 1); +#elif defined(CRYPT_R_CRYPTD) + CRYPTD buffer; + + crypt_pw = crypt_r(passwd, hash, &buffer); + if (!crypt_pw) { + return APR_EMISMATCH; + } + apr_cpystrn(sample, crypt_pw, sizeof(sample) - 1); +#elif defined(CRYPT_R_STRUCT_CRYPT_DATA) + struct crypt_data buffer; + +#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2,4) + buffer.initialized = 0; +#else + /* + * glibc before 2.3.2 had a bug that required clearing the + * whole struct + */ + memset(&buffer, 0, sizeof(buffer)); +#endif + crypt_pw = crypt_r(passwd, hash, &buffer); + if (!crypt_pw) { + return APR_EMISMATCH; + } + apr_cpystrn(sample, crypt_pw, sizeof(sample) - 1); +#else + /* Do a bit of sanity checking since we know that crypt_r() + * should always be used for threaded builds on AIX, and + * problems in configure logic can result in the wrong + * choice being made. + */ +#if defined(_AIX) && APR_HAS_THREADS +#error Configuration error! crypt_r() should have been selected! +#endif + + /* Handle thread safety issues by holding a mutex around the + * call to crypt(). + */ + crypt_mutex_lock(); + crypt_pw = crypt(passwd, hash); + if (!crypt_pw) { + crypt_mutex_unlock(); + return APR_EMISMATCH; + } + apr_cpystrn(sample, crypt_pw, sizeof(sample) - 1); + crypt_mutex_unlock(); +#endif + } + return (strcmp(sample, hash) == 0) ? APR_SUCCESS : APR_EMISMATCH; +} |