Wrapper for PAM
Salih Dincer
salihdb at hotmail.com
Thu Oct 3 23:56:37 UTC 2024
On Thursday, 3 October 2024 at 22:54:53 UTC, Alexander Zhirov
wrote:
> I want to try to make access via D to PAM.
>
> ```d
> /// I added it here:
> import pam_wrapper;
> int main(string[] args)
> {
> if (args.length < 3)
> {
> writeln("Usage: ", args[0], "<username> <password>");
> return 1;
> }
> /// I added it here.
> string username = args[1];
> string password = args[2];
>
> int result = authenticate_user(username, password);
> if (result == 0) {
> writeln("Authentication succeeded!");
> } else {
> writefln("Authentication failed with code: %d", result);
> }
>
> return EXIT_SUCCESS;
> }
> ```
It is possible to implement PAM (Pluggable Authentication
Modules) support in the D programming language using the standard
library. The D standard library provides extern(C) support to
access C language APIs and a strong FFI (Foreign Function
Interface) support to adapt to C data structures. However, D
itself does not include a special module for PAM, so it is
necessary to work with C-based PAM libraries in the D language.
I think you should use 2 separate modules! This can make type
conversions and memory management safer. Here is the
pam_wrapper.d file:
```d
module pam_wrapper;
import pam; // You have this module.
import std.string, std.conv : to;
import core.stdc.string : strdup;
import core.stdc.stdlib : malloc, free;
public import std.stdio;
struct pam_data { string password; }
extern(C)
{
int conversation_func(int num_msg, const pam_message **msg,
pam_response **resp, void *appdata_ptr)
{
pam_data *data = cast(pam_data*)appdata_ptr;
*resp = cast(pam_response *)malloc(num_msg *
pam_response.sizeof);
if (resp == null) return PAM_BUF_ERR;
for (int i = 0; i < num_msg; i++)
{
switch (msg[i].msg_style)
{
case PAM_PROMPT_ECHO_ON:
goto case;
case PAM_PROMPT_ECHO_OFF:
resp[i].resp =
strdup(data.password.toStringz);
resp[i].resp_retcode = 0;
break;
default:
resp[i].resp = null;
resp[i].resp_retcode = 0;
break;
}
}
return PAM_SUCCESS;
}
}
int authenticate_user(string username, string password)
{
pam_handle_t *pamh = null;
int retval = 0;
pam_data data = { password };
void *appdata_ptr = &data;
pam_conv conv = { cast(conversation*)&conversation_func,
appdata_ptr };
retval = pam_start("login", username.toStringz, &conv, &pamh);
if (retval != PAM_SUCCESS)
{
pam_strerror(pamh, retval).to!string.writefln!"pam_start:
%s";
return 1;
}
retval = pam_authenticate(pamh, 0);
if (retval != PAM_SUCCESS)
{
pam_strerror(pamh,
retval).to!string.writefln!"Authentication failure: %s";
pam_end(pamh, retval);
return 2;
}
retval = pam_end(pamh, PAM_SUCCESS);
if (retval != PAM_SUCCESS)
{
pam_strerror(pamh, retval).to!string.writefln!"pam_end:
%s";
return 3;
}
return 0;
}
```
SDB at 79
More information about the Digitalmars-d-learn
mailing list