[core] Provide safe wrapper for crypt if crypt_r is not available
parent
9dd5a0c4db
commit
ab9421a5e1
|
@ -305,6 +305,7 @@ AC_ARG_ENABLE(profiler,
|
|||
|
||||
AM_CONDITIONAL([WITH_PROFILER], [test "x$profiler" = "xyes"])
|
||||
|
||||
dnl search for crypt_r and (fallback) for crypt
|
||||
save_LIBS=$LIBS
|
||||
LIBS=
|
||||
AC_SEARCH_LIBS(crypt_r,crypt,[
|
||||
|
@ -314,6 +315,14 @@ AC_SEARCH_LIBS(crypt_r,crypt,[
|
|||
])
|
||||
|
||||
CRYPT_LIB=$LIBS
|
||||
],[
|
||||
AC_SEARCH_LIBS(crypt,crypt,[
|
||||
AC_CHECK_HEADERS([crypt.h],[
|
||||
AC_DEFINE([HAVE_CRYPT_H], [1], [crypt.h])
|
||||
])
|
||||
|
||||
CRYPT_LIB=$LIBS
|
||||
])
|
||||
])
|
||||
LIBS=$save_LIBS
|
||||
AC_SUBST(CRYPT_LIB)
|
||||
|
|
|
@ -101,6 +101,8 @@ LI_API gsize li_dirent_buf_size(DIR * dirp);
|
|||
LI_API void li_apr_sha1_base64(GString *dest, const GString *passwd);
|
||||
LI_API void li_apr_md5_crypt(GString *dest, const GString *password, const GString *salt);
|
||||
|
||||
LI_API void li_safe_crypt(GString *dest, const GString *password, const GString *salt);
|
||||
|
||||
INLINE GString* _li_g_string_append_len(GString *s, const gchar *val, gssize len);
|
||||
INLINE void li_g_string_clear(GString *s);
|
||||
|
||||
|
|
|
@ -50,12 +50,15 @@ CHECK_INCLUDE_FILES(execinfo.h HAVE_EXECINFO_H)
|
|||
CHECK_INCLUDE_FILES(crypt.h HAVE_CRYPT_H)
|
||||
IF(HAVE_CRYPT_H)
|
||||
# check if we need libcrypt for crypt_r()
|
||||
CHECK_LIBRARY_EXISTS(crypt crypt_r "" HAVE_LIBCRYPT)
|
||||
CHECK_LIBRARY_EXISTS(crypt crypt_r "" HAVE_LIBCRYPT_CRYPT_R)
|
||||
IF(HAVE_LIBCRYPT_CRYPT_R)
|
||||
SET(HAVE_CRYPT_R 1 FORCE)
|
||||
SET(HAVE_LIBCRYPT 1 FORCE)
|
||||
ELSE(HAVE_LIBCRYPT_CRYPT_R)
|
||||
CHECK_LIBRARY_EXISTS(crypt crypt "" HAVE_LIBCRYPT)
|
||||
ENDIF(HAVE_LIBCRYPT_CRYPT_R)
|
||||
ENDIF(HAVE_CRYPT_H)
|
||||
CHECK_FUNCTION_EXISTS(crypt_r HAVE_CRYPT_R)
|
||||
IF(HAVE_LIBCRYPT)
|
||||
SET(HAVE_CRYPT_R 1 FORCE)
|
||||
ENDIF(HAVE_LIBCRYPT)
|
||||
|
||||
CHECK_LIBRARY_EXISTS(kvm kvm_open "" HAVE_LIBKVM)
|
||||
|
||||
|
@ -363,10 +366,6 @@ IF(HAVE_LIBSSL AND HAVE_LIBCRYPTO)
|
|||
TARGET_LINK_LIBRARIES(mod_openssl crypto)
|
||||
ENDIF(HAVE_LIBSSL AND HAVE_LIBCRYPTO)
|
||||
|
||||
IF(HAVE_LIBCRYPT)
|
||||
TARGET_LINK_LIBRARIES(mod_auth crypt)
|
||||
ENDIF(HAVE_LIBCRYPT)
|
||||
|
||||
ADD_TARGET_PROPERTIES(lighttpd-${PACKAGE_VERSION}-common LINK_FLAGS ${COMMON_LDFLAGS})
|
||||
ADD_TARGET_PROPERTIES(lighttpd-${PACKAGE_VERSION}-common COMPILE_FLAGS ${COMMON_CFLAGS})
|
||||
|
||||
|
@ -382,6 +381,10 @@ ADD_TARGET_PROPERTIES(lighttpd2-worker COMPILE_FLAGS ${COMMON_CFLAGS})
|
|||
ADD_TARGET_PROPERTIES(lighttpd2 LINK_FLAGS ${COMMON_LDFLAGS})
|
||||
ADD_TARGET_PROPERTIES(lighttpd2 COMPILE_FLAGS ${COMMON_CFLAGS})
|
||||
|
||||
IF(HAVE_LIBCRYPT)
|
||||
TARGET_LINK_LIBRARIES(lighttpd-${PACKAGE_VERSION}-common crypt)
|
||||
ENDIF(HAVE_LIBCRYPT)
|
||||
|
||||
IF(HAVE_LIBKVM)
|
||||
TARGET_LINK_LIBRARIES(lighttpd-${PACKAGE_VERSION}-common kvm)
|
||||
ENDIF(HAVE_LIBKVM)
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if 0
|
||||
#include <stropts.h>
|
||||
#ifdef HAVE_CRYPT_H
|
||||
# include <crypt.h>
|
||||
#endif
|
||||
|
||||
/* for send/li_receive_fd */
|
||||
|
@ -965,6 +965,29 @@ void li_apr_md5_crypt(GString *dest, const GString *password, const GString *sal
|
|||
md5_crypt_to64(dest, digest[11] , 2);
|
||||
}
|
||||
|
||||
void li_safe_crypt(GString *dest, const GString *password, const GString *salt) {
|
||||
if (g_str_has_prefix(salt->str, "$apr1$")) {
|
||||
li_apr_md5_crypt(dest, password, salt);
|
||||
} else {
|
||||
#ifdef HAVE_CRYPT_R
|
||||
struct crypt_data buffer;
|
||||
|
||||
memset(&buffer, 0, sizeof(buffer));
|
||||
|
||||
g_string_assign(dest, crypt_r(password->str, salt->str, &buffer));
|
||||
#else
|
||||
/* This is an acceptable hack: any library that uses crypt() itself is "broken"
|
||||
* for threaded usage anyway; and our own usage is protected.
|
||||
*/
|
||||
static GStaticMutex crypt_mutex = G_STATIC_MUTEX_INIT;
|
||||
|
||||
g_static_mutex_lock(&crypt_mutex);
|
||||
g_string_assign(crypt(password->str, salt->str));
|
||||
g_static_mutex_unlock(&crypt_mutex);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void li_g_queue_merge(GQueue *dest, GQueue *src) {
|
||||
assert(dest != src);
|
||||
|
|
|
@ -1955,7 +1955,7 @@ static const liPluginAngel angelcbs[] = {
|
|||
};
|
||||
#include <sys/types.h>
|
||||
|
||||
static void plugin_core_prepare_worker(liServer *srv, liPlugin *p, liWorker *wrk) {
|
||||
static void plugin_core_prepare(liServer *srv, liPlugin *p) {
|
||||
guint i;
|
||||
|
||||
UNUSED(p);
|
||||
|
@ -1978,6 +1978,10 @@ static void plugin_core_prepare_worker(liServer *srv, liPlugin *p, liWorker *wrk
|
|||
}
|
||||
}
|
||||
g_mutex_unlock(srv->action_mutex);
|
||||
}
|
||||
|
||||
static void plugin_core_prepare_worker(liServer *srv, liPlugin *p, liWorker *wrk) {
|
||||
UNUSED(p);
|
||||
|
||||
#if defined(LIGHTY_OS_LINUX)
|
||||
/* sched_setaffinity is only available on linux */
|
||||
|
@ -2003,6 +2007,8 @@ static void plugin_core_prepare_worker(liServer *srv, liPlugin *p, liWorker *wrk
|
|||
CPU_SET(v->data.number, &mask);
|
||||
DEBUG(srv, "binding worker #%u to cpu %u", wrk->ndx+1, (guint)v->data.number);
|
||||
} else {
|
||||
guint i;
|
||||
|
||||
g_string_truncate(wrk->tmp_str, 0);
|
||||
arr = v->data.list;
|
||||
|
||||
|
@ -2030,5 +2036,6 @@ void li_plugin_core_init(liServer *srv, liPlugin *p, gpointer userdata) {
|
|||
p->setups = setups;
|
||||
p->angelcbs = angelcbs;
|
||||
|
||||
p->handle_prepare = plugin_core_prepare;
|
||||
p->handle_prepare_worker = plugin_core_prepare_worker;
|
||||
}
|
||||
|
|
|
@ -65,10 +65,6 @@
|
|||
|
||||
#include <lighttpd/plugin_core.h>
|
||||
|
||||
#ifdef HAVE_CRYPT_H
|
||||
# include <crypt.h>
|
||||
#endif
|
||||
|
||||
LI_API gboolean mod_auth_init(liModules *mods, liModule *mod);
|
||||
LI_API gboolean mod_auth_free(liModules *mods, liModule *mod);
|
||||
|
||||
|
@ -284,8 +280,8 @@ static gboolean auth_backend_htpasswd(liVRequest *vr, const GString *username, c
|
|||
|
||||
if (NULL == afd) return FALSE;
|
||||
|
||||
/* unknown user? */
|
||||
if (!(pass = g_hash_table_lookup(afd->users, username->str))) {
|
||||
/* unknown user or empty crypt? */
|
||||
if (NULL == (pass = g_hash_table_lookup(afd->users, username->str)) || '\0' == pass[0]) {
|
||||
if (debug) {
|
||||
VR_DEBUG(vr, "User \"%s\" not found", username->str);
|
||||
}
|
||||
|
@ -302,8 +298,7 @@ static gboolean auth_backend_htpasswd(liVRequest *vr, const GString *username, c
|
|||
}
|
||||
goto out;
|
||||
}
|
||||
} else
|
||||
if (g_str_has_prefix(pass, "{SHA}")) {
|
||||
} else if (g_str_has_prefix(pass, "{SHA}")) {
|
||||
li_apr_sha1_base64(vr->wrk->tmp_str, password);
|
||||
|
||||
if (0 != g_strcmp0(pass, vr->wrk->tmp_str->str)) {
|
||||
|
@ -312,23 +307,17 @@ static gboolean auth_backend_htpasswd(liVRequest *vr, const GString *username, c
|
|||
}
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_CRYPT_R
|
||||
else {
|
||||
struct crypt_data buffer;
|
||||
const gchar *crypted;
|
||||
} else {
|
||||
const GString salt = { (gchar*) pass, strlen(pass), 0 };
|
||||
li_safe_crypt(vr->wrk->tmp_str, password, &salt);
|
||||
|
||||
memset(&buffer, 0, sizeof(buffer));
|
||||
crypted = crypt_r(password->str, pass, &buffer);
|
||||
|
||||
if (0 != g_strcmp0(pass, crypted)) {
|
||||
if (0 != g_strcmp0(pass, vr->wrk->tmp_str->str)) {
|
||||
if (debug) {
|
||||
VR_DEBUG(vr, "Password crypt \"%s\" doesn't match \"%s\" for user \"%s\"", crypted, pass, username->str);
|
||||
VR_DEBUG(vr, "Password crypt \"%s\" doesn't match \"%s\" for user \"%s\"", vr->wrk->tmp_str->str, pass, username->str);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
res = TRUE;
|
||||
|
||||
|
|
Loading…
Reference in New Issue