--- ssh-1.2.22/acconfig.h.pam	Tue Jan 20 13:23:46 1998
+++ ssh-1.2.22/acconfig.h	Wed Jan 21 13:22:00 1998
@@ -368,3 +368,6 @@
 
 /* Define this if your spwd struct defined shadow.h have sp_inact field */
 #undef HAVE_STRUCT_SPWD_INACT
+
+/* Define this if you use PAM */
+#undef HAVE_PAM
--- ssh-1.2.22/auth-passwd.c.pam	Tue Jan 20 13:23:48 1998
+++ ssh-1.2.22/auth-passwd.c	Wed Jan 21 14:03:01 1998
@@ -21,6 +21,9 @@
  * 	Fixed kerberos ticket name handling. Added OSF C2 account
  * 	locking and expiration support.
  *
+ * Revision 1.11a 1997/06/06 06:40:00  jonchen
+ *    Added support for PAM
+ *
  * Revision 1.11  1997/04/17 03:57:05  kivinen
  * 	Kept FILE: prefix in kerberos ticket filename as DCE cache
  * 	code requires it (patch from Doug Engert <DEEngert@anl.gov>).
@@ -112,6 +115,13 @@
 #include <auth.h>
 #include <sys/svcinfo.h>
 #endif /* HAVE_ULTRIX_SHADOW_PASSWORDS */
+#ifdef HAVE_PAM
+#include <security/pam_appl.h>
+extern pam_handle_t *pamh;
+extern int retval;
+extern char* pampasswd;
+extern int origretval;
+#endif /* HAVE_PAM */
 #include "packet.h"
 #include "ssh.h"
 #include "servconf.h"
@@ -672,6 +682,17 @@
   seteuid(UID_ROOT);                /* just let it fail if ran by user */
 #endif /* SECURE_RPC */
 
+#ifdef HAVE_PAM
+  {
+    retval = origretval;
+    pampasswd = xstrdup(password);
+    if (retval == PAM_SUCCESS)
+      retval = pam_authenticate ((pam_handle_t *)pamh, 0);
+    if (retval == PAM_SUCCESS)
+      retval = pam_acct_mgmt ((pam_handle_t *)pamh, 0);
+    xfree(pampasswd);
+  }
+#else /* HAVE_PAM */
 #ifdef HAVE_OSF1_C2_SECURITY
   switch (osf1c2_getprpwent(correct_passwd, saved_pw_name,
 			    sizeof(correct_passwd)))
@@ -764,6 +785,7 @@
 #endif /* HAVE_ETC_SHADOW */
 #endif /* HAVE_SCO_ETC_SHADOW */
 #endif /* HAVE_OSF1_C2_SECURITY */
+#endif /* HAVE_PAM */
 
   /* Check for users with no password. */
   if (strcmp(password, "") == 0 && strcmp(correct_passwd, "") == 0)
@@ -783,6 +805,14 @@
 
   xfree(saved_pw_name);
   xfree(saved_pw_passwd);
