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