From: Marco Trevisan (TreviƱo) Date: Tue, 17 Oct 2023 02:27:32 +0000 (+0200) Subject: auth-pam: Immediately report interactive instructions to clients X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b9a6dd4d66ee14577494d550b396d0452bf05e1e;p=thirdparty%2Fopenssh-portable.git auth-pam: Immediately report interactive instructions to clients SSH keyboard-interactive authentication method supports instructions but sshd didn't show them until an user prompt was requested. This is quite inconvenient for various PAM modules that need to notify an user without requiring for their explicit input. So, properly implement RFC4256 making instructions to be shown to users when they are requested from PAM. Closes: https://bugzilla.mindrot.org/show_bug.cgi?id=2876 --- diff --git a/auth-pam.c b/auth-pam.c index 0b247421b..cb9e0bc31 100644 --- a/auth-pam.c +++ b/auth-pam.c @@ -136,6 +136,7 @@ typedef int SshPamDone; #define SshPamError -1 #define SshPamNone 0 #define SshPamAuthenticated 1 +#define SshPamAgain 2 struct pam_ctxt { sp_pthread_t pam_thread; @@ -868,6 +869,8 @@ sshpam_query(void *ctx, char **name, char **info, **prompts = NULL; plen = 0; *echo_on = xmalloc(sizeof(u_int)); + ctxt->pam_done = SshPamNone; + while (ssh_msg_recv(ctxt->pam_psock, buffer) == 0) { if (++nmesg > PAM_MAX_NUM_MSG) fatal_f("too many query messages"); @@ -888,15 +891,13 @@ sshpam_query(void *ctx, char **name, char **info, return (0); case PAM_ERROR_MSG: case PAM_TEXT_INFO: - /* accumulate messages */ - len = plen + mlen + 2; - **prompts = xreallocarray(**prompts, 1, len); - strlcpy(**prompts + plen, msg, len - plen); - plen += mlen; - strlcat(**prompts + plen, "\n", len - plen); - plen++; - free(msg); - break; + *num = 0; + free(*info); + *info = msg; /* Steal the message */ + msg = NULL; + ctxt->pam_done = SshPamAgain; + sshbuf_free(buffer); + return (0); case PAM_ACCT_EXPIRED: case PAM_MAXTRIES: if (type == PAM_ACCT_EXPIRED) @@ -1000,6 +1001,8 @@ sshpam_respond(void *ctx, u_int num, char **resp) return (0); case SshPamNone: break; + case SshPamAgain: + return 1; /* KbdintResultAgain */ default: return (-1); }