diff -Nur pam_skey-1.1.4/INSTALL pam_skey/INSTALL
--- pam_skey-1.1.4/INSTALL	2005-06-18 14:11:24.000000000 +0200
+++ pam_skey/INSTALL	2006-03-06 09:26:55.000000000 +0100
@@ -1,5 +1,39 @@
 $Id: INSTALL,v 1.1.1.1 2005/06/18 12:11:24 kreator Exp $
 
+Gentoo patch
+------------
+Most everything below still holds, though the libraries required are now
+those used by Gentoo.  Other S/Key libraries may work with a bit of
+tweaking.
+
+The options listed for the module below are no longer valid.  See the
+Gentoo patch section in README for details.
+
+The intended method for configuring PAM is by using the newer module
+specification, with a line like:
+
+auth	[success=done ignore=ignore auth_err=die default=bad] /lib/security/pam_skey.so
+
+This is a combination of the standard "sufficient" and "requisite"
+specifications:
+
+- If the module returns PAM_SUCCESS, we are authenticated and no other
+  modules should be tested.
+- If the module returns PAM_IGNORE, then the module didn't accept its
+  input as an S/Key response, and the next module should try using
+  the input (using the try_first_pass option).
+- If the module returns PAM_AUTH_ERR, then the module accepted an
+  S/Key input but it was invalid.  Do not try any more modules in the
+  stack; the user already chose S/Key authentication.
+- If the module returns any other code, it is a simple error in processing.
+  Set the error flag but try other modules, just in case.
+
+The module is intended to be placed before another authentication module,
+like pam_unix.so; if not, it should be placed before pam_deny.so.
+
+If the newer module specification is unavailable in your version of PAM,
+the "sufficient" specification will work.
+
 Required
 --------
 For building this package you will probably need original Wietse Venema's
diff -Nur pam_skey-1.1.4/Makefile.in pam_skey/Makefile.in
--- pam_skey-1.1.4/Makefile.in	2005-06-18 14:11:24.000000000 +0200
+++ pam_skey/Makefile.in	2006-03-06 09:26:55.000000000 +0100
@@ -12,42 +12,26 @@
 LIBS=@LIBS@ @SKEYLIB@ @PAMLIB@
 LDFLAGS=@LDFLAGS@
 
-INSTALL=@INSTALL@ -m 644
+INSTALL=@INSTALL@
+INSTALL_LIB=${INSTALL} -m 755
 RM=@RM@ -f
 CP=@CP@ -f
 LN=@LN@ -s
 AWK=@AWK@
 
-PAM_FILES=pam_skey.so.1 pam_skey_access.so.1
+PAM_FILES=pam_skey.so
 
 all: $(PAM_FILES)
 
-pam_skey.so.1: pam_skey.o
-	$(CC) $(CFLAGS) -o $@ $< $(LIBS) $(LDFLAGS)
-
-pam_skey_access.so.1: pam_skey_access.o
+pam_skey.so: pam_skey.o
 	$(CC) $(CFLAGS) -o $@ $< $(LIBS) $(LDFLAGS)
 
 lint-pam_skey:
 	lclint $(CFLAGS) pam_skey.c
 
-lint-pam_skey_access:
-	lclint $(CFLAGS) pam_skey_access.c
-
-install:
-	@if test ! -d $(INSTALLDIR); then \
-		echo "Missing $(INSTALLDIR). Problem with PAM installation?"; \
-	else \
-		for file in $(PAM_FILES); do \
-			if test ! -f "$(INSTALLDIR)/$$file"; then \
-				echo "Installing $$file in $(INSTALLDIR)"; \
-				$(INSTALL) "$$file" "$(INSTALLDIR)/$$file"; \
-				(cd $(INSTALLDIR) && $(LN) "$$file" `echo $$file | cut -d. -f1,2`); \
-			else \
-				echo "$$file exists - will not overwrite it"; \
-			fi \
-		done \
-	fi
+install: all
+	$(INSTALL) -d $(INSTALLDIR)
+	$(INSTALL_LIB) $(PAM_FILES) $(INSTALLDIR)
 
 clean:
 	$(RM) a.out core *.so.1 *.o *.bak
diff -Nur pam_skey-1.1.4/README pam_skey/README
--- pam_skey-1.1.4/README	2005-06-18 14:36:18.000000000 +0200
+++ pam_skey/README	2006-03-06 09:26:55.000000000 +0100
@@ -1,5 +1,77 @@
 $Id: README,v 1.2 2005/06/18 12:36:18 kreator Exp $
 
+Gentoo patch
+------------
+
+The Gentoo pam_skey patch changes the original module in a number of ways.
+The behavior of the module is changed to make it more consistent with the
+PAM design, and several changes were made throughout the code to make the
+module interact better with the skey library used by Gentoo.  Many of
+these changes will break pam_skey's compatibility with other systems and
+libraries, but this is, after all, the Gentoo patch.
+
+A (not necessarily) exhaustive list of the changes is as follows:
+- pam_skey_access.so is completely removed, since the Gentoo skey library
+  does not support the skey_access() call.
+- The pam_skey.so authentication code is completely rewritten.  The
+  original code contained many references to the standard I/O library
+  (writing to stderr, etc.), as well as inconsistent communication with
+  the PAM libraries.  Also, the authentication process is different, as
+  described below.
+- The options accepted by the pam_skey.so module are different, as
+  described below.
+
+Four options are accepted by the pam_skey.so module:
+  debug                  - This option turns on debug logging.
+  try_first_pass         - This option tells the module to first try using
+                           the authentication token passed from the
+			   previous module as an S/Key response, before
+			   informing the user of the challenge.  If the
+			   token is not valid, the module will proceed with
+			   the standard process of challenging the user
+			   and requesting a response, subject to the
+			   no_default_skey option below.
+  use_first_pass         - This option is identical to the try_first_pass
+                           option, except that if the token is not valid,
+			   it will return silently without challenging the
+			   user.
+  no_default_skey        - This flag changes the behavior of pam_skey.
+                           Instead of immediately challenging the user with
+			   an S/Key challenge, it will present the user with
+			   a standard "Password: " prompt.  If the user enters
+			   the password "s/key" (case insensitive), it will
+			   then challenge the user.  Any other input will
+			   cause the module to pass the given password to the
+			   next module in the authentication stack (usually
+			   pam_unix.so with the try_first_pass option).
+
+The exact behavior of pam_skey.so is detailed below:
+
+1. Retrieve username from PAM, possibly querying the user for it.
+2. If the user does not have any S/Key information, return PAM_IGNORE to
+   proceed to the next module in the stack.
+3. If *_first_pass is enabled, check the given authentication token to see
+   if it is a valid response to the current S/Key challenge.  If so,
+   return PAM_SUCCESS.
+ 3a. If the token is invalid and use_first_pass is enabled, return
+     PAM_IGNORE.
+4. If no_default_skey is enabled, issue a "Password: " prompt.
+ 4a. If the response is anything besides "s/key" (case insensitive),
+     store it as the authentication token and return PAM_IGNORE.
+5. Display the current S/Key challenge and request a response, with
+   input not echoed.  If no_default_skey is enabled, this will only be
+   an S/Key response request; otherwise, it will request either an
+   S/Key response or a system passsword.
+ 5a. If an empty response is given, request the S/Key response again,
+     this time with input echoed.
+ 5b. If the response is a valid S/Key response, return PAM_SUCCESS.
+     Otherwise, return PAM_AUTHERR.
+6. If the response is a valid S/Key response, return PAM_SUCCESS.
+7. Otherwise, if no_default_skey is enabled (the user specifically
+   requested "s/key" authentication), return PAM_AUTHERR.
+8. Otherwise, store the response as the authentication token and
+   return PAM_IGNORE.
+
 About
 -----
 This is complete pam_skey modul as interface to existing S/Key
