diff options
| author | Remi Collet <remi@remirepo.net> | 2026-04-16 12:42:56 +0200 |
|---|---|---|
| committer | Remi Collet <remi@php.net> | 2026-04-16 12:42:56 +0200 |
| commit | 3abf1f3abbd68a6c0cda07c50a19b93e655744da (patch) | |
| tree | 8a925070e66a40806c2e4f2c2ba37c777cf99dc4 | |
| parent | 8709323ba47833d1b349d3b64023f98eef510750 (diff) | |
add --with-xpass-dlopen
| -rw-r--r-- | config.m4 | 19 | ||||
| -rw-r--r-- | xpass.c | 51 |
2 files changed, 68 insertions, 2 deletions
@@ -6,10 +6,25 @@ PHP_ARG_ENABLE([xpass], [Enable xpass support])], [no]) +PHP_ARG_WITH([xpass-dlopen], + [whether to enable dlopen of libxcrypt], + [AS_HELP_STRING([[--with-xpass-dlopen[=libcrypt.so.2]]], + [Enable dlopen of libxcrypt])], + [no], [no]) + if test "$PHP_XPASS" != "no"; then PKG_CHECK_MODULES([LIBXCRYPT], [libxcrypt >= 4.4]) - PHP_EVAL_INCLINE([$LIBXCRYPT_CFLAGS]) - PHP_EVAL_LIBLINE([$LIBXCRYPT_LIBS], [XPASS_SHARED_LIBADD]) + + if test "$PHP_XPASS_DLOPEN" = "no"; then + PHP_EVAL_INCLINE([$LIBXCRYPT_CFLAGS]) + PHP_EVAL_LIBLINE([$LIBXCRYPT_LIBS], [XPASS_SHARED_LIBADD]) + elif test "$PHP_XPASS_DLOPEN" = "yes"; then + AC_DEFINE([USE_LIBCRYPT_DLOPEN], ["libcrypt.so.2"], [ libcrypt path for dlopen ]) + PHP_SUBST([USE_LIBCRYPT_DLOPEN]) + else + AC_DEFINE_UNQUOTED([USE_LIBCRYPT_DLOPEN], ["$PHP_XPASS_DLOPEN"], [ libcrypt path for dlopen ]) + PHP_SUBST([USE_LIBCRYPT_DLOPEN]) + fi old_CFLAGS=$CFLAGS; CFLAGS="$CFLAGS $LIBXCRYPT_CFLAGS" old_LIBS=$LIBS; LIBS="$LIBS $LIBXCRYPT_LIBS" @@ -24,6 +24,25 @@ #include "xpass_arginfo.h" +#ifdef USE_LIBCRYPT_DLOPEN +static struct _libsyms { + void *handle; + char * (*crypt_r) (const char *__phrase, const char *__setting, + struct crypt_data *__restrict __data); + char * (*crypt_gensalt_rn) (const char *__prefix, unsigned long __count, + const char *__rbytes, int __nrbytes, + char *__output, int __output_size); + int (*crypt_checksalt) (const char *__setting); + const char * (*crypt_preferred_method) (void); +} libsyms; + +/* substitute symbols */ +#define crypt_r libsyms.crypt_r +#define crypt_gensalt_rn libsyms.crypt_gensalt_rn +#define crypt_checksalt libsyms.crypt_checksalt +#define crypt_preferred_method libsyms.crypt_preferred_method +#endif + /* {{{ PHP_RINIT_FUNCTION */ PHP_RINIT_FUNCTION(xpass) { @@ -42,6 +61,9 @@ PHP_MINFO_FUNCTION(xpass) php_info_print_table_header(2, "Extended password support", "enabled"); php_info_print_table_row(2, "Extension version", PHP_XPASS_VERSION); php_info_print_table_row(2, "libxcrypt version", XCRYPT_VERSION_STR); +#ifdef USE_LIBCRYPT_DLOPEN + php_info_print_table_row(2, "Loaded library", USE_LIBCRYPT_DLOPEN); +#endif php_info_print_table_row(2, "Author", PHP_XPASS_AUTHOR); php_info_print_table_row(2, "License", PHP_XPASS_LICENSE); #ifdef HAVE_CRYPT_SHA512 @@ -237,8 +259,37 @@ PHP_FUNCTION(crypt_checksalt) } /* }}} */ +/* remove to not substitute symbols in MINIT */ +#undef crypt_r +#undef crypt_gensalt_rn +#undef crypt_checksalt +#undef crypt_preferred_method + PHP_MINIT_FUNCTION(xpass) /* {{{ */ { +#ifdef USE_LIBCRYPT_DLOPEN + if ((libsyms.handle = dlopen(USE_LIBCRYPT_DLOPEN, RTLD_NOW)) == NULL) { + php_error_docref(NULL, E_ERROR, "xpass: Cannot load %s", USE_LIBCRYPT_DLOPEN); + return FAILURE; + } + if ((libsyms.crypt_r = dlsym(libsyms.handle, "crypt_r")) == NULL) { + php_error_docref(NULL, E_ERROR, "xpass: Cannot find crypt_r symbol"); + return FAILURE; + } + if ((libsyms.crypt_gensalt_rn = dlsym(libsyms.handle, "crypt_gensalt_rn")) == NULL) { + php_error_docref(NULL, E_ERROR, "xpass: Cannot find crypt_gensalt_rn symbol"); + return FAILURE; + } + if ((libsyms.crypt_checksalt = dlsym(libsyms.handle, "crypt_checksalt")) == NULL) { + php_error_docref(NULL, E_ERROR, "xpass: Cannot find crypt_checksalt symbol"); + return FAILURE; + } + if ((libsyms.crypt_preferred_method = dlsym(libsyms.handle, "crypt_preferred_method")) == NULL) { + php_error_docref(NULL, E_ERROR, "xpass: Cannot find crypt_preferred_method symbol"); + return FAILURE; + } +#endif + register_xpass_symbols(module_number); #ifdef HAVE_CRYPT_SHA512 |
