summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config.m419
-rw-r--r--xpass.c51
2 files changed, 68 insertions, 2 deletions
diff --git a/config.m4 b/config.m4
index ecaa8ed..4cd9b38 100644
--- a/config.m4
+++ b/config.m4
@@ -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"
diff --git a/xpass.c b/xpass.c
index d2732d1..5ebf64a 100644
--- a/xpass.c
+++ b/xpass.c
@@ -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