diff -Nur pam_skey-1.1.4/autoconf/acconfig.h pam_skey/autoconf/acconfig.h
--- pam_skey-1.1.4/autoconf/acconfig.h	2005-06-18 14:11:24.000000000 +0200
+++ pam_skey/autoconf/acconfig.h	2006-03-06 09:26:55.000000000 +0100
@@ -1,17 +1,2 @@
 /* Define if we can include both string.h and strings.h */
 #undef STRING_WITH_STRINGS
-
-/* Define if you have Linux */
-#undef LINUX
-
-/* Define if you have *BSD */
-#undef BSD
-
-/* Define if not missing skeyaccess() */
-#undef HAVE_SKEYACCESS
-
-/* Define if not missing skeyinfo() */
-#undef HAVE_SKEYINFO
-
-/* Define if you have skeylookup() instead of skeyinfo() */
-#undef HAVE_SKEYLOOKUP
diff -Nur pam_skey-1.1.4/autoconf/configure.in pam_skey/autoconf/configure.in
--- pam_skey-1.1.4/autoconf/configure.in	2005-06-18 14:11:24.000000000 +0200
+++ pam_skey/autoconf/configure.in	2006-03-06 09:26:55.000000000 +0100
@@ -10,21 +10,9 @@
 AC_LANG_C
 AC_LANG_SAVE
 
-dnl Get system type
-AC_CANONICAL_HOST
-MYHOST=$host_os
-case "$host_os" in
-*linux*)
-  AC_DEFINE(LINUX)
-  ;;
-*bsd*)
-  AC_DEFINE(BSD)
-  ;;
-esac
-
 dnl Package information
 PACKAGE=pam_skey
-VERSION=1.1
+VERSION=1.4r1
 
 dnl Standard installation path
 AC_PREFIX_DEFAULT(/usr)
@@ -65,13 +53,9 @@
 AC_ARG_WITH(skey-inc, [  --with-skey-inc=DIR     Directory containing skey include files], CFLAGS="${CFLAGS} -I${withval}")
 
 dnl Check for skey library
-AC_CHECK_LIB(socket, socket)
-AC_CHECK_LIB(nsl, gethostbyname)
+AC_CHECK_LIB(socket, socket, LIBS="${LIBS} -lsocket")
+AC_CHECK_LIB(nsl, gethostbyname, LIBS="${LIBS} -lnsl")
 AC_CHECK_LIB(skey, skeyverify, SKEYLIB="-lskey", AC_MSG_ERROR(skey library not found or unknown interface))
-AC_CHECK_LIB(skey, skeyaccess, AC_DEFINE(HAVE_SKEYACCESS))
-AC_CHECK_LIB(skey, skeyinfo, AC_DEFINE(HAVE_SKEYINFO),
-  AC_CHECK_LIB(skey, skeylookup, AC_DEFINE(HAVE_SKEYLOOKUP))
-)
 
 dnl Check against -G linker flag
 hold_ldflags=$LDFLAGS
diff -Nur pam_skey-1.1.4/configure pam_skey/configure
--- pam_skey-1.1.4/configure	2005-06-18 14:36:18.000000000 +0200
+++ pam_skey/configure	2006-03-06 09:27:41.000000000 +0100
@@ -310,7 +310,7 @@
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT SET_MAKE RM LN CP AWK INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CPP EGREP SKEYLIB PAMLIB MYHOST PACKAGE VERSION LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT SET_MAKE RM LN CP AWK INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CPP EGREP SKEYLIB PAMLIB MYHOST PACKAGE VERSION LIBOBJS LTLIBOBJS'
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -720,13 +720,13 @@
   	  /^X\(\/\).*/{ s//\1/; q; }
   	  s/.*/./; q'`
   srcdir=$ac_confdir
-  if test ! -r $srcdir/$ac_unique_file; then
+  if test ! -r "$srcdir/$ac_unique_file"; then
     srcdir=..
   fi
 else
   ac_srcdir_defaulted=no
 fi
-if test ! -r $srcdir/$ac_unique_file; then
+if test ! -r "$srcdir/$ac_unique_file"; then
   if test "$ac_srcdir_defaulted" = yes; then
     { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
    { (exit 1); exit 1; }; }
@@ -735,7 +735,7 @@
    { (exit 1); exit 1; }; }
   fi
 fi
