components/openssh/patches/015-pam_conversation_fix.patch
author Yiteng Zhang <yiteng.zhang@oracle.com>
Tue, 04 Oct 2016 11:04:14 -0700
branchs11u3-sru
changeset 7033 a49f9f0272f2
parent 3946 b1e0e68de63b
child 7320 edeb951aa980
permissions -rw-r--r--
22599190 problem in LIBRARY/CURL

#
# This patch contains an important bug fix for the PAM password userauth
# conversation function. This bug fix was contributed back to the upstream in 
# 2009, but it was not accepted by the upstream.  For more information, see
# https://bugzilla.mindrot.org/show_bug.cgi?id=1681.
#
--- orig/auth-pam.c	Mon Oct 27 14:40:01 2014
+++ new/auth-pam.c	Tue Oct 28 12:40:59 2014
@@ -1111,11 +1111,13 @@
 	free(env);
 }
 
+#ifndef PAM_BUGFIX
 /*
  * "Blind" conversation function for password authentication.  Assumes that
  * echo-off prompts are for the password and stores messages for later
  * display.
  */
+#endif
 static int
 sshpam_passwd_conv(int n, sshpam_const struct pam_message **msg,
     struct pam_response **resp, void *data)
@@ -1137,6 +1139,17 @@
 	for (i = 0; i < n; ++i) {
 		switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
 		case PAM_PROMPT_ECHO_OFF:
+#ifdef PAM_BUGFIX
+                       /*
+                        * PAM conversation function for the password userauth
+			* method (non-interactive) really cannot do any 
+			* prompting.  We set the PAM_AUTHTOK item in 
+                        * sshpam_auth_passwd()to avoid conversation. If some
+			* modules still try to converse, then the password
+			* userauth will fail.
+			*/
+			goto fail;
+#else
 			if (sshpam_password == NULL)
 				goto fail;
 			if ((reply[i].resp = strdup(sshpam_password)) == NULL)
@@ -1143,6 +1156,7 @@
 				goto fail;
 			reply[i].resp_retcode = PAM_SUCCESS;
 			break;
+#endif
 		case PAM_ERROR_MSG:
 		case PAM_TEXT_INFO:
 			len = strlen(PAM_MSG_MEMBER(msg, i, msg));
@@ -1178,6 +1192,9 @@
 int
 sshpam_auth_passwd(Authctxt *authctxt, const char *password)
 {
+#ifdef PAM_BUGFIX
+        int set_item_rtn;
+#endif
 	int flags = (options.permit_empty_passwd == 0 ?
 	    PAM_DISALLOW_NULL_AUTHTOK : 0);
 
@@ -1197,6 +1214,15 @@
 	    options.permit_root_login != PERMIT_YES))
 		sshpam_password = badpw;
 
+#ifdef PAM_BUGFIX
+  	sshpam_err = pam_set_item(sshpam_handle, PAM_AUTHTOK, password);
+	if (sshpam_err != PAM_SUCCESS) {
+		debug("PAM: %s: failed to set PAM_AUTHTOK: %s", __func__,
+		    pam_strerror(sshpam_handle, sshpam_err));
+		return 0;
+	}
+#endif
+
 	sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
 	    (const void *)&passwd_conv);
 	if (sshpam_err != PAM_SUCCESS)
@@ -1205,6 +1231,16 @@
 
 	sshpam_err = pam_authenticate(sshpam_handle, flags);
 	sshpam_password = NULL;
+
+#ifdef PAM_BUGFIX
+        set_item_rtn = pam_set_item(sshpam_handle, PAM_AUTHTOK, NULL);
+	if (set_item_rtn != PAM_SUCCESS) {
+		debug("PAM: %s: failed to set PAM_AUTHTOK: %s", __func__,
+		    pam_strerror(sshpam_handle, set_item_rtn));
+		return 0;
+	}
+#endif
+
 	if (sshpam_err == PAM_SUCCESS && authctxt->valid) {
 		debug("PAM: password authentication accepted for %.100s",
 		    authctxt->user);