On Monday, 7 October 2024 at 08:23:08 UTC, Alexander Zhirov wrote:

```
module login.auth;

import libpam;

enum {
    AUTH_SUCCESS = 0,
    AUTH_ERR_USER = 1,
    AUTH_ERR_PASS = 2,
    AUTH_ERR_NPASS = 3,
    AUTH_ERR_START = 4,
    AUTH_ERR_AUTH = 5,
    AUTH_ERR_ACCT = 6,
    AUTH_ERR_CHTOK = 7,
    AUTH_ERR_END = 8
}

class Auth {
private:
    struct PAMdata {
        string password;
        string newPassword;
    }

    extern(C) {
int conversation_func(int num_msg, const pam_message **msg, pam_response **resp, void *appdata_ptr) {
            PAMdata *data = cast(PAMdata*)appdata_ptr;

pam_response *responses = cast(pam_response *)calloc(num_msg, pam_response.sizeof);

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

            for (int count = 0; count < num_msg; ++count) {
                responses[count].resp_retcode = 0;
                switch (msg[count].msg_style) {
                    case PAM_PROMPT_ECHO_ON:
                    case PAM_PROMPT_ECHO_OFF:
                        switch (msg[count].msg.to!string) {
                            case "New password: ":
                            case "Retype new password: ":
responses[count].resp = strdup(data.newPassword.toStringz);
                                break;
                            case "Password: ":
                            case "Current password: ":
responses[count].resp = strdup(data.password.toStringz);
                                break;
                            default:
                                responses[count].resp = null;
                                break;
                        }
                        break;
                    default:
                        responses[count].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;
        int retval = 0;

        PAMdata data = { password };
        void *appdata_ptr = &data;

pam_conv conv = { cast(conversation*)&this.conversation_func, appdata_ptr };

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;
    }
}

```

Reply via email to