-(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+(cd $srcdir && test -r "./$ac_unique_file") 2>/dev/null ||
   { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
    { (exit 1); exit 1; }; }
 srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
@@ -831,10 +831,6 @@
 _ACEOF
 
   cat <<\_ACEOF
-
-System types:
-  --build=BUILD     configure for building on BUILD [guessed]
-  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
 _ACEOF
 fi
 
@@ -948,7 +944,7 @@
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1333,78 +1329,8 @@
 
 
 
-# Make sure we can run config.sub.
-$ac_config_sub sun4 >/dev/null 2>&1 ||
-  { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
-echo "$as_me: error: cannot run $ac_config_sub" >&2;}
-   { (exit 1); exit 1; }; }
-
-echo "$as_me:$LINENO: checking build system type" >&5
-echo $ECHO_N "checking build system type... $ECHO_C" >&6
-if test "${ac_cv_build+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_cv_build_alias=$build_alias
-test -z "$ac_cv_build_alias" &&
-  ac_cv_build_alias=`$ac_config_guess`
-test -z "$ac_cv_build_alias" &&
-  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
-echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
-   { (exit 1); exit 1; }; }
-ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
-  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
-echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
-   { (exit 1); exit 1; }; }
-
-fi
-echo "$as_me:$LINENO: result: $ac_cv_build" >&5
-echo "${ECHO_T}$ac_cv_build" >&6
-build=$ac_cv_build
-build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-
-
-echo "$as_me:$LINENO: checking host system type" >&5
-echo $ECHO_N "checking host system type... $ECHO_C" >&6
-if test "${ac_cv_host+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_cv_host_alias=$host_alias
-test -z "$ac_cv_host_alias" &&
-  ac_cv_host_alias=$ac_cv_build_alias
-ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
-  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
-echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
-   { (exit 1); exit 1; }; }
-
-fi
-echo "$as_me:$LINENO: result: $ac_cv_host" >&5
-echo "${ECHO_T}$ac_cv_host" >&6
-host=$ac_cv_host
-host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-
-
-MYHOST=$host_os
-case "$host_os" in
-*linux*)
-  cat >>confdefs.h <<\_ACEOF
-#define LINUX 1
-_ACEOF
-
-  ;;
-*bsd*)
-  cat >>confdefs.h <<\_ACEOF
-#define BSD 1
-_ACEOF
-
-  ;;
-esac
-
 PACKAGE=pam_skey
-VERSION=1.1
+VERSION=1.4r1
 
 
 
@@ -1976,7 +1902,8 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2034,7 +1961,8 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2150,7 +2078,8 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2204,7 +2133,8 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2249,7 +2179,8 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2293,7 +2224,8 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2881,7 +2813,8 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3051,7 +2984,8 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3124,7 +3058,8 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3278,7 +3213,8 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3431,7 +3367,8 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3533,7 +3470,8 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3583,7 +3521,6 @@
   CFLAGS="${CFLAGS} -I${withval}"
 fi;
 
-
 echo "$as_me:$LINENO: checking for socket in -lsocket" >&5
 echo $ECHO_N "checking for socket in -lsocket... $ECHO_C" >&6
 if test "${ac_cv_lib_socket_socket+set}" = set; then
@@ -3622,7 +3559,8 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3648,15 +3586,9 @@
 echo "$as_me:$LINENO: result: $ac_cv_lib_socket_socket" >&5
 echo "${ECHO_T}$ac_cv_lib_socket_socket" >&6
 if test $ac_cv_lib_socket_socket = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBSOCKET 1
-_ACEOF
-
-  LIBS="-lsocket $LIBS"
-
+  LIBS="${LIBS} -lsocket"
 fi
 
-
 echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5
 echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6
 if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then
@@ -3695,7 +3627,8 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3721,12 +3654,7 @@
 echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5
 echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6
 if test $ac_cv_lib_nsl_gethostbyname = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBNSL 1
-_ACEOF
-
-  LIBS="-lnsl $LIBS"
-
+  LIBS="${LIBS} -lnsl"
 fi
 
 echo "$as_me:$LINENO: checking for skeyverify in -lskey" >&5
@@ -3767,7 +3695,8 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3800,218 +3729,6 @@
    { (exit 1); exit 1; }; }
 fi
 
-echo "$as_me:$LINENO: checking for skeyaccess in -lskey" >&5
-echo $ECHO_N "checking for skeyaccess in -lskey... $ECHO_C" >&6
-if test "${ac_cv_lib_skey_skeyaccess+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lskey  $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 gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char skeyaccess ();
-int
-main ()
-{
-skeyaccess ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&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); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_skey_skeyaccess=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_skey_skeyaccess=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_skey_skeyaccess" >&5
-echo "${ECHO_T}$ac_cv_lib_skey_skeyaccess" >&6
-if test $ac_cv_lib_skey_skeyaccess = yes; then
-  cat >>confdefs.h <<\_ACEOF
-#define HAVE_SKEYACCESS 1
-_ACEOF
-
-fi
-
-echo "$as_me:$LINENO: checking for skeyinfo in -lskey" >&5
-echo $ECHO_N "checking for skeyinfo in -lskey... $ECHO_C" >&6
-if test "${ac_cv_lib_skey_skeyinfo+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lskey  $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 gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char skeyinfo ();
-int
-main ()
-{
-skeyinfo ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&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); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_skey_skeyinfo=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_skey_skeyinfo=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_skey_skeyinfo" >&5
-echo "${ECHO_T}$ac_cv_lib_skey_skeyinfo" >&6
-if test $ac_cv_lib_skey_skeyinfo = yes; then
-  cat >>confdefs.h <<\_ACEOF
-#define HAVE_SKEYINFO 1
-_ACEOF
-
-else
-  echo "$as_me:$LINENO: checking for skeylookup in -lskey" >&5
-echo $ECHO_N "checking for skeylookup in -lskey... $ECHO_C" >&6
-if test "${ac_cv_lib_skey_skeylookup+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lskey  $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 gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char skeylookup ();
-int
-main ()
-{
-skeylookup ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&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); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_skey_skeylookup=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_skey_skeylookup=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_skey_skeylookup" >&5
-echo "${ECHO_T}$ac_cv_lib_skey_skeylookup" >&6
-if test $ac_cv_lib_skey_skeylookup = yes; then
-  cat >>confdefs.h <<\_ACEOF
-#define HAVE_SKEYLOOKUP 1
-_ACEOF
-
-fi
-
-
-fi
-
 
 hold_ldflags=$LDFLAGS
 echo "$as_me:$LINENO: checking for the ld -shared flag" >&5
@@ -4041,7 +3758,8 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4099,7 +3817,8 @@
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4747,14 +4466,6 @@
 s,@ECHO_N@,$ECHO_N,;t t
 s,@ECHO_T@,$ECHO_T,;t t
 s,@LIBS@,$LIBS,;t t
-s,@build@,$build,;t t
-s,@build_cpu@,$build_cpu,;t t
-s,@build_vendor@,$build_vendor,;t t
-s,@build_os@,$build_os,;t t
-s,@host@,$host,;t t
-s,@host_cpu@,$host_cpu,;t t
-s,@host_vendor@,$host_vendor,;t t
-s,@host_os@,$host_os,;t t
 s,@CC@,$CC,;t t
 s,@CFLAGS@,$CFLAGS,;t t
 s,@LDFLAGS@,$LDFLAGS,;t t
@@ -4945,6 +4656,11 @@
   *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
   esac
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -4983,12 +4699,6 @@
 	 fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
