[Bug 118] New: Implement TIS (protocol 1) via PAM

bugzilla-daemon at mindrot.org bugzilla-daemon at mindrot.org
Fri Feb 15 21:44:21 EST 2002


http://bugzilla.mindrot.org/show_bug.cgi?id=118

           Summary: Implement TIS (protocol 1) via PAM
           Product: Portable OpenSSH
           Version: -current
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P3
         Component: sshd
        AssignedTo: openssh-unix-dev at mindrot.org
        ReportedBy: fcusack at fcusack.com


Currently, TIS is handled "natively" by sshd and only supports
S/Key.  With this patch, TIS is done via PAM, which gives a lot
more flexibility on choice of "backend", eg you could do x9.9 tokens
with protocol 1.

It's a little bit less flexible if you have a server you want to
be capable of doing either C/R or password.  You can't do both
via PAM in protocol 1.  But the patch doesn't *break* doing both,
you need merely turn off the TISviaPAM option and you are limited
to the builtin S/Key for C/R.

I hope this cut/pastes ok.

This also fixes a bug in the current TIS handling, it turns echo on
when doing TIS.

diff -uNr openssh-3.0.2p1.orig/auth-pam.c openssh-3.0.2p1/auth-pam.c
--- openssh-3.0.2p1.orig/auth-pam.c	Fri Nov  9 12:22:17 2001
+++ openssh-3.0.2p1/auth-pam.c	Fri Feb 15 02:17:19 2002
@@ -26,6 +26,8 @@
 
 #ifdef USE_PAM
 #include "ssh.h"
+#include "ssh1.h"
+#include "packet.h"
 #include "xmalloc.h"
 #include "log.h"
 #include "auth-pam.h"
@@ -54,6 +56,8 @@
 
 /* states for do_pam_conversation() */
 enum { INITIAL_LOGIN, OTHER } pamstate = INITIAL_LOGIN;
+/* which type of prompts we should handle, set in auth_pam_password */
+static int pamprompt;
 /* remember whether pam_acct_mgmt() returned PAM_NEWAUTHTOK_REQD */
 static int password_change_required = 0;
 /* remember whether the last pam_authenticate() succeeded or not */
@@ -98,6 +102,10 @@
 	int count;
 	char buf[1024];
 
+	u_int dlen;
+	int plen, type;
+	char *response;
+
 	/* PAM will free this later */
 	reply = malloc(num_msg * sizeof(*reply));
 	if (reply == NULL)
@@ -111,10 +119,40 @@
 			 */
 			switch(PAM_MSG_MEMBER(msg, count, msg_style)) {
 			case PAM_PROMPT_ECHO_ON:
-				free(reply);
-				return PAM_CONV_ERR;
+				if (pamprompt != PAM_PROMPT_ECHO_ON ||
+				    (*msg)[count].msg == NULL) {
+					free(reply);
+					return PAM_CONV_ERR;
+				}
+
+				/* handle challenge/response (ssh1 TIS) */
+				/* Send the challenge */
+				strlcpy(buf, PAM_MSG_MEMBER(msg, count, msg),
+					sizeof(buf));
+				debug("sending challenge '%s'", buf);
+				packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
+				packet_put_cstring(buf);
+				packet_send();
+				packet_write_wait();
+
+				/* Give the response to the PAM module */
+				if ((type = packet_read(&plen)) !=
+				    SSH_CMSG_AUTH_TIS_RESPONSE) {
+					free(reply);
+					return PAM_CONV_ERR;
+				}
+				debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE");
+				response = packet_get_string(&dlen);
+				debug("got response '%s'", response);
+				packet_integrity_check(plen, 4 + dlen, type);
+				reply[count].resp = xstrdup(response);
+				reply[count].resp_retcode = PAM_SUCCESS;
+				xfree(response);
+				break;
+
 			case PAM_PROMPT_ECHO_OFF:
-				if (__pampasswd == NULL) {
+				if (__pampasswd == NULL ||
+				    pamprompt != PAM_PROMPT_ECHO_OFF) {
 					free(reply);
 					return PAM_CONV_ERR;
 				}
@@ -198,8 +236,8 @@
 	}
 }
 
