1 From 71e2185a3a2301f08c845a9cb884280dcb0d2cff Mon Sep 17 00:00:00 2001
   2 From: oracle <solaris@oracle.com>
   3 Date: Mon, 3 Aug 2015 14:36:13 -0700
   4 Subject: [PATCH 09/30] PAM conversation fix
   5 
   6 #
   7 # This patch contains an important bug fix for the PAM password userauth
   8 # conversation function. This bug fix was contributed back to the upstream in
   9 # 2009, but it was not accepted by the upstream.  For more information, see
  10 # https://bugzilla.mindrot.org/show_bug.cgi?id=1681.
  11 #
  12 ---
  13  auth-pam.c | 36 ++++++++++++++++++++++++++++++++++++
  14  1 file changed, 36 insertions(+)
  15 
  16 diff --git a/auth-pam.c b/auth-pam.c
  17 index d94c828..b941991 100644
  18 --- a/auth-pam.c
  19 +++ b/auth-pam.c
  20 @@ -1111,11 +1111,13 @@ free_pam_environment(char **env)
  21         free(env);
  22  }
  23  
  24 +#ifndef PAM_BUGFIX
  25  /*
  26   * "Blind" conversation function for password authentication.  Assumes that
  27   * echo-off prompts are for the password and stores messages for later
  28   * display.
  29   */
  30 +#endif
  31  static int
  32  sshpam_passwd_conv(int n, sshpam_const struct pam_message **msg,
  33      struct pam_response **resp, void *data)
  34 @@ -1137,12 +1139,24 @@ sshpam_passwd_conv(int n, sshpam_const struct pam_message **msg,
  35         for (i = 0; i < n; ++i) {
  36                 switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
  37                 case PAM_PROMPT_ECHO_OFF:
  38 +#ifdef PAM_BUGFIX
  39 +                       /*
  40 +                        * PAM conversation function for the password userauth
  41 +                       * method (non-interactive) really cannot do any 
  42 +                       * prompting.  We set the PAM_AUTHTOK item in 
  43 +                        * sshpam_auth_passwd()to avoid conversation. If some
  44 +                       * modules still try to converse, then the password
  45 +                       * userauth will fail.
  46 +                       */
  47 +                       goto fail;
  48 +#else
  49                         if (sshpam_password == NULL)
  50                                 goto fail;
  51                         if ((reply[i].resp = strdup(sshpam_password)) == NULL)
  52                                 goto fail;
  53                         reply[i].resp_retcode = PAM_SUCCESS;
  54                         break;
  55 +#endif
  56                 case PAM_ERROR_MSG:
  57                 case PAM_TEXT_INFO:
  58                         len = strlen(PAM_MSG_MEMBER(msg, i, msg));
  59 @@ -1178,6 +1192,9 @@ static struct pam_conv passwd_conv = { sshpam_passwd_conv, NULL };
  60  int
  61  sshpam_auth_passwd(Authctxt *authctxt, const char *password)
  62  {
  63 +#ifdef PAM_BUGFIX
  64 +        int set_item_rtn;
  65 +#endif
  66         int flags = (options.permit_empty_passwd == 0 ?
  67             PAM_DISALLOW_NULL_AUTHTOK : 0);
  68  
  69 @@ -1197,6 +1214,15 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password)
  70             options.permit_root_login != PERMIT_YES))
  71                 sshpam_password = badpw;
  72  
  73 +#ifdef PAM_BUGFIX
  74 +       sshpam_err = pam_set_item(sshpam_handle, PAM_AUTHTOK, password);
  75 +       if (sshpam_err != PAM_SUCCESS) {
  76 +               debug("PAM: %s: failed to set PAM_AUTHTOK: %s", __func__,
  77 +                   pam_strerror(sshpam_handle, sshpam_err));
  78 +               return 0;
  79 +       }
  80 +#endif
  81 +
  82         sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
  83             (const void *)&passwd_conv);
  84         if (sshpam_err != PAM_SUCCESS)
  85 @@ -1205,6 +1231,16 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password)
  86  
  87         sshpam_err = pam_authenticate(sshpam_handle, flags);
  88         sshpam_password = NULL;
  89 +
  90 +#ifdef PAM_BUGFIX
  91 +        set_item_rtn = pam_set_item(sshpam_handle, PAM_AUTHTOK, NULL);
  92 +       if (set_item_rtn != PAM_SUCCESS) {
  93 +               debug("PAM: %s: failed to set PAM_AUTHTOK: %s", __func__,
  94 +                   pam_strerror(sshpam_handle, set_item_rtn));
  95 +               return 0;
  96 +       }
  97 +#endif
  98 +
  99         if (sshpam_err == PAM_SUCCESS && authctxt->valid) {
 100                 debug("PAM: password authentication accepted for %.100s",
 101                     authctxt->user);
 102 -- 
 103 2.3.2 (Apple Git-55)
 104