diff -Nur pam_skey-1.1.4/defs.h.in pam_skey/defs.h.in
--- pam_skey-1.1.4/defs.h.in	2005-06-18 14:36:18.000000000 +0200
+++ pam_skey/defs.h.in	2006-03-06 09:26:55.000000000 +0100
@@ -1,96 +1,49 @@
-/* defs.h.in.  Generated from configure.in by autoheader.  */
-/* Define if we can include both string.h and strings.h */
-#undef STRING_WITH_STRINGS
-
-/* Define if you have Linux */
-#undef LINUX
-
-/* Define if you have *BSD */
-#undef BSD
+/* defs.h.in.  Generated automatically from configure.in by autoheader.  */
 
-/* Define if not missing skeyaccess() */
-#undef HAVE_SKEYACCESS
-
-/* Define if not missing skeyinfo() */
-#undef HAVE_SKEYINFO
+/* Define if you have the ANSI C header files.  */
+#undef STDC_HEADERS
 
-/* Define if you have skeylookup() instead of skeyinfo() */
-#undef HAVE_SKEYLOOKUP
+/* Define if we can include both string.h and strings.h */
+#undef STRING_WITH_STRINGS
 
-/* Define to 1 if you have the `fprintf' function. */
+/* Define if you have the fprintf function.  */
 #undef HAVE_FPRINTF
 
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
+/* Define if you have the gethostbyname function.  */
+#undef HAVE_GETHOSTBYNAME
 
-/* Define to 1 if you have the `nsl' library (-lnsl). */
-#undef HAVE_LIBNSL
+/* Define if you have the snprintf function.  */
+#undef HAVE_SNPRINTF
 
-/* Define to 1 if you have the `socket' library (-lsocket). */
-#undef HAVE_LIBSOCKET
+/* Define if you have the strncmp function.  */
+#undef HAVE_STRNCMP
 
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
+/* Define if you have the syslog function.  */
+#undef HAVE_SYSLOG
 
-/* Define to 1 if you have the <pwd.h> header file. */
+/* Define if you have the <pwd.h> header file.  */
 #undef HAVE_PWD_H
 
-/* Define to 1 if you have the <security/pam_appl.h> header file. */
+/* Define if you have the <security/pam_appl.h> header file.  */
 #undef HAVE_SECURITY_PAM_APPL_H
 
-/* Define to 1 if you have the <security/pam_modules.h> header file. */
+/* Define if you have the <security/pam_modules.h> header file.  */
 #undef HAVE_SECURITY_PAM_MODULES_H
 
-/* Define to 1 if you have the `snprintf' function. */
-#undef HAVE_SNPRINTF
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
+/* Define if you have the <stdlib.h> header file.  */
 #undef HAVE_STDLIB_H
 
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
+/* Define if you have the <string.h> header file.  */
 #undef HAVE_STRING_H
 
-/* Define to 1 if you have the `strncmp' function. */
-#undef HAVE_STRNCMP
-
-/* Define to 1 if you have the `syslog' function. */
-#undef HAVE_SYSLOG
-
-/* Define to 1 if you have the <syslog.h> header file. */
-#undef HAVE_SYSLOG_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
+/* Define if you have the <strings.h> header file.  */
+#undef HAVE_STRINGS_H
 
-/* Define to 1 if you have the <sys/syslog.h> header file. */
+/* Define if you have the <sys/syslog.h> header file.  */
 #undef HAVE_SYS_SYSLOG_H
 
-/* Define to 1 if you have the <sys/types.h> header file. */
+/* Define if you have the <sys/types.h> header file.  */
 #undef HAVE_SYS_TYPES_H
 
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
+/* Define if you have the <syslog.h> header file.  */
+#undef HAVE_SYSLOG_H
diff -Nur pam_skey-1.1.4/pam_skey.c pam_skey/pam_skey.c
--- pam_skey-1.1.4/pam_skey.c	2005-06-18 14:36:18.000000000 +0200
+++ pam_skey/pam_skey.c	2006-03-06 09:26:55.000000000 +0100
@@ -1,5 +1,6 @@
 /* 
- * (c) 2001 Dinko Korunic, kreator@srce.hr
+ * Rewrite (c) 2005 Dani Church, dani.church@gmail.com
+ * Original (c) 2001 Dinko Korunic, kreator@srce.hr
  *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
@@ -33,272 +34,146 @@
 #include <pwd.h> 
 #include <sys/types.h>
 #include <syslog.h>
+#include <ctype.h>
 
 #define PAM_EXTERN extern
 #undef PAM_STATIC
 
 #include <security/pam_appl.h>
 #include <security/pam_modules.h>
+#include <security/_pam_macros.h>
 
 #include "skey.h"
 #include "pam_skey.h"
 #include "misc.h"
 
+#define LOGDEBUG(x) if (mod_opt & _MOD_DEBUG) { syslog x ;}
+#define QUERY_USERNAME NULL /* Use default username prompt */
+#define QUERY_PASSWORD "Password: "
+#define QUERY_RESPONSE_OR_PASSWORD "S/Key response or system password: "
+#define QUERY_RESPONSE "S/Key response: "
+
 PAM_EXTERN int pam_sm_setcred (pam_handle_t *pamh, int flags,
   int argc, const char **argv)
 {
   return PAM_SUCCESS;
 }
 
