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