On Thursday, 10 October 2024 at 13:10:58 UTC, Salih Dincer wrote:
On Thursday, 10 October 2024 at 12:58:22 UTC, Salih Dincer wrote:
```d
class Auth
{
  private:
    struct PAMdata
    {
      string password;
      string newPassword;
    }

    extern(C)
    { // 1. Salih changed it:
      static int conversation_func(int num_msg,
                       const pam_message **msg,
                           pam_response **resp,
                             void *appdata_ptr)
      {
        auto data = cast(PAMdata*)appdata_ptr;
        auto responses = cast(pam_response*)
          calloc(num_msg, pam_response.sizeof);

        if (responses == null)
        {
          return PAM_BUF_ERR;
        }

        for (int i = 0; i < num_msg; ++i)
        {
          responses[i].resp_retcode = 0;
          switch (msg[i].msg_style)
          {
            case PAM_PROMPT_ECHO_ON: goto case;
            case PAM_PROMPT_ECHO_OFF:
              switch (msg[i].msg.to!string)
              {
                case "New password: ": goto case;
                case "Retype new password: ":
responses[i].resp = strdup(data.newPassword.toStringz);
                  break;
                case "Password: ": goto case;
                case "Current password: ":
responses[i].resp = strdup(data.password.toStringz);
                  break;
                default:
                  responses[i].resp = null;
                  break;
              }
              break;
            default:
              responses[i].resp = null;
              break;
          }
        }
        *resp = responses;
        return PAM_SUCCESS;
      }
    }

  public:
    int authenticate(string username, string password)
    {
      if (!username.length)
      {
        return AUTH_ERR_USER;
      }

      if (!password.length)
      {
        return AUTH_ERR_PASS;
      }

      pam_handle_t *pamh = null;
      PAMdata data = {
        password
      };

      void *appdata_ptr = &data;
      // 2. Salih changed it:
      pam_conv conv = {
        cast(conversation*)&conversation_func,
        appdata_ptr
      };
      // 3. Salih changed it:
auto retval = pam_start("login", username.toStringz, &conv, &pamh);
      if (retval != PAM_SUCCESS)
      {
        return AUTH_ERR_START;
      }

      retval = pam_authenticate(pamh, 0);
      if (retval != PAM_SUCCESS)
      {
        pam_end(pamh, retval);
        return AUTH_ERR_AUTH;
      }

      retval = pam_end(pamh, PAM_SUCCESS);
      if (retval != PAM_SUCCESS)
      {
        return AUTH_ERR_END;
      }
      return AUTH_SUCCESS;
    }
}
```

SDB@79

Thanks for the example. I'll try to test it.

Reply via email to