Sending immediate PAM auth failure messages via kbd-int

Dan Kaminsky dan at doxpara.com
Wed Jun 2 03:50:48 EST 2004


Most versions of SSH1 would leak whether an account existed or not 
through high debug levels.  I absolutely respect the need to have 
forced-ejection messages, but we should try to avoid this mechanism for 
information leakage.  After all -- logins are encrypted, and therefore 
can't be readily noticed by an IDS.

--Dan

Darren Tucker wrote:

> Hi.
>     One thing that people seem to want to do with PAM is to deny a 
> login immediately without interacting but return a message to the 
> user.  (Some platforms implement, eg, /etc/nologin via PAM this way.) 
> Currently, sshd will just deny the login and the user will not be told 
> why.
>
>     Attached it a patch that return a keyboard-interactive packet with 
> the message in the "instruction" block but with zero prompts (this is 
> permitted by kbdinteract-06 section 3.4).
>
>     The next question is whether or not it's a good idea to send extra 
> info to a denied login.  As a rule, sshd doesn't, but this condition 
> only occurs if the admin explicitly configures PAM to behave this 
> way.  This won't happen with the recently re-added PAM-via-password 
> authentication, only keyboard-interactive.
>
>     This has an interesting side-effect the OpenSSH client: it 
> immediately retries (since it's just a failed kbdint auth attempt) so 
> the message is repeated 3 times.  This can be fixed in the client (I 
> have a 4-line patch that disables kbdint if it gets a messages with 
> zero prompts) but I'm not sure it's the right thing to do.  The server 
> might have multiple keyboard-interactive "devices" and the next one 
> might behave differently.
>
>     Similarly, making sshd disable keyboard-interactive in this case 
> doesn't seem right either, since a client might to choose to do 
> something differently (like change username) in response to the message.
>
>     Anyway, feel free discuss the patch, try it or pick it apart :-)
>
>         -Daz.
>
> $ ssh -o preferredauthentications=keyboard-interactive localhost
> No user logins right now.
>
> No user logins right now.
>
> No user logins right now.
>
>------------------------------------------------------------------------
>
>Index: auth-pam.c
>===================================================================
>RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/auth-pam.c,v
>retrieving revision 1.105
>diff -u -p -r1.105 auth-pam.c
>--- auth-pam.c	1 Jun 2004 01:28:20 -0000	1.105
>+++ auth-pam.c	1 Jun 2004 14:10:42 -0000
>@@ -93,6 +93,7 @@ struct pam_ctxt {
> 	int		 pam_psock;
> 	int		 pam_csock;
> 	int		 pam_done;
>+	int		 pam_pending_resp;
> };
> 
> static void sshpam_free_ctx(void *);
>@@ -590,7 +591,7 @@ sshpam_query(void *ctx, char **name, cha
> 		switch (type) {
> 		case PAM_PROMPT_ECHO_ON:
> 		case PAM_PROMPT_ECHO_OFF:
>-			*num = 1;
>+			ctxt->pam_pending_resp = *num = 1;
> 			len = plen + strlen(msg) + 1;
> 			**prompts = xrealloc(**prompts, len);
> 			plen += snprintf(**prompts + plen, len, "%s", msg);
>@@ -608,16 +609,27 @@ sshpam_query(void *ctx, char **name, cha
> 		case PAM_SUCCESS:
> 		case PAM_AUTH_ERR:
> 			if (**prompts != NULL) {
>-				/* drain any accumulated messages */
> 				debug("PAM: %s", **prompts);
>-				buffer_append(&loginmsg, **prompts,
>-				    strlen(**prompts));
>-				xfree(**prompts);
>-				**prompts = NULL;
>+				if (compat20 && type == PAM_AUTH_ERR) {
>+					/* tell the user about it now */
>+					ctxt->pam_pending_resp = *num = 0;
>+					*info = xrealloc(*info, len);
>+					strlcpy(*info, **prompts, len);
>+					xfree(**prompts);
>+					**prompts = NULL;
>+					xfree(msg);
>+					return (0);
>+				} else {	
>+					/* save for display later */
>+					buffer_append(&loginmsg, **prompts,
>+					    strlen(**prompts));
>+					xfree(**prompts);
>+					**prompts = NULL;
>+				}
> 			}
> 			if (type == PAM_SUCCESS) {
> 				import_environments(&buffer);
>-				*num = 0;
>+				ctxt->pam_pending_resp = *num = 0;
> 				**echo_on = 0;
> 				ctxt->pam_done = 1;
> 				xfree(msg);
>@@ -629,7 +641,7 @@ sshpam_query(void *ctx, char **name, cha
> 			    get_remote_name_or_ip(utmp_len, options.use_dns));
> 			/* FALLTHROUGH */
> 		default:
>-			*num = 0;
>+			ctxt->pam_pending_resp = *num = 0;
> 			**echo_on = 0;
> 			xfree(msg);
> 			ctxt->pam_done = -1;
>@@ -656,10 +668,12 @@ sshpam_respond(void *ctx, u_int num, cha
> 	default:
> 		return (-1);
> 	}
>-	if (num != 1) {
>-		error("PAM: expected one response, got %u", num);
>+	if (num != ctxt->pam_pending_resp) {
>+		error("PAM: expected %d responses, got %u",
>+		    ctxt->pam_pending_resp, num);
> 		return (-1);
>-	}
>+	} else if (num == 0)
>+		return(-1);
> 	buffer_init(&buffer);
> 	buffer_put_cstring(&buffer, *resp);
> 	if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer) == -1) {
>  
>
>------------------------------------------------------------------------
>
>_______________________________________________
>openssh-unix-dev mailing list
>openssh-unix-dev at mindrot.org
>http://www.mindrot.org/mailman/listinfo/openssh-unix-dev
>  
>




More information about the openssh-unix-dev mailing list