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