--- 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 &&