Darren Tucker
2004-Jun-01 14:18 UTC
Sending immediate PAM auth failure messages via kbd-int
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. -- Darren Tucker (dtucker at zip.com.au) GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69 Good judgement comes with experience. Unfortunately, the experience usually comes from bad judgement. -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: openssh-pam-zeromsgs.patch Url: http://lists.mindrot.org/pipermail/openssh-unix-dev/attachments/20040602/2c7e903b/attachment.ksh
Dan Kaminsky
2004-Jun-01 17:50 UTC
Sending immediate PAM auth failure messages via kbd-int
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 > >