--- 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 <[email protected]>).
@@ -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.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
 *     <[email protected]>.
 *
+ * 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 &&