From 84dcc336500b75f05a857cf2c3075e37c9ba3119 Mon Sep 17 00:00:00 2001 From: zodiac Date: Tue, 17 Feb 2009 04:13:47 +0000 Subject: [PATCH] Allow "configure" to explicitly disable OpenSSL and PAM support. Also, allow OpenSSL and PAM libraries to be optionally linked as regular shared libraries instead of being searched for and loaded at run-time. git-svn-id: https://shellinabox.googlecode.com/svn/trunk@65 0da03de8-d603-11dd-86c2-0f8696b7b6f9 --- ChangeLog | 9 + Makefile.am | 21 +- Makefile.in | 21 +- configure | 1139 +++++++++++++++++++++++++------ configure.ac | 85 ++- libhttp/ssl.c | 11 +- libhttp/ssl.h | 2 + shellinabox/launcher.c | 90 ++- shellinabox/shellinaboxd.man.in | 10 +- 9 files changed, 1134 insertions(+), 254 deletions(-) diff --git a/ChangeLog b/ChangeLog index 39f2d0b..fcde3b7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2009-02-16 Markus Gutschke + + * Fixed various bugs that prevents ShellInABox from running on + FreeBSD + + * Allow "configure" to select whether OpenSSL and PAM libraries + should be used at all, dynamically searched-for at run-time, or + linked as a regular dynamic library. + 2009-02-12 Markus Gutschke * Released version 2.4 diff --git a/Makefile.am b/Makefile.am index 1115cc1..8e80e74 100644 --- a/Makefile.am +++ b/Makefile.am @@ -79,19 +79,28 @@ shellinaboxd_LDFLAGS = -static libtool: $(LIBTOOL_DEPS) $(SHELL) ./config.status --recheck -shellinaboxd.1: shellinabox/shellinaboxd.man.in +shellinaboxd.1: shellinabox/shellinaboxd.man.in $(top_srcdir)/config.h @src="${top_srcdir}/shellinabox/shellinaboxd.man.in"; \ echo preprocess "$$src" '>'"$@"; \ - if echo " $(DEFS)" | grep HAVE_OPENSSL_BIO_H | \ - grep HAVE_OPENSSL_ERR_H | \ - grep -q HAVE_OPENSSL_SSL_H; then \ + if [ `sed -e 's/^#define \([^ ]*\).*/\1/' -e t -e d \ + "${top_srcdir}/config.h" | \ + egrep 'HAVE_OPENSSL_BIO_H|HAVE_OPENSSL_ERR_H|HAVE_OPENSSL_SSL_H'|\ + wc -l` -eq 3 ]; then \ sed -e '/^#ifdef *HAVE_OPENSSL$$/d' \ -e '/^#endif$$/d' "$$src" >"$@"; \ else \ sed -e '/^#ifdef *HAVE_OPENSSL$$/,/^#endif$$/d' "$$src" >"$@"; \ + fi; \ + if sed -e 's/^#define \([^ ]*\).*/\1/' -e t -e d \ + "${top_srcdir}/config.h" | \ + grep 'HAVE_SECURITY_PAM_APPL_H' >/dev/null 2>&1; then \ + sed -e '/^#ifdef *HAVE_PAM$$/d' \ + -e '/^#endif$$/d' "$$src" >"$@"; \ + else \ + sed -e '/^#ifdef *HAVE_PAM$$/,/^#endif$$/d' "$$src" >"$@"; \ fi - @man -Tps "./$@" >`echo "$@" 2>/dev/null|sed -e 's/\.[^.]*$$/.ps/'` \ - || true + @out=`echo "$@" 2>/dev/null|sed -e 's/\.[^.]*$$/.ps/'`; \ + man -Tps "./$@" >"$${out}" 2>/dev/null || rm -f "$${out}" clean-local: -rm -rf shellinaboxd.1 \ diff --git a/Makefile.in b/Makefile.in index f9d8bdc..7104031 100644 --- a/Makefile.in +++ b/Makefile.in @@ -991,19 +991,28 @@ uninstall-man: uninstall-man1 libtool: $(LIBTOOL_DEPS) $(SHELL) ./config.status --recheck -shellinaboxd.1: shellinabox/shellinaboxd.man.in +shellinaboxd.1: shellinabox/shellinaboxd.man.in $(top_srcdir)/config.h @src="${top_srcdir}/shellinabox/shellinaboxd.man.in"; \ echo preprocess "$$src" '>'"$@"; \ - if echo " $(DEFS)" | grep HAVE_OPENSSL_BIO_H | \ - grep HAVE_OPENSSL_ERR_H | \ - grep -q HAVE_OPENSSL_SSL_H; then \ + if [ `sed -e 's/^#define \([^ ]*\).*/\1/' -e t -e d \ + "${top_srcdir}/config.h" | \ + egrep 'HAVE_OPENSSL_BIO_H|HAVE_OPENSSL_ERR_H|HAVE_OPENSSL_SSL_H'|\ + wc -l` -eq 3 ]; then \ sed -e '/^#ifdef *HAVE_OPENSSL$$/d' \ -e '/^#endif$$/d' "$$src" >"$@"; \ else \ sed -e '/^#ifdef *HAVE_OPENSSL$$/,/^#endif$$/d' "$$src" >"$@"; \ + fi; \ + if sed -e 's/^#define \([^ ]*\).*/\1/' -e t -e d \ + "${top_srcdir}/config.h" | \ + grep 'HAVE_SECURITY_PAM_APPL_H' >/dev/null 2>&1; then \ + sed -e '/^#ifdef *HAVE_PAM$$/d' \ + -e '/^#endif$$/d' "$$src" >"$@"; \ + else \ + sed -e '/^#ifdef *HAVE_PAM$$/,/^#endif$$/d' "$$src" >"$@"; \ fi - @man -Tps "./$@" >`echo "$@" 2>/dev/null|sed -e 's/\.[^.]*$$/.ps/'` \ - || true + @out=`echo "$@" 2>/dev/null|sed -e 's/\.[^.]*$$/.ps/'`; \ + man -Tps "./$@" >"$${out}" 2>/dev/null || rm -f "$${out}" clean-local: -rm -rf shellinaboxd.1 \ diff --git a/configure b/configure index 654c419..afdfb98 100755 --- a/configure +++ b/configure @@ -1477,6 +1477,23 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) + --disable-ssl if available at built-time, support for SSL + connections will be enabled. It can still be + disabled at run-time, either on the daemon's + command line or if the operating system does not + have the OpenSSL libraries available. + --disable-pam PAM support is necessary in order to authenticate + users for running programs other than their default + login shell. + --disable-runtime-loading ShellInABox will try to load the OpenSSL, and PAM + libraries at run-time, if it has been compiled with + support for these libraries, and if the operating + system supports dynamic loading of libraries. This + allows you to install the same binary on different + systems independent of whether they have OpenSSL + and PAM enabled. If you would rather directly link + these libraries into the binary, thus making them a + hard dependency, then disable runtime-loading. Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -1932,6 +1949,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu + am__api_version='1.10' ac_aux_dir= @@ -4394,7 +4412,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 4397 "configure"' > conftest.$ac_ext + echo '#line 4415 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -7451,11 +7469,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7454: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7472: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7458: \$? = $ac_status" >&5 + echo "$as_me:7476: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7741,11 +7759,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7744: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7762: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7748: \$? = $ac_status" >&5 + echo "$as_me:7766: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7845,11 +7863,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7848: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7866: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7852: \$? = $ac_status" >&5 + echo "$as_me:7870: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -10222,7 +10240,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:12744: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:12730: \$? = $ac_status" >&5 + echo "$as_me:12748: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -12827,11 +12845,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12830: $lt_compile\"" >&5) + (eval echo "\"\$as_me:12848: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:12834: \$? = $ac_status" >&5 + echo "$as_me:12852: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -14425,11 +14443,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14428: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14446: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14432: \$? = $ac_status" >&5 + echo "$as_me:14450: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14529,11 +14547,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14532: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14550: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14536: \$? = $ac_status" >&5 + echo "$as_me:14554: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -16749,11 +16767,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16752: $lt_compile\"" >&5) + (eval echo "\"\$as_me:16770: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:16756: \$? = $ac_status" >&5 + echo "$as_me:16774: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -17039,11 +17057,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:17042: $lt_compile\"" >&5) + (eval echo "\"\$as_me:17060: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:17046: \$? = $ac_status" >&5 + echo "$as_me:17064: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -17143,11 +17161,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:17146: $lt_compile\"" >&5) + (eval echo "\"\$as_me:17164: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:17150: \$? = $ac_status" >&5 + echo "$as_me:17168: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -19996,14 +20014,7 @@ fi - - - - - -for ac_header in libutil.h openssl/bio.h openssl/err.h openssl/ssl.h \ - pthread.h security/pam_appl.h security/pam_client.h \ - security/pam_misc.h sys/prctrl.h utmp.h utmpx.h +for ac_header in libutil.h pthread.h sys/prctrl.h utmp.h utmpx.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then @@ -20148,169 +20159,6 @@ fi done -for ac_func in dlopen -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -{ echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } -if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$ac_func || defined __stub___$ac_func -choke me -#endif - -int -main () -{ -return $ac_func (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_var=no" -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -ac_res=`eval echo '${'$as_ac_var'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_dl_dlopen=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } -if test $ac_cv_lib_dl_dlopen = yes; then - LIBS="-ldl $LIBS" - cat >>confdefs.h <<\_ACEOF -#define HAVE_DLOPEN 1 -_ACEOF - -fi - -fi -done - for ac_func in login_tty do @@ -20475,6 +20323,7 @@ fi fi done + cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -20528,6 +20377,908 @@ fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext + +# Check whether --enable-ssl was given. +if test "${enable_ssl+set}" = set; then + enableval=$enable_ssl; +fi + + +# Check whether --enable-pam was given. +if test "${enable_pam+set}" = set; then + enableval=$enable_pam; +fi + + +# Check whether --enable-runtime-loading was given. +if test "${enable_runtime_loading+set}" = set; then + enableval=$enable_runtime_loading; +fi + + +if test "x$enable_ssl" != xno; then + + + +for ac_header in openssl/bio.h openssl/err.h openssl/ssl.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ------------------------------------- ## +## Report this to markus@shellinabox.com ## +## ------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +fi + +if test "x$enable_pam" != xno; then + + + +for ac_header in security/pam_appl.h security/pam_client.h \ + security/pam_misc.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ------------------------------------- ## +## Report this to markus@shellinabox.com ## +## ------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +fi + +if test "x$enable_runtime_loading" != xno; then + +for ac_func in dlopen +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dl_dlopen=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } +if test $ac_cv_lib_dl_dlopen = yes; then + LIBS="-ldl $LIBS" + cat >>confdefs.h <<\_ACEOF +#define HAVE_DLOPEN 1 +_ACEOF + +else + enable_runtime_loading=no +fi + +fi +done + +fi + +if test "x$enable_runtime_loading" == xno; then + if test "x$enable_ssl" != xno; then + if test "${ac_cv_header_openssl_ssl_h+set}" = set; then + { echo "$as_me:$LINENO: checking for openssl/ssl.h" >&5 +echo $ECHO_N "checking for openssl/ssl.h... $ECHO_C" >&6; } +if test "${ac_cv_header_openssl_ssl_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_openssl_ssl_h" >&5 +echo "${ECHO_T}$ac_cv_header_openssl_ssl_h" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking openssl/ssl.h usability" >&5 +echo $ECHO_N "checking openssl/ssl.h usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking openssl/ssl.h presence" >&5 +echo $ECHO_N "checking openssl/ssl.h presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: openssl/ssl.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: openssl/ssl.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: openssl/ssl.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: openssl/ssl.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: openssl/ssl.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: openssl/ssl.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: openssl/ssl.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: openssl/ssl.h: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ------------------------------------- ## +## Report this to markus@shellinabox.com ## +## ------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for openssl/ssl.h" >&5 +echo $ECHO_N "checking for openssl/ssl.h... $ECHO_C" >&6; } +if test "${ac_cv_header_openssl_ssl_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_openssl_ssl_h=$ac_header_preproc +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_openssl_ssl_h" >&5 +echo "${ECHO_T}$ac_cv_header_openssl_ssl_h" >&6; } + +fi +if test $ac_cv_header_openssl_ssl_h = yes; then + LIBS="-lssl $LIBS" +fi + + + fi + + if test "x$enable_pam" != xno; then + if test "${ac_cv_header_security_pam_appl_h+set}" = set; then + { echo "$as_me:$LINENO: checking for security/pam_appl.h" >&5 +echo $ECHO_N "checking for security/pam_appl.h... $ECHO_C" >&6; } +if test "${ac_cv_header_security_pam_appl_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_security_pam_appl_h" >&5 +echo "${ECHO_T}$ac_cv_header_security_pam_appl_h" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking security/pam_appl.h usability" >&5 +echo $ECHO_N "checking security/pam_appl.h usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking security/pam_appl.h presence" >&5 +echo $ECHO_N "checking security/pam_appl.h presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: security/pam_appl.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: security/pam_appl.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: security/pam_appl.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: security/pam_appl.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: security/pam_appl.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: security/pam_appl.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: security/pam_appl.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: security/pam_appl.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: security/pam_appl.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: security/pam_appl.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: security/pam_appl.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: security/pam_appl.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: security/pam_appl.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: security/pam_appl.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: security/pam_appl.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: security/pam_appl.h: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ------------------------------------- ## +## Report this to markus@shellinabox.com ## +## ------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for security/pam_appl.h" >&5 +echo $ECHO_N "checking for security/pam_appl.h... $ECHO_C" >&6; } +if test "${ac_cv_header_security_pam_appl_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_security_pam_appl_h=$ac_header_preproc +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_security_pam_appl_h" >&5 +echo "${ECHO_T}$ac_cv_header_security_pam_appl_h" >&6; } + +fi +if test $ac_cv_header_security_pam_appl_h = yes; then + LIBS="-lpam $LIBS" +fi + + + if test "${ac_cv_header_security_pam_misc_h+set}" = set; then + { echo "$as_me:$LINENO: checking for security/pam_misc.h" >&5 +echo $ECHO_N "checking for security/pam_misc.h... $ECHO_C" >&6; } +if test "${ac_cv_header_security_pam_misc_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_security_pam_misc_h" >&5 +echo "${ECHO_T}$ac_cv_header_security_pam_misc_h" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking security/pam_misc.h usability" >&5 +echo $ECHO_N "checking security/pam_misc.h usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking security/pam_misc.h presence" >&5 +echo $ECHO_N "checking security/pam_misc.h presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: security/pam_misc.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: security/pam_misc.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: security/pam_misc.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: security/pam_misc.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: security/pam_misc.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: security/pam_misc.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: security/pam_misc.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: security/pam_misc.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: security/pam_misc.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: security/pam_misc.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: security/pam_misc.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: security/pam_misc.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: security/pam_misc.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: security/pam_misc.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: security/pam_misc.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: security/pam_misc.h: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ------------------------------------- ## +## Report this to markus@shellinabox.com ## +## ------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for security/pam_misc.h" >&5 +echo $ECHO_N "checking for security/pam_misc.h... $ECHO_C" >&6; } +if test "${ac_cv_header_security_pam_misc_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_security_pam_misc_h=$ac_header_preproc +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_security_pam_misc_h" >&5 +echo "${ECHO_T}$ac_cv_header_security_pam_misc_h" >&6; } + +fi +if test $ac_cv_header_security_pam_misc_h = yes; then + LIBS="-lpam_misc $LIBS" +fi + + + fi +fi + ac_config_files="$ac_config_files Makefile" cat >confcache <<\_ACEOF diff --git a/configure.ac b/configure.ac index 9d61f68..1494f03 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,9 @@ AC_PREREQ(2.57) + +dnl This is the one location where the authoritative version number is stored AC_INIT(shellinabox, 2.4, markus@shellinabox.com) + +dnl Set up autoconf/automake for building C libraries and binaries with GCC AM_INIT_AUTOMAKE AM_CONFIG_HEADER(config.h) AC_PROG_CC @@ -8,17 +12,17 @@ AC_PROG_LIBTOOL AC_SUBST(LIBTOOL_DEPS) AC_C_CONST AC_PROG_GCC_TRADITIONAL -AC_CHECK_HEADERS([libutil.h openssl/bio.h openssl/err.h openssl/ssl.h \ - pthread.h security/pam_appl.h security/pam_client.h \ - security/pam_misc.h sys/prctrl.h utmp.h utmpx.h]) -AC_CHECK_FUNCS(dlopen, [], - [AC_CHECK_LIB(dl, dlopen, - [LIBS="-ldl $LIBS" - AC_DEFINE(HAVE_DLOPEN)])]) + +dnl Check for header files that do not exist on all platforms +AC_CHECK_HEADERS([libutil.h pthread.h sys/prctrl.h utmp.h utmpx.h]) + +dnl Most systems require linking against libutil.so in order to get login_tty() AC_CHECK_FUNCS(login_tty, [], [AC_CHECK_LIB(util, login_tty, [LIBS="-lutil $LIBS" AC_DEFINE(HAVE_LOGIN_TTY)])]) + +dnl We prefer ptsname_r(), but will settle for ptsname() if necessary AC_TRY_LINK([#ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE #endif @@ -29,5 +33,72 @@ AC_TRY_LINK([#ifndef _XOPEN_SOURCE [ptsname_r(0, 0, 0);], [AC_DEFINE(HAVE_PTSNAME_R, 1, Define to 1 if you have a re-entrant version of ptsname)]) + +dnl We automatically detect SSL support, but allow users to disable it +AC_ARG_ENABLE(ssl, + [ --disable-ssl if available at built-time, support for SSL + connections will be enabled. It can still be + disabled at run-time, either on the daemon's + command line or if the operating system does not + have the OpenSSL libraries available.]) + +dnl We automatically detect PAM support, but allow users to disable it +AC_ARG_ENABLE(pam, + [ --disable-pam PAM support is necessary in order to authenticate + users for running programs other than their default + login shell.]) + +dnl We try to always use dlopen() instead of linking libraries dynamically, as +dnl this reduces the hard run-time dependencies that our binary has. But we +dnl allow users to disable this feature. +AC_ARG_ENABLE(runtime-loading, + [ --disable-runtime-loading ShellInABox will try to load the OpenSSL, and PAM + libraries at run-time, if it has been compiled with + support for these libraries, and if the operating + system supports dynamic loading of libraries. This + allows you to install the same binary on different + systems independent of whether they have OpenSSL + and PAM enabled. If you would rather directly link + these libraries into the binary, thus making them a + hard dependency, then disable runtime-loading.]) + +dnl Only test for OpenSSL headers, if not explicitly disabled +if test "x$enable_ssl" != xno; then + AC_CHECK_HEADERS([openssl/bio.h openssl/err.h openssl/ssl.h]) +fi + +dnl Only test for PAM headers, if not explicitly disabled +if test "x$enable_pam" != xno; then + AC_CHECK_HEADERS([security/pam_appl.h security/pam_client.h \ + security/pam_misc.h ]) +fi + +dnl Only test for dlopen(), if not explicitly disabled. Add required libdl.so +dnl library if necessary. Also, if dlopen() is not available on this system, +dnl explicitly disable runtime loading. +if test "x$enable_runtime_loading" != xno; then + AC_CHECK_FUNCS(dlopen, [], + [AC_CHECK_LIB(dl, dlopen, + [LIBS="-ldl $LIBS" + AC_DEFINE(HAVE_DLOPEN)], + [enable_runtime_loading=no])]) +fi + +dnl If runtime loading has been disabled, add OpenSSL and PAM as hard +dnl dependencies. +if test "x$enable_runtime_loading" == xno; then + dnl Link against OpenSSL libraries, unless SSL support has been disabled + if test "x$enable_ssl" != xno; then + AC_CHECK_HEADER(openssl/ssl.h, [LIBS="-lssl $LIBS"]) + fi + + dnl Link against PAM libraries, unless PAM support has been disabled + if test "x$enable_pam" != xno; then + AC_CHECK_HEADER(security/pam_appl.h, [LIBS="-lpam $LIBS"]) + AC_CHECK_HEADER(security/pam_misc.h, [LIBS="-lpam_misc $LIBS"]) + fi +fi + +dnl Generate output files AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/libhttp/ssl.c b/libhttp/ssl.c index b3efe5d..ba20a92 100644 --- a/libhttp/ssl.c +++ b/libhttp/ssl.c @@ -67,12 +67,15 @@ // Pthread support is optional. Only enable it, if the library has been // linked into the program #include +#if defined(__linux__) extern int pthread_once(pthread_once_t *, void (*)(void))__attribute__((weak)); +#endif extern int pthread_sigmask(int, const sigset_t *, sigset_t *) __attribute__((weak)); #endif +#if defined(HAVE_DLOPEN) // SSL support is optional. Only enable it, if the library can be loaded. long (*BIO_ctrl)(BIO *, int, long, void *); BIO_METHOD * (*BIO_f_buffer)(void); @@ -113,7 +116,7 @@ int (*SSL_set_ex_data)(SSL *, int, void *); int (*SSL_shutdown)(SSL *); int (*SSL_write)(SSL *, const void *, int); SSL_METHOD * (*SSLv23_server_method)(void); - +#endif static void sslDestroyCachedContext(void *ssl_, char *context_) { struct SSLSupport *ssl = (struct SSLSupport *)ssl_; @@ -163,7 +166,7 @@ void deleteSSL(struct SSLSupport *ssl) { free(ssl); } -#if defined(HAVE_OPENSSL) +#if defined(HAVE_OPENSSL) && defined(HAVE_DLOPEN) static void *loadSymbol(const char *lib, const char *fn) { void *dl = RTLD_DEFAULT; void *rc = dlsym(dl, fn); @@ -251,6 +254,9 @@ static void loadSSL(void) { #endif int serverSupportsSSL(void) { +#if defined(HAVE_OPENSSL) && !defined(HAVE_DLOPEN) + return SSL_library_init(); +#else #if defined(HAVE_OPENSSL) // We want to call loadSSL() exactly once. For single-threaded applications, // this is straight-forward. For threaded applications, we need to call @@ -274,6 +280,7 @@ int serverSupportsSSL(void) { #else return 0; #endif +#endif } #if defined(HAVE_OPENSSL) diff --git a/libhttp/ssl.h b/libhttp/ssl.h index 89595d1..c2d2f42 100644 --- a/libhttp/ssl.h +++ b/libhttp/ssl.h @@ -68,6 +68,7 @@ typedef struct SSL_METHOD SSL_METHOD; #define SSL_ERROR_WANT_WRITE 3 #endif +#if defined(HAVE_DLOPEN) extern long (*x_BIO_ctrl)(BIO *, int, long, void *); extern BIO_METHOD *(*x_BIO_f_buffer)(void); extern void (*x_BIO_free_all)(BIO *); @@ -166,6 +167,7 @@ extern SSL_METHOD *(*x_SSLv23_server_method)(void); #define SSL_get_app_data(s) (x_SSL_get_ex_data(s, 0)) #define SSL_set_app_data(s, arg) (x_SSL_set_ex_data(s, 0, (char *)arg)) #define SSL_set_mode(ssl, op) (x_SSL_ctrl((ssl), SSL_CTRL_MODE, (op), NULL)) +#endif struct SSLSupport { int enabled; diff --git a/shellinabox/launcher.c b/shellinabox/launcher.c index eca29e5..d07fd1a 100644 --- a/shellinabox/launcher.c +++ b/shellinabox/launcher.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -90,7 +91,7 @@ struct pam_conv; typedef struct pam_handle pam_handle_t; #endif -#if defined(HAVE_PTHREAD_H) +#if defined(HAVE_PTHREAD_H) && defined(__linux__) #include extern int pthread_once(pthread_once_t *, void (*)(void))__attribute__((weak)); #endif @@ -103,7 +104,7 @@ extern int pthread_once(pthread_once_t *, void (*)(void))__attribute__((weak)); // If PAM support is available, take advantage of it. Otherwise, silently fall // back on legacy operations for session management. -#if defined(HAVE_SECURITY_PAM_APPL_H) +#if defined(HAVE_SECURITY_PAM_APPL_H) && defined(HAVE_DLOPEN) static int (*x_pam_acct_mgmt)(pam_handle_t *, int); static int (*x_pam_authenticate)(pam_handle_t *, int); #if defined(HAVE_SECURITY_PAM_CLIENT_H) @@ -118,6 +119,17 @@ static int (*x_pam_start)(const char *, const char *, const struct pam_conv *, pam_handle_t **); static int (*x_misc_conv)(int, const struct pam_message **, struct pam_response **, void *); + +#define pam_acct_mgmt x_pam_acct_mgmt +#define pam_authenticate x_pam_authenticate +#define pam_binary_handler_fn x_pam_binary_handler_fn +#define pam_close_session x_pam_close_session +#define pam_end x_pam_end +#define pam_get_item x_pam_get_item +#define pam_open_session x_pam_open_session +#define pam_set_item x_pam_set_item +#define pam_start x_pam_start +#define misc_conv x_misc_conv #endif // Older versions of glibc might not support fdopendir(). That's OK, we can @@ -128,7 +140,7 @@ static int launcher = -1; static uid_t restricted; -#if defined(HAVE_SECURITY_PAM_APPL_H) +#if defined(HAVE_SECURITY_PAM_APPL_H) && defined(HAVE_DLOPEN) // If the PAM misc library cannot be found, we have to provide our own basic // conversation function. As we know that this code is only ever called from @@ -221,14 +233,14 @@ static int my_misc_conv(int num_msg, const struct pam_message **msgm, #if defined(HAVE_SECURITY_PAM_CLIENT_H) case PAM_BINARY_PROMPT: { pamc_bp_t binary_prompt = NULL; - if (!msgm[count]->msg || !*x_pam_binary_handler_fn) { + if (!msgm[count]->msg || !*pam_binary_handler_fn) { goto failed_conversation; } PAM_BP_RENEW(p(&binary_prompt), PAM_BP_RCONTROL(msgm[count]->msg), PAM_BP_LENGTH(msgm[count]->msg)); PAM_BP_FILL(binary_prompt, 0, PAM_BP_LENGTH(msgm[count]->msg), PAM_BP_RDATA(msgm[count]->msg)); - if ((*x_pam_binary_handler_fn)(appdata_ptr, &binary_prompt) != + if ((*pam_binary_handler_fn)(appdata_ptr, &binary_prompt) != PAM_SUCCESS || !binary_prompt) { goto failed_conversation; } @@ -268,8 +280,8 @@ static void *loadSymbol(const char *lib, const char *fn) { } static void loadPAM(void) { - check(!x_pam_start); - check(!x_misc_conv); + check(!pam_start); + check(!misc_conv); struct { union { void *avoid_gcc_warning_about_type_punning; @@ -278,18 +290,18 @@ static void loadPAM(void) { const char *lib; const char *fn; } symbols[] = { - { { &x_pam_acct_mgmt }, "libpam.so", "pam_acct_mgmt" }, - { { &x_pam_authenticate }, "libpam.so", "pam_authenticate" }, + { { &pam_acct_mgmt }, "libpam.so", "pam_acct_mgmt" }, + { { &pam_authenticate }, "libpam.so", "pam_authenticate" }, #if defined(HAVE_SECURITY_PAM_CLIENT_H) - { { &x_pam_binary_handler_fn }, "libpam_misc.so", "pam_binary_handler_fn"}, + { { &pam_binary_handler_fn }, "libpam_misc.so", "pam_binary_handler_fn" }, #endif - { { &x_pam_close_session }, "libpam.so", "pam_close_session" }, - { { &x_pam_end }, "libpam.so", "pam_end" }, - { { &x_pam_get_item }, "libpam.so", "pam_get_item" }, - { { &x_pam_open_session }, "libpam.so", "pam_open_session" }, - { { &x_pam_set_item }, "libpam.so", "pam_set_item" }, - { { &x_pam_start }, "libpam.so", "pam_start" }, - { { &x_misc_conv }, "libpam_misc.so", "misc_conv" } + { { &pam_close_session }, "libpam.so", "pam_close_session" }, + { { &pam_end }, "libpam.so", "pam_end" }, + { { &pam_get_item }, "libpam.so", "pam_get_item" }, + { { &pam_open_session }, "libpam.so", "pam_open_session" }, + { { &pam_set_item }, "libpam.so", "pam_set_item" }, + { { &pam_start }, "libpam.so", "pam_start" }, + { { &misc_conv }, "libpam_misc.so", "misc_conv" } }; for (int i = 0; i < sizeof(symbols)/sizeof(symbols[0]); i++) { if (!(*symbols[i].var = loadSymbol(symbols[i].lib, symbols[i].fn))) { @@ -317,6 +329,9 @@ static void loadPAM(void) { #endif int supportsPAM(void) { +#if defined(HAVE_SECURITY_PAM_APPL_H) && !defined(HAVE_DLOPEN) + return 1; +#else #if defined(HAVE_SECURITY_PAM_APPL_H) // We want to call loadPAM() exactly once. For single-threaded applications, @@ -337,10 +352,11 @@ int supportsPAM(void) { loadPAM(); } } - return x_misc_conv && x_pam_start; + return misc_conv && pam_start; #else return 0; #endif +#endif } int launchChild(int service, struct Session *session) { @@ -540,7 +556,7 @@ static int ptsname_r(int fd, char *buf, size_t buflen) { } strcpy(buf, p); return 0; -} +} #endif static int forkPty(int *pty, int useLogin, struct Utmp **utmp, @@ -666,48 +682,48 @@ static pam_handle_t *internalLogin(struct Service *service, struct Utmp *utmp, const struct passwd *pw; pam_handle_t *pam = NULL; #if defined(HAVE_SECURITY_PAM_APPL_H) - struct pam_conv conv = { .conv = x_misc_conv }; + struct pam_conv conv = { .conv = misc_conv }; if (service->authUser) { check(supportsPAM()); - check(x_pam_start("shellinabox", NULL, &conv, &pam) == PAM_SUCCESS); + check(pam_start("shellinabox", NULL, &conv, &pam) == PAM_SUCCESS); // Change the prompt to include the host name struct utsname uts; check(!uname(&uts)); const char *origPrompt; - check(x_pam_get_item(pam, PAM_USER_PROMPT, (void *)&origPrompt) == + check(pam_get_item(pam, PAM_USER_PROMPT, (void *)&origPrompt) == PAM_SUCCESS); char *prompt; check(prompt = stringPrintf(NULL, "%s %s", uts.nodename, origPrompt ? origPrompt : "login: ")); - check(x_pam_set_item(pam, PAM_USER_PROMPT, prompt) == PAM_SUCCESS); + check(pam_set_item(pam, PAM_USER_PROMPT, prompt) == PAM_SUCCESS); // Up to three attempts to enter the user id and password for (int i = 0;;) { - check(x_pam_set_item(pam, PAM_USER, NULL) == PAM_SUCCESS); + check(pam_set_item(pam, PAM_USER, NULL) == PAM_SUCCESS); int rc; - if ((rc = x_pam_authenticate(pam, PAM_SILENT)) == + if ((rc = pam_authenticate(pam, PAM_SILENT)) == PAM_SUCCESS && (geteuid() || - (rc = x_pam_acct_mgmt(pam, PAM_SILENT)) == + (rc = pam_acct_mgmt(pam, PAM_SILENT)) == PAM_SUCCESS)) { break; } if (++i == 3) { // Quit if login failed. puts("\nMaximum number of tries exceeded (3)"); - x_pam_end(pam, rc); + pam_end(pam, rc); _exit(1); } else { puts("\nLogin incorrect"); } } - check(x_pam_set_item(pam, PAM_USER_PROMPT, "login: ") == PAM_SUCCESS); + check(pam_set_item(pam, PAM_USER_PROMPT, "login: ") == PAM_SUCCESS); free(prompt); // Retrieve user id, and group id. const char *name; - check(x_pam_get_item(pam, PAM_USER, (void *)&name) == PAM_SUCCESS); + check(pam_get_item(pam, PAM_USER, (void *)&name) == PAM_SUCCESS); pw = getPWEnt(getUserId(name)); check(service->uid < 0); check(service->gid < 0); @@ -723,16 +739,16 @@ static pam_handle_t *internalLogin(struct Service *service, struct Utmp *utmp, check(service->user); check(service->group); if (supportsPAM()) { - check(x_pam_start("shellinabox", service->user, &conv, &pam) == + check(pam_start("shellinabox", service->user, &conv, &pam) == PAM_SUCCESS); int rc; // PAM account management requires root access. Just skip it, if we // are running with lower privileges. if (geteuid() && - (rc = x_pam_acct_mgmt(pam, PAM_SILENT)) != + (rc = pam_acct_mgmt(pam, PAM_SILENT)) != PAM_SUCCESS) { - x_pam_end(pam, rc); + pam_end(pam, rc); _exit(1); } } @@ -747,7 +763,7 @@ static pam_handle_t *internalLogin(struct Service *service, struct Utmp *utmp, (service->uid != restricted || service->gid != pw->pw_gid)) { puts("\nAccess denied!"); #if defined(HAVE_SECURITY_PAM_APPL_H) - x_pam_end(pam, PAM_SUCCESS); + pam_end(pam, PAM_SUCCESS); #endif _exit(1); } @@ -755,7 +771,7 @@ static pam_handle_t *internalLogin(struct Service *service, struct Utmp *utmp, #if defined(HAVE_SECURITY_PAM_APPL_H) if (pam) { #ifdef HAVE_UTMPX_H - check(x_pam_set_item(pam, PAM_TTY, (const void **)utmp->utmpx.ut_line) == + check(pam_set_item(pam, PAM_TTY, (const void **)utmp->utmpx.ut_line) == PAM_SUCCESS); #endif } @@ -1080,7 +1096,7 @@ static void childProcess(struct Service *service, int width, int height, pam_handle_t *pam = internalLogin(service, utmp, &environment); #if defined(HAVE_SECURITY_PAM_APPL_H) if (pam && !geteuid()) { - check(x_pam_open_session(pam, PAM_SILENT) == PAM_SUCCESS); + check(pam_open_session(pam, PAM_SILENT) == PAM_SUCCESS); pid_t pid = fork(); switch (pid) { case -1: @@ -1091,9 +1107,9 @@ static void childProcess(struct Service *service, int width, int height, // Finish all pending PAM operations. int status, rc; check(NOINTR(waitpid(pid, &status, 0)) == pid); - check((rc = x_pam_close_session(pam, PAM_SILENT)) == + check((rc = pam_close_session(pam, PAM_SILENT)) == PAM_SUCCESS); - check(x_pam_end(pam, rc) == PAM_SUCCESS); + check(pam_end(pam, rc) == PAM_SUCCESS); _exit(WIFEXITED(status) ? WEXITSTATUS(status) : -WTERMSIG(status)); } } diff --git a/shellinabox/shellinaboxd.man.in b/shellinabox/shellinaboxd.man.in index 8310621..b9acfc4 100755 --- a/shellinabox/shellinaboxd.man.in +++ b/shellinabox/shellinaboxd.man.in @@ -300,13 +300,19 @@ Alternatively, an \fIapplication\fP can be specified by providing a \fIuser\fP description, a working directory, and a command line: .in +4 \fIAPPLICATION\fP := 'LOGIN' | \fIUSER\fP ':' \fICWD\fP ':' -.in +#ifdef HAVE_PAM +.in The keyword 'AUTH' indicates that the \fIuser\fP information should be requested interactively, instead of being provided as part of the \fIservice\fP description: .in +4 -\fIUSER\fP := 'AUTH' | ':' +#endif +\fIUSER\fP := +#ifdef HAVE_PAM +'AUTH' | +#endif + ':' .in The working directory can either be given as an absolute path, or it