+/*
+ * The authentication module will return the following status codes:
+ * PAM_SUCCESS: Successful authentication via S/Key.
+ * PAM_IGNORE: The user doesn't have S/Key or doesn't want to use it.
+ *             Continue with the next module, using try_first_pass.
+ * PAM_AUTH_ERR: The user asked to use S/Key, but failed the authentication.
+ *               Don't try any more PAM modules.
+ * others: random errors, try next authentication method
+ */
+
 PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags,
   int argc, const char **argv)
 {
-  char challenge[CHALLENGE_MAXSIZE]; /* challenge to print in conv */
-  char msg_text[PAM_MAX_MSG_SIZE]; /* text for pam conv */
-  char *username = NULL; /* username spacer */
+  const char *challenge; /* challenge to print in conv */
+  const char *username = NULL; /* username spacer */
   char *response = NULL; /* response spacer */
-  struct skey skey; /* structure that contains skey information */
   int status; /* return status spacer */
-  unsigned mod_opt = _MOD_NONE_ON; /* module options */
+  unsigned mod_opt=_MOD_NONE_ON; /* module options */
 
   /* Get module options */
   mod_getopt(&mod_opt, argc, argv);
 
-  /* Get username */
-#if defined LINUX || defined BSD
-  if (pam_get_user(pamh, (const char **)&username, "login:")
-#else
-  if (pam_get_user(pamh, (char **)&username, "login:")
-#endif
-      != PAM_SUCCESS)
-  {
-    fprintf(stderr, "cannot determine username\n");
-    if (mod_opt & _MOD_DEBUG)
-      syslog(LOG_DEBUG, "cannot determine username");
-    return PAM_USER_UNKNOWN;
-  }
-
-  if (mod_opt & _MOD_DEBUG)
-    syslog(LOG_DEBUG, "got username %s", username);
-
-#ifdef HAVE_SKEYACCESS
-  /* Check S/Key access permissions - user, host and port. Also include
-   * sanity checks */
-  if (mod_opt & _MOD_ACCESS_CHECK)
-  {
-    char *host; /* points to host */
-    char *port; /* points to port */
-    struct passwd *pwuser; /* structure for getpw() */
-
-    /* Get host.. */
-#if defined LINUX || defined BSD
-    if (pam_get_item(pamh, PAM_RHOST, (const void **)&host)
-#else
-    if (pam_get_item(pamh, PAM_RHOST, (void **)&host)
-#endif
-        != PAM_SUCCESS)
-      host = NULL; /* couldn't get host */
-    /* ..and port */
-#if defined LINUX || defined BSD
-    if (pam_get_item(pamh, PAM_TTY, (const void **)&port)
-#else
-    if (pam_get_item(pamh, PAM_TTY, (void **)&port)
-#endif
-        != PAM_SUCCESS)
-      port = NULL; /* couldn't get port */
-
-    if (mod_opt & _MOD_DEBUG)
-      syslog(LOG_DEBUG, "checking s/key access for user %s,"
-        " host %s, port %s", username,
-        (host != NULL) ? host : "*unknown*",
-        (port != NULL) ? port : "*unknown*");
-
-    /* Get information from passwd file */
-    if ((pwuser = getpwnam(username)) == NULL)
-    {
-      fprintf(stderr, "no such user\n");
-      syslog(LOG_NOTICE, "cannot find user %s", username);
-      return PAM_USER_UNKNOWN; /* perhaps even return PAM_ABORT here? */
+  /* Get username (taken mainly from pam_unix) */
+  status = pam_get_user(pamh, &username, QUERY_USERNAME);
+  if (status == PAM_SUCCESS) {
+    if (username == NULL || !isalnum(*username)) {
+      syslog(LOG_ERR, "bad username [%s]", username);
+      return PAM_USER_UNKNOWN;
     }
+    LOGDEBUG((LOG_DEBUG, "username [%s] obtained", username));
+  } else {
+    LOGDEBUG((LOG_DEBUG, "trouble reading username"));
+    if (status == PAM_CONV_AGAIN)
+      return PAM_INCOMPLETE;
+    return status;
+  }
 
-    /* Do actual checking - we assume skeyaccess() returns PERMIT which is
-     * by default 1. Notice 4th argument is NULL - we will not perform
-     * address checks on host itself */
-    if (skeyaccess(pwuser, port, host, NULL) != 1)
-    {
-      fprintf(stderr, "no s/key access permissions\n");
-      syslog(LOG_NOTICE, "no s/key access permissions for %s",
-          username);
-      return PAM_AUTH_ERR;
-    }
+  /* Check whether or not this user has an S/Key */
+  if (skey_haskey(username) != 0) {
+    LOGDEBUG((LOG_DEBUG, "user [%s] has no S/Key entry", username));
+    return PAM_IGNORE;
   }
-  else
 
-#endif /* HAVE_SKEYACCESS */
-    
-  /* Only do check whether user has passwd entry */
-    if (getpwnam(username) == NULL)
-    {
-      fprintf(stderr, "no such user\n");
-      if (mod_opt & _MOD_DEBUG)
-        syslog(LOG_DEBUG, "cannot find user %s",
-            username);
-      return PAM_USER_UNKNOWN;
+  if ((mod_opt & _MOD_TRY_FIRST_PASS) || (mod_opt & _MOD_USE_FIRST_PASS)) {
+    status = pam_get_item(pamh, PAM_AUTHTOK, (const void **) &response);
+    if (status != PAM_SUCCESS) {
+      syslog(LOG_ALERT, "pam_get_item returned error to pam_skey");
+      return status;
+    } else if (response != NULL) {
+      if (skey_passcheck(username, response) != -1) {
+	return PAM_SUCCESS;
+      } else if (mod_opt & _MOD_USE_FIRST_PASS) {
+	return PAM_IGNORE;
+      }
+    } else if (mod_opt & _MOD_USE_FIRST_PASS) {
+      return PAM_AUTHTOK_RECOVER_ERR;
     }
-
-  /* Get S/Key information on user with skeyinfo() */
-#ifdef HAVE_SKEYINFO
-  switch (skeyinfo(&skey, username, NULL))
-#else
-#ifdef HAVE_SKEYLOOKUP
-  switch (skeylookup(&skey, username))
-#endif /* HAVE_SKEYLOOKUP */
-#endif /* HAVE_SKEYINFO */
-  {
-  /* 0: OK */
-  case 0:
-    break;
-  /* -1: File error */
-  case -1:
-#if 0
-  /* XXX- This seems broken in (at least) logdaemon-5.8. It returns -1
-   * when user not found in keyfile. -kre */
-    fprintf(stderr, "s/key database error\n");
-    syslog(LOG_NOTICE, "s/key database error");
-    return PAM_AUTH_ERR;
-#endif
-  /* 1: No such user in database */
-  case 1:
-    /* We won't confuse the ordinary user telling him about missing skeys
-     * -kre */
-#if 0
-    fprintf(stderr, "no s/key for %s\n", username);
-#endif
-    if (mod_opt & _MOD_DEBUG)
-      syslog(LOG_DEBUG, "no s/key for %s\n", username);
-    return PAM_AUTH_ERR;
   }
-
-  /* Make challenge string */
-#if defined(SKEY_MAX_HASHNAME_LEN) && defined(SKEY_MAX_SEED_LEN)
-  snprintf(challenge, CHALLENGE_MAXSIZE, "otp-%.*s %d %.*s",
-      SKEY_MAX_HASHNAME_LEN, skey_get_algorithm(), skey.n - 1, SKEY_MAX_SEED_LEN, skey.seed);
-#else
-  snprintf(challenge, CHALLENGE_MAXSIZE, "s/key %d %s",
-      skey.n - 1, skey.seed);
-#endif
-
-  if (mod_opt & _MOD_DEBUG)
-    syslog(LOG_DEBUG, "got challenge %s for %s", challenge,
-        username);
-
-  /* Read response from last module's PAM_AUTHTOK */
-  if (mod_opt & _MOD_USE_FIRST_PASS)
-  {
-    /* Try to extract authtoken */
-#if defined LINUX || defined BSD
-    if (pam_get_item(pamh, PAM_AUTHTOK, (const void **)&response)
-#else
-    if (pam_get_item(pamh, PAM_AUTHTOK, (void **)&response)
-#endif
-        != PAM_SUCCESS)
-    {
-      if (mod_opt & _MOD_DEBUG)
-        syslog(LOG_DEBUG, "could not get PAM_AUTHTOK");
-      mod_opt &= ~_MOD_USE_FIRST_PASS;
+  
+  if (mod_opt & _MOD_NO_DEFAULT_SKEY) {
+    status = mod_talk_touser(pamh, mod_opt, NULL, QUERY_PASSWORD, 0, &response);
+    if (status != PAM_SUCCESS) {
+      _pam_delete(response)
+      return status;
     }
-    else
-    {
-      /* Got AUTHTOK, but it was empty */
-      if (empty_authtok(response))
-      {
-        if (mod_opt & _MOD_DEBUG)
-          syslog(LOG_DEBUG, "empty PAM_AUTHTOK");
-        mod_opt &= ~_MOD_USE_FIRST_PASS;
-      }
-      else
-        /* All OK, print challenge information */
-        fprintf(stderr, "challenge %s\n", challenge);
+    if (strcasecmp(response,"s/key")!=0) {
+      status = pam_set_item(pamh, PAM_AUTHTOK, response);
+      if (status != PAM_SUCCESS)
+	return status;
+      return PAM_IGNORE;
     }
+    _pam_delete(response);
   }
 
-  /* There was no PAM_AUTHTOK, or there was no such option in pam-conf
-   * file */
-  if (!(mod_opt & _MOD_USE_FIRST_PASS))
-  {
-    /* Prepare a complete message for conversation */
-    snprintf(msg_text, PAM_MAX_MSG_SIZE,
-        "challenge %s\npassword: ", challenge);
-
-    /* Talk with user */
-    if (mod_talk_touser(pamh, &mod_opt, msg_text, &response)
-        != PAM_SUCCESS)
-      return PAM_SERVICE_ERR;
-
-    /* Simulate standard S/Key login procedure - if empty token, turn on
-     * ECHO and prompt again */
-    if (empty_authtok(response) && !(mod_opt & _MOD_ONLY_ONE_TRY))
-    {
-      /* Was there echo off? */
-      if (mod_opt & _MOD_ECHO_OFF)
-      {
-        _pam_delete(response);
-        fprintf(stderr, "(turning echo on)\n");
-        mod_opt &= ~_MOD_ECHO_OFF;
-
-        /* Prepare a complete message for conversation */
-        snprintf(msg_text, PAM_MAX_MSG_SIZE, "password: ");
-
-        /* Talk with user */
-        if (mod_talk_touser(pamh, &mod_opt, msg_text, &response)
-          != PAM_SUCCESS)
-          return PAM_SERVICE_ERR;
-
-        /* Got again empty response. Bailout and don't save auth token */
-        if (empty_authtok(response))
-          return PAM_AUTH_ERR;
-      }
-      else
-      /* There was echo on already - just get out and don't save auth token
-       * for other modules */
-        return PAM_AUTH_ERR;
-    }
+  challenge = skey_keyinfo(username);
+  if (challenge == NULL) {
+    syslog(LOG_ALERT, "Could not retrieve S/Key challenge for [%s]", username);
+    return PAM_AUTHINFO_UNAVAIL;
+  }
 
-    /* XXX - ECHO ON puts '\n' at the end in Solaris 2.7! This is
-     * cludge to get rid of this nasty `feature' -kre */
-    _pam_degarbage(response);
-  
-    /* Store auth token - that next module can use with `use_first_pass' */
-    if (pam_set_item(pamh, PAM_AUTHTOK, response) != PAM_SUCCESS)
-    {
-      syslog(LOG_NOTICE, "unable to save auth token");
-      return PAM_SERVICE_ERR;
-    }
+  if (mod_opt & _MOD_NO_DEFAULT_SKEY) 
+    status = mod_talk_touser(pamh, mod_opt, challenge, QUERY_RESPONSE, 0, &response);
+  else
+    status = mod_talk_touser(pamh, mod_opt, challenge, QUERY_RESPONSE_OR_PASSWORD, 0, &response);
 
-    /* cleanup conversation */
+  if (status != PAM_SUCCESS)
+    return status;
+  
+  if (*response == '\0') {
     _pam_delete(response);
-  } 
-
-  /* Verify S/Key */
-  status = skeyverify(&skey, response);
+    status = mod_talk_touser(pamh, mod_opt, NULL, QUERY_RESPONSE, 1, &response);
+    if (status != PAM_SUCCESS)
+      return status;
+    status = pam_set_item(pamh, PAM_AUTHTOK, response);
+    status = skey_passcheck(username, response);
+    _pam_delete(response);
+    if (status != -1)
+      return PAM_SUCCESS;
+    return PAM_AUTH_ERR;
+  }
 
-  switch (status)
-  {
-    /* 0: Verify successful, database updated */
-    case 0:
-      break;
-    /* -1: Error of some sort; database unchanged */
-    /*  1: Verify failed, database unchanged */
-    case -1:
-    case 1:
-      if (mod_opt & _MOD_DEBUG)
-        syslog(LOG_DEBUG, "verify for %s failed, database"
-            " unchanged", username);
-      return PAM_AUTH_ERR;
+  status = pam_set_item(pamh, PAM_AUTHTOK, response);
+  status = skey_passcheck(username, response);
+  if (status != -1) {
+    _pam_delete(response);
+    return PAM_SUCCESS;
+  }
+  
+  if (mod_opt & _MOD_NO_DEFAULT_SKEY) {
+    _pam_delete(response);
+    return PAM_AUTH_ERR;
   }
 
-  /* Success by default */
-  return PAM_SUCCESS;
+  status = pam_set_item(pamh, PAM_AUTHTOK, response);
+  return PAM_IGNORE;
 }
 
 /* Get module optional parameters */
@@ -332,50 +207,43 @@
 }
 
 /* This will talk to user through PAM_CONV */
-static int mod_talk_touser(pam_handle_t *pamh, unsigned *mod_opt,
-    char *msg_text, char **response)
+static int mod_talk_touser(pam_handle_t *pamh, unsigned mod_opt,
+    const char *info_text, const char *prompt_text, int echo_on, char **response)
 {
-  struct pam_message message;
-  const struct pam_message *pmessage = &message;
+  struct pam_message message[2], *pmessage[2];
   struct pam_conv *conv = NULL;
   struct pam_response *presponse = NULL;
-
+  int i=0;
+  
   /* Better safe than sorry */
   *response = NULL;
 
   /* Be paranoid */
   memset(&message, 0, sizeof(message));
 
-  /* Turn on/off PAM echo */
-  if (*mod_opt & _MOD_ECHO_OFF)
-    message.msg_style = PAM_PROMPT_ECHO_OFF;
-  else
-    message.msg_style = PAM_PROMPT_ECHO_ON;
+  pmessage[0] = &message[0];
+  pmessage[1] = &message[1];
+  
+  /* Set info text, if any */
+  if (info_text) {
+    message[i].msg = info_text;
+    message[i].msg_style = PAM_TEXT_INFO;
+    i++;
+  }
   
-  /* Point to conversation text */
-  message.msg = msg_text;
+  /* Set prompt text */
+  message[i].msg = prompt_text;
+  message[i].msg_style = echo_on ? PAM_PROMPT_ECHO_ON : PAM_PROMPT_ECHO_OFF;
+  i++;
 
   /* Do conversation and see if all is OK */
-#if defined LINUX || defined BSD
-  if (pam_get_item(pamh, PAM_CONV, (const void **)&conv)
-#else
-  if (pam_get_item(pamh, PAM_CONV, (void **)&conv)
-#endif
-      != PAM_SUCCESS)
-  {
-    if (*mod_opt & _MOD_DEBUG)
-      syslog(LOG_DEBUG, "error in conversation");
+  if (pam_get_item(pamh, PAM_CONV, (const void **)&conv) != PAM_SUCCESS) {
+    LOGDEBUG((LOG_DEBUG, "error in conversation"));
     return PAM_SERVICE_ERR;
   }
-
-  /* Convert into pam_response - only 1 reply expected */
-#if defined LINUX || defined BSD
-  if (conv->conv(1, &pmessage, &presponse,
+  /* Convert into pam_response */
+  if (conv->conv(i, (const struct pam_message **)pmessage, &presponse,
         conv->appdata_ptr)
-#else
-  if (conv->conv(1, (struct pam_message **)&pmessage, &presponse,
-        conv->appdata_ptr)
-#endif
     != PAM_SUCCESS)
   {
     _pam_delete(presponse->resp);
@@ -385,10 +253,10 @@
   if (presponse != NULL)
   {
     /* Save address */
-    *response = presponse->resp;
+    *response = presponse[i-1].resp;
     /* To ensure that response address will not be erased */
-    presponse->resp = NULL;
-    _pam_drop(presponse);
+    presponse[i-1].resp = NULL;
+    _pam_drop_reply(presponse,i);
   }
   else
     return PAM_SERVICE_ERR;
diff -Nur pam_skey-1.1.4/pam_skey.h pam_skey/pam_skey.h
--- pam_skey-1.1.4/pam_skey.h	2005-06-18 14:36:18.000000000 +0200
+++ pam_skey/pam_skey.h	2006-03-06 09:26:55.000000000 +0100
@@ -22,29 +22,25 @@
  */
 
 /* Prototypes */
-#ifndef BSD
-extern int skeyinfo(struct skey *, char *, char *); /* ORGH! Not in skey.h */
-#endif
-
 static void mod_getopt(unsigned *, int, const char **);
-static int mod_talk_touser(pam_handle_t *, unsigned *, char *, char **);
+static int mod_talk_touser(pam_handle_t *, unsigned, const char *, const char *, int, char **);
 
 /* free() macro */
-#define _pam_drop(X)  \
+/*#define _pam_drop(X)  \
 if (X != NULL)        \
 {                     \
   free(X);            \
   X = NULL;           \
-}
+}*/
 
 /* Secure overwrite */
-#define _pam_overwrite(x)   \
+/*#define _pam_overwrite(x)   \
 {                           \
   register char *__xx__;    \
   if ((__xx__ = (x)))       \
     while (*__xx__)         \
     *__xx__++ = '\0';       \
-}
+}*/
 
 /* Drop-in secure replacement - we do not want cleartext passwords lying
  * scattered around */
@@ -56,7 +52,7 @@
 
 /* This will get us rid of first '\n' in response string and cut-off the
  * rest of the string. It should be ASCIIZ, of course */
-#define _pam_degarbage(x)      \
+/*#define _pam_degarbage(x)      \
 {                              \
   register char *__xx__;       \
     if ((__xx__ = (x)))        \
@@ -70,30 +66,25 @@
         else                   \
           __xx__++;            \
       }                        \
-}
+}*/
 
 /* Handy empty AUTHTOK macro */
 #define empty_authtok(a) (a == NULL || !*a || *a == '\n')
 
-/* Maximum challenge size. It should be 64, but be sure */
-#define CHALLENGE_MAXSIZE 128
-
 /* Define module flags */
-#define _MOD_NONE_ON        0x0000      /* Generic flag */
-#define _MOD_ALL_ON    (~_MOD_NONE_ON)  /* Generic mask */
-#define _MOD_DEBUG          0x0001      /* Debugging options on */
-#define _MOD_ECHO_OFF       0x0002      /* PAM_ECHO_OFF */
-#define _MOD_ACCESS_CHECK   0x0004      /* Check S/Key access permissions */
-#define _MOD_USE_FIRST_PASS 0x0008      /* Use PAM_AUTHTOK */
-#define _MOD_ONLY_ONE_TRY   0x0010      /* Only one try, no matter of echo */
-#define _MOD_SPACER         0x0020      /* Currently unused */
+#define _MOD_NONE_ON         0x0000	/* Generic flag */
+#define _MOD_ALL_ON    (~_MOD_NONE_ON)	/* Generic mask */
+#define _MOD_DEBUG           0x0001	/* Debugging options on */
+#define _MOD_TRY_FIRST_PASS  0x0002	/* Attempt using PAM_AUTHTOK */
+#define _MOD_USE_FIRST_PASS  0x0004	/* Only use PAM_AUTHTOK */
+#define _MOD_NO_DEFAULT_SKEY 0x0008	/* Don't use S/Key by default */
 
 /* Setup defaults - use echo off only */
-#define _MOD_DEFAULT_FLAG   _MOD_ECHO_OFF
+#define _MOD_DEFAULT_FLAG   _MOD_NONE_ON
 #define _MOD_DEFAULT_MASK   _MOD_ALL_ON
 
 /* Number of parameters currently known */
-#define _MOD_ARGS           8
+#define _MOD_ARGS           4
 
 /* Structure for flexible argument parsing */
 typedef struct
@@ -108,11 +99,7 @@
 {
   /* String            Mask                           Flag */
   {"debug",            _MOD_ALL_ON,                   _MOD_DEBUG},
-  {"echo=off",         _MOD_ALL_ON,                   _MOD_ECHO_OFF},
-  {"echo=on",          _MOD_ALL_ON^_MOD_ECHO_OFF,     _MOD_NONE_ON},
-  {"access_check=on",  _MOD_ALL_ON,                   _MOD_ACCESS_CHECK},
-  {"access_check=off", _MOD_ALL_ON^_MOD_ACCESS_CHECK, _MOD_NONE_ON},
+  {"try_first_pass",   _MOD_ALL_ON,                   _MOD_TRY_FIRST_PASS},
   {"use_first_pass",   _MOD_ALL_ON,                   _MOD_USE_FIRST_PASS},
-  {"try_first_pass",   _MOD_ALL_ON,                   _MOD_USE_FIRST_PASS},
-  {"only_one_try",     _MOD_ALL_ON,                   _MOD_ONLY_ONE_TRY}
+  {"no_default_skey",  _MOD_ALL_ON,                   _MOD_NO_DEFAULT_SKEY}
 };
diff -Nur pam_skey-1.1.4/pam_skey_access.c pam_skey/pam_skey_access.c
--- pam_skey-1.1.4/pam_skey_access.c	2005-06-18 14:36:18.000000000 +0200
+++ pam_skey/pam_skey_access.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,161 +0,0 @@
-/* 
- * (c) 2001 Dinko Korunic, kreator@srce.hr
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- *
- * S/KEY is a trademark of Bellcore.
- * Mink is the former name of the S/KEY authentication system.
- *
- * Programs that had some influence in development of this source:
- *  Wietse Venema's logdaemon package
- *  Olaf Kirch's Linux S/Key package
- *  Linux-PAM modules and templates
- *  Wyman Miles' pam_securid module
- *
- * Should you choose to use and/or modify this source code, please do so
- * under the terms of the GNU General Public License under which this
- * program is distributed.
- */
-
-static char rcsid[] = "$Id: pam_skey_access.c,v 1.2 2005/06/18 12:36:18 kreator Exp $";
-
-#include "defs.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#ifdef STRING_WITH_STRINGS
-# include <strings.h>
-#endif
-#include <unistd.h>
-#include <pwd.h> 
-#include <sys/types.h>
-#include <syslog.h>
-
-#define PAM_EXTERN extern
-#undef PAM_STATIC
-
-#include <security/pam_appl.h>
-#include <security/pam_modules.h>
-
-#include "skey.h"
-#include "pam_skey.h"
-#include "misc.h"
-
-PAM_EXTERN int pam_sm_setcred (pam_handle_t *pamh, int flags,
-  int argc, const char **argv)
-{
-  return PAM_SUCCESS;
-}
-
-PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags,
-  int argc, const char **argv)
-{
-  char *username = NULL; /* will point to username */
-  unsigned mod_opt = _MOD_NONE_ON; /* module options */
-  char *host; /* will point to host */
-  char *port; /* will point to port */
-  struct passwd *pwuser;
-
-  /* Get module options */
-  mod_getopt(&mod_opt, argc, argv);
-
-  /* Get username */
-#if defined LINUX || defined BSD
-  if (pam_get_user(pamh, (const char **)&username, "login:")!=PAM_SUCCESS)
-#else
-  if (pam_get_user(pamh, (char **)&username, "login:")!=PAM_SUCCESS)
-#endif
-  {
-    fprintf(stderr, "cannot determine username\n");
-    if (mod_opt & _MOD_DEBUG)
-      syslog(LOG_DEBUG, "cannot determine username");
-    return PAM_AUTHINFO_UNAVAIL;
-  }
-
-  if (mod_opt & _MOD_DEBUG)
-    syslog(LOG_DEBUG, "got username %s", username);
-
-  /* Check S/Key access permissions - user, host and port. Also include
-   * sanity checks */
-  /* Get host.. */
-#if defined LINUX || defined BSD
-  if (pam_get_item(pamh, PAM_RHOST, (const void **)&host)
-#else
-  if (pam_get_item(pamh, PAM_RHOST, (void **)&host)
-#endif
-    != PAM_SUCCESS)
-      host = NULL;
-  /* ..and port */
-#ifdef LINUX
-  if (pam_get_item(pamh, PAM_TTY, (const void **)&port)
-#else
-  if (pam_get_item(pamh, PAM_TTY, (void **)&port)
-#endif
-    != PAM_SUCCESS)
-      port = NULL;
-
-  if (mod_opt & _MOD_DEBUG)
-    syslog(LOG_DEBUG, "checking s/key access for user %s,"
-      " host %s, port %s", username,
-      (host != NULL) ? host : "*unknown*",
-      (port != NULL) ? port : "*unknown*");
-
-  /* Get information from passwd file */
-  if ((pwuser = getpwnam(username)) == NULL)
-  {
-    fprintf(stderr, "no such user\n");
-    syslog(LOG_NOTICE, "cannot find user %s",
-      username);
-    return PAM_AUTHINFO_UNAVAIL;
-  }
-
-#ifdef HAVE_SKEYACCESS
-
-  /* Do actual checking - we assume skeyaccess() returns PERMIT which is
-   * by default 1. Notice 4th argument is NULL - we will not perform
-   * address checks on host itself */
-  if (skeyaccess(pwuser, port, host, NULL) != 1)
-  {
-    fprintf(stderr, "no s/key access permissions\n");
-    syslog(LOG_NOTICE, "no s/key access permissions for %s",
-        username);
-    return PAM_AUTH_ERR;
-  }
-
-#endif /* HAVE_SKEYACCESS */
-
-  return PAM_SUCCESS;
-}
-
-/* Get module optional parameters */
-static void mod_getopt(unsigned *mod_opt, int mod_argc, const char **mod_argv)
-{
-  int i;
-
-  /* Setup runtime defaults */
-  *mod_opt |= _MOD_DEFAULT_FLAG;
-  *mod_opt &= _MOD_DEFAULT_MASK;
-
-  /* Setup runtime options */
-  while (mod_argc--)
-  {
-    for (i = 0; i < _MOD_ARGS; ++i)
-    {
-      if (mod_args[i].token != NULL &&
-          !strncmp(*mod_argv, mod_args[i].token,
-            strlen(mod_args[i].token)))
-        break;
-    }
-    if (i >= _MOD_ARGS)
-      syslog(LOG_ERR, "unknown option %s", *mod_argv);
-    else
-    {
-      *mod_opt &= mod_args[i].mask; /* Turn off */
-      *mod_opt |= mod_args[i].flag; /* Turn on */
-    }
-    ++mod_argv;
-  }
-}