-/* Attempt password authentation using PAM */
-int auth_pam_password(struct passwd *pw, const char *password)
+/* Attempt password authentication using PAM */
+int auth_pam_password(struct passwd *pw, const char *password, int prompt_type)
{
 	extern ServerOptions options;
 	int pam_retval;
@@ -211,12 +249,14 @@
 		return 0;
 	if (pw->pw_uid == 0 && options.permit_root_login == PERMIT_NO_PASSWD)
 		return 0;
-	if (*password == '\0' && options.permit_empty_passwd == 0)
+ 	if (*password == '\0' && options.permit_empty_passwd == 0 &&
+ 	    prompt_type == PAM_PROMPT_ECHO_OFF)
 		return 0;
 
 	__pampasswd = password;
 
 	pamstate = INITIAL_LOGIN;
+ 	pamprompt = prompt_type;
 	pam_retval = do_pam_authenticate(
 	    options.permit_empty_passwd == 0 ? PAM_DISALLOW_NULL_AUTHTOK : 0);
 	if (pam_retval == PAM_SUCCESS) {
diff -uNr openssh-3.0.2p1.orig/auth-pam.h openssh-3.0.2p1/auth-pam.h
--- openssh-3.0.2p1.orig/auth-pam.h	Mon Mar 26 22:12:24 2001
+++ openssh-3.0.2p1/auth-pam.h	Fri Feb 15 02:15:02 2002
@@ -7,7 +7,7 @@
 
 void start_pam(const char *user);
 void finish_pam(void);
-int auth_pam_password(struct passwd *pw, const char *password);
+int auth_pam_password(struct passwd *pw, const char *password, int
prompt_type);
 char **fetch_pam_environment(void);
 int do_pam_authenticate(int flags);
 int do_pam_account(char *username, char *remote_user);
diff -uNr openssh-3.0.2p1.orig/auth1.c openssh-3.0.2p1/auth1.c
--- openssh-3.0.2p1.orig/auth1.c	Tue Nov 13 04:46:19 2001
+++ openssh-3.0.2p1/auth1.c	Fri Feb 15 02:15:02 2002
@@ -85,7 +85,7 @@
 	    (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
 #endif
 #ifdef USE_PAM
-	    auth_pam_password(pw, "")) {
+	    auth_pam_password(pw, "", PAM_PROMPT_ECHO_OFF)) {
 #elif defined(HAVE_OSF_SIA)
 	    0) {
 #else
@@ -252,7 +252,8 @@
 
 #ifdef USE_PAM
 			/* Do PAM auth with password */
-			authenticated = auth_pam_password(pw, password);
+			authenticated = auth_pam_password(pw, password,
+							  PAM_PROMPT_ECHO_OFF);
 #elif defined(HAVE_OSF_SIA)
 			/* Do SIA auth with password */
 			authenticated = auth_sia_password(authctxt->user, 
@@ -269,6 +270,15 @@
 		case SSH_CMSG_AUTH_TIS:
 			debug("rcvd SSH_CMSG_AUTH_TIS");
 			if (options.challenge_response_authentication == 1) {
+#ifdef USE_PAM
+			    if (options.tis_via_pam == 1) {
+				authenticated = auth_pam_password(pw, "",
+							  PAM_PROMPT_ECHO_ON);
+				break;
+			    } else {
+#else
+			    {
+#endif /* USE_PAM */
 				char *challenge = get_challenge(authctxt);
 				if (challenge != NULL) {
 					debug("sending challenge '%s'", challenge);
@@ -279,6 +289,7 @@
 					packet_write_wait();
 					continue;
 				}
+			    }
 			}
 			break;
 		case SSH_CMSG_AUTH_TIS_RESPONSE:
diff -uNr openssh-3.0.2p1.orig/auth2.c openssh-3.0.2p1/auth2.c
--- openssh-3.0.2p1.orig/auth2.c	Tue Nov 13 04:46:19 2001
+++ openssh-3.0.2p1/auth2.c	Fri Feb 15 02:20:36 2002
@@ -345,7 +345,7 @@
 		return(0);
 #endif
 #ifdef USE_PAM
-	return auth_pam_password(authctxt->pw, "");
+	return auth_pam_password(authctxt->pw, "", PAM_PROMPT_ECHO_OFF);
 #elif defined(HAVE_OSF_SIA)
 	return 0;
 #else /* !HAVE_OSF_SIA && !USE_PAM */
@@ -370,7 +370,7 @@
 		check_nt_auth(1, authctxt->pw->pw_uid) &&
 #endif
 #ifdef USE_PAM
-	    auth_pam_password(authctxt->pw, password) == 1)
+	    auth_pam_password(authctxt->pw, password, PAM_PROMPT_ECHO_OFF) == 1) #elif
defined(HAVE_OSF_SIA)
 	    auth_sia_password(authctxt->user, password) == 1)
 #else /* !USE_PAM && !HAVE_OSF_SIA */
diff -uNr openssh-3.0.2p1.orig/servconf.c openssh-3.0.2p1/servconf.c
--- openssh-3.0.2p1.orig/servconf.c	Tue Nov 13 05:03:15 2001
+++ openssh-3.0.2p1/servconf.c	Fri Feb 15 02:15:05 2002
@@ -88,6 +88,7 @@
 	options->password_authentication = -1;
 	options->kbd_interactive_authentication = -1;
 	options->challenge_response_authentication = -1;
+	options->tis_via_pam = -1;
 	options->permit_empty_passwd = -1;
 	options->use_login = -1;
 	options->allow_tcp_forwarding = -1;
@@ -249,7 +250,7 @@
 #ifdef AFS
 	sAFSTokenPassing,
 #endif
-	sChallengeResponseAuthentication,
+	sChallengeResponseAuthentication, sTISviaPAM,
 	sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
 	sX11Forwarding, sX11DisplayOffset,
@@ -304,6 +305,7 @@
 	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
 	{ "challengeresponseauthentication", sChallengeResponseAuthentication }, 	{
"skeyauthentication", sChallengeResponseAuthentication }, /* alias */
+	{ "tisviapam", sTISviaPAM },
 	{ "checkmail", sDeprecated },
 	{ "listenaddress", sListenAddress },
 	{ "printmotd", sPrintMotd },
@@ -648,6 +650,10 @@
 
 		case sChallengeResponseAuthentication:
 			intptr = &options->challenge_response_authentication;
+			goto parse_flag;
+
+		case sTISviaPAM:
+			intptr = &options->tis_via_pam;
 			goto parse_flag;
 
 		case sPrintMotd:
diff -uNr openssh-3.0.2p1.orig/servconf.h openssh-3.0.2p1/servconf.h
--- openssh-3.0.2p1.orig/servconf.h	Wed Sep 12 09:40:06 2001
+++ openssh-3.0.2p1/servconf.h	Fri Feb 15 02:15:05 2002
@@ -94,6 +94,7 @@
 						 * authentication. */
 	int     kbd_interactive_authentication;	/* If true, permit */
 	int     challenge_response_authentication;
+	int	tis_via_pam;			/* Use PAM for TIS? */
 	int     permit_empty_passwd;	/* If false, do not permit empty
 					 * passwords. */
 	int     use_login;	/* If true, login(1) is used */
diff -uNr openssh-3.0.2p1.orig/sshconnect1.c openssh-3.0.2p1/sshconnect1.c
--- openssh-3.0.2p1.orig/sshconnect1.c	Tue Oct  9 22:03:12 2001
+++ openssh-3.0.2p1/sshconnect1.c	Fri Feb 15 02:15:05 2002
@@ -849,7 +849,7 @@
 		if (options.cipher == SSH_CIPHER_NONE)
 			log("WARNING: Encryption is disabled! "
 			    "Reponse will be transmitted in clear text.");
-		response = read_passphrase(prompt, 0);
+		response = read_passphrase(prompt, RP_ECHO);
 		if (strcmp(response, "") == 0) {
 			xfree(response);
 			break;
diff -uNr openssh-3.0.2p1.orig/sshd.8 openssh-3.0.2p1/sshd.8
--- openssh-3.0.2p1.orig/sshd.8	Sat Dec  1 15:37:08 2001
+++ openssh-3.0.2p1/sshd.8	Fri Feb 15 02:15:05 2002
@@ -379,6 +379,12 @@
 are supported.
 The default is
 .Dq yes .
+.It Cm TISviaPAM
+Specifies whether protocol version 1 challenge response authentication (TIS)
+should be handled via PAM.  This is incompatible with with password
+authentication.
+The default is
+.Dq no .
 .It Cm Ciphers
 Specifies the ciphers allowed for protocol version 2.
 Multiple ciphers must be comma-separated.
diff -uNr openssh-3.0.2p1.orig/sshd_config openssh-3.0.2p1/sshd_config
--- openssh-3.0.2p1.orig/sshd_config	Thu Sep 20 16:15:44 2001
+++ openssh-3.0.2p1/sshd_config	Fri Feb 15 02:15:05 2002
@@ -52,6 +52,9 @@
 
 # Uncomment to disable s/key passwords 
 #ChallengeResponseAuthentication no
+# Do ssh1 TIS authentication (challenge/response) via PAM?
+# ChallengeResponseAuthentication must be set for this to take effect.
+#TISviaPAM no
 
 # Uncomment to enable PAM keyboard-interactive authentication 
 # Warning: enabling this may bypass the setting of 'PasswordAuthentication'



------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.



More information about the openssh-unix-dev mailing list