+
+#ifdef HAVE_PAM
+  {
+    if (retval == PAM_SUCCESS) 
+      retval = pam_open_session ((pam_handle_t *)pamh, 0);
+    return (retval == PAM_SUCCESS);
+  }
+#endif /* HAVE_PAM */
 
 #ifdef HAVE_ULTRIX_SHADOW_PASSWORDS
   {
--- ssh-1.2.22/config.h.in.pam	Tue Jan 20 13:24:14 1998
+++ ssh-1.2.22/config.h.in	Wed Jan 21 13:22:01 1998
@@ -415,6 +415,9 @@
 /* Define this if your spwd struct defined shadow.h have sp_inact field */
 #undef HAVE_STRUCT_SPWD_INACT
 
+/* Define this if you use PAM */
+#undef HAVE_PAM
+
 /* The number of bytes in a int.  */
 #undef SIZEOF_INT
 
--- ssh-1.2.22/configure.pam	Wed Jan 21 13:21:56 1998
+++ ssh-1.2.22/configure	Wed Jan 21 14:01:22 1998
@@ -2527,6 +2527,13 @@
 #define SIZEOF_SHORT $ac_cv_sizeof_short
 EOF
 
+if test -f /usr/include/security/pam_appl.h; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_PAM 1
+EOF
+
+  LIBS="$LIBS -lpam -ldl"
+fi
 
 
 if test -z "$no_termios"; then
--- ssh-1.2.22/configure.in.pam	Tue Jan 20 13:24:14 1998
+++ ssh-1.2.22/configure.in	Wed Jan 21 13:22:05 1998
@@ -27,6 +27,9 @@
 # 	Fixed AC_MSG_RESULT messages when disabling idea in commercial
 # 	version.
 #
+# Revision 1.46a 1997/06/06 18:40:00  jonchen
+#	Added support for PAM
+#
 # Revision 1.46  1997/04/22 23:59:59  kivinen
 # 	Fixed SIGINFO check.
 # 	Added check that getpseudotty function exists before using.
@@ -679,6 +682,11 @@
 AC_CHECK_SIZEOF(long,4)
 AC_CHECK_SIZEOF(int,4)
 AC_CHECK_SIZEOF(short,2)
+
+if test -f /usr/include/security/pam_appl.h; then
+  AC_DEFINE(HAVE_PAM)
+  LIBS="$LIBS -lpam -ldl"
+fi
 
 if test -z "$no_termios"; then
   AC_CHECK_HEADERS(termios.h)
--- ssh-1.2.22/sshd.c.pam	Tue Jan 20 13:24:10 1998
+++ ssh-1.2.22/sshd.c	Wed Jan 21 13:22:05 1998
@@ -43,6 +43,9 @@
  * 	feature. Added {Allow,Deny}Users feature from Steve Kann
  * 	<stevek@SteveK.COM>.
  *
+ * Revision 1.42a 1997/06/06 18:40:00  jonchen
+ *	Added support for PAM
+ *
  * Revision 1.42  1997/04/23 00:05:35  kivinen
  * 	Added ifdefs around password expiration and inactivity checks,
  * 	because some systems dont have sp_expire and sp_inact fields.
@@ -460,6 +463,14 @@
 char *ticket = "none\0";
 #endif /* KERBEROS */
 
+#ifdef HAVE_PAM
+#include <security/pam_appl.h>
+struct pam_handle_t *pamh=NULL;
+char *pampasswd=NULL;
+int retval;
+int origretval;
+#endif /* HAVE_PAM */
+
 /* Server configuration options. */
 ServerOptions options;
 
@@ -547,7 +558,56 @@
 void do_child(const char *command, struct passwd *pw, const char *term,
 	      const char *display, const char *auth_proto,
 	      const char *auth_data, const char *ttyname);
+#ifdef HAVE_PAM
+static int pamconv (int num_msg,
+                     const struct pam_message **msg,
+                     struct pam_response **resp,
+                     void *appdata_ptr) {
+  int count = 0, replies = 0;
+  struct pam_response *reply = NULL;
+  int size = sizeof(struct pam_response);
+
+  for (count = 0; count < num_msg; count++) {
+    switch (msg[count]->msg_style) {
+      case PAM_PROMPT_ECHO_ON:
+      case PAM_PROMPT_ECHO_OFF:
+        if (reply) 
+          realloc(reply, size); 
+        else 
+          reply = malloc(size); 
+        if (!reply) return PAM_CONV_ERR; 
+        size += sizeof(struct pam_response);
+        reply[replies].resp_retcode = PAM_SUCCESS;
+        reply[replies++].resp = xstrdup (pampasswd);
+          /* PAM frees resp */
+        break;
+      case PAM_TEXT_INFO:
+        /* ignore it... */
+        break;
+      case PAM_ERROR_MSG:
+      default:
+        /* Must be an error of some sort... */
+        free (reply);
+        return PAM_CONV_ERR;
+    }
+  }
+  if (reply) *resp = reply;
+  return PAM_SUCCESS;
+}
+
+static struct pam_conv conv = {
+    pamconv,
+    NULL
+};
+
+void pam_cleanup_proc (void *context) {
+  if (retval == PAM_SUCCESS) 
+    retval = pam_close_session ((pam_handle_t *)pamh, 0);
+  if (pam_end ((pam_handle_t *)pamh, retval) != PAM_SUCCESS)
+    log_msg ("Cannot release PAM authentication.");
+}
 
+#endif /* HAVE_PAM */
 
 /* Signal handler for SIGHUP.  Sshd execs itself when it receives SIGHUP;
    the effect is to reread the configuration file (and to regenerate
@@ -1254,6 +1314,13 @@
   
   /* The connection has been terminated. */
   log_msg("Closing connection to %.100s", get_remote_ipaddr());
+#ifdef HAVE_PAM
+  if (retval == PAM_SUCCESS)
+    retval = pam_close_session ((pam_handle_t *)pamh, 0);
+  if (pam_end ((pam_handle_t *)pamh, retval) != PAM_SUCCESS)
+    log_msg ("Cannot release PAM authentication.");
+  fatal_remove_cleanup (&pam_cleanup_proc, NULL);
+#endif /* HAVE_PAM */
   packet_close();
   exit(0);
 }
@@ -1810,7 +1877,13 @@
      with any characters that are commonly used to start NIS entries. */
   pw = getpwnam(user);
   if (!pw || user[0] == '-' || user[0] == '+' || user[0] == '@' ||
-      !login_permitted(user, pw))
+      !login_permitted(user, pw)
+#ifdef HAVE_PAM
+      || ((retval=pam_start("ssh", pw->pw_name, &conv, (pam_handle_t **)&pamh)), 
+	  (fatal_add_cleanup (&pam_cleanup_proc, NULL)), 
+          (origretval = retval), (retval != PAM_SUCCESS))
+#endif /* HAVE_PAM */
+      )
     do_authentication_fail_loop();
   
   /* Take a copy of the returned structure. */
@@ -1841,6 +1914,7 @@
     packet_disconnect("Cannot change user when server not running as root.");
 
   debug("Attempting authentication for %.100s.", user);
+
 
 #if defined (KERBEROS) && defined (KRB5)
   if (!options.kerberos_authentication && options.password_authentication &&
