mirror of
https://github.com/falk-werner/webfused
synced 2026-03-02 04:09:19 +00:00
added pam authenticator
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "webfused/auth/factory.h"
|
||||
#include "webfused/auth/file_authenticator.h"
|
||||
#include "webfused/auth/pam_authenticator.h"
|
||||
#include "webfused/config/settings.h"
|
||||
#include "webfused/log/log.h"
|
||||
|
||||
@@ -16,6 +17,10 @@ wfd_authenticator_create(
|
||||
{
|
||||
result = wfd_file_authenticator_create(settings, authenticator);
|
||||
}
|
||||
else if (0 == strcmp("pam", provider))
|
||||
{
|
||||
result = wfd_pam_authenticator_create(settings, authenticator);
|
||||
}
|
||||
else
|
||||
{
|
||||
WFD_ERROR("failed to create authenticator: unknown type \"%s\"", provider);
|
||||
|
||||
@@ -61,7 +61,7 @@ wfd_file_authenticator_get_type(
|
||||
return "username";
|
||||
}
|
||||
|
||||
static struct wfd_authenticator_vtable
|
||||
static struct wfd_authenticator_vtable const
|
||||
wfd_file_authenticator_vtable =
|
||||
{
|
||||
.dispose = &wfd_file_authenticator_dispose,
|
||||
|
||||
174
src/webfused/auth/pam_authenticator.c
Normal file
174
src/webfused/auth/pam_authenticator.c
Normal file
@@ -0,0 +1,174 @@
|
||||
#include "webfused/auth/pam_authenticator.h"
|
||||
#include "webfused/auth/authenticator.h"
|
||||
#include "webfused/config/settings.h"
|
||||
#include "webfused/log/log.h"
|
||||
|
||||
#include "webfuse/adapter/credentials.h"
|
||||
|
||||
#include <security/pam_appl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct wfd_pam_authenticator
|
||||
{
|
||||
char * service_name;
|
||||
};
|
||||
|
||||
struct wfd_pam_credentials
|
||||
{
|
||||
char const * username;
|
||||
char const * password;
|
||||
};
|
||||
|
||||
static int
|
||||
wfd_pam_conversation(
|
||||
int count,
|
||||
struct pam_message const ** messages,
|
||||
struct pam_response * * ret_responses,
|
||||
void * user_data)
|
||||
{
|
||||
int result = PAM_SUCCESS;
|
||||
struct pam_response * responses = malloc(count * sizeof(struct pam_response));
|
||||
struct wfd_pam_credentials * creds = user_data;
|
||||
|
||||
for(int i = 0; (PAM_SUCCESS == result) && (i < count); i++)
|
||||
{
|
||||
struct pam_response * response = &responses[i];
|
||||
struct pam_message const * message = messages[i];
|
||||
|
||||
response->resp_retcode = 0;
|
||||
response->resp = NULL;
|
||||
|
||||
switch (message->msg_style)
|
||||
{
|
||||
case PAM_PROMPT_ECHO_ON:
|
||||
response->resp = strdup(creds->username);
|
||||
break;
|
||||
case PAM_PROMPT_ECHO_OFF:
|
||||
response->resp = strdup(creds->password);
|
||||
break;
|
||||
default:
|
||||
free(responses);
|
||||
result = PAM_CONV_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS == result)
|
||||
{
|
||||
*ret_responses = responses;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
wfd_pam_authenticator_dispose(
|
||||
void * data)
|
||||
{
|
||||
struct wfd_pam_authenticator * authenticator = data;
|
||||
|
||||
free(authenticator->service_name);
|
||||
free(authenticator);
|
||||
}
|
||||
|
||||
static bool
|
||||
wfd_pam_authenticator_authenticate(
|
||||
struct wf_credentials * credentials,
|
||||
void * user_data)
|
||||
{
|
||||
bool result = false;
|
||||
struct wfd_pam_authenticator * authenticator = user_data;
|
||||
|
||||
char const * username = wf_credentials_get(credentials, "username");
|
||||
char const * password = wf_credentials_get(credentials, "password");
|
||||
if ((NULL != username) && (NULL != password))
|
||||
{
|
||||
struct wfd_pam_credentials creds =
|
||||
{
|
||||
.username = username,
|
||||
.password = password
|
||||
};
|
||||
|
||||
struct pam_conv const conversation =
|
||||
{
|
||||
.conv = &wfd_pam_conversation,
|
||||
.appdata_ptr = &creds
|
||||
};
|
||||
|
||||
pam_handle_t * handle = NULL;
|
||||
bool cleanup_handle = false;
|
||||
result = true;
|
||||
{
|
||||
int rc = pam_start(authenticator->service_name, NULL,
|
||||
&conversation, &handle);
|
||||
result = (PAM_SUCCESS == rc);
|
||||
cleanup_handle = result;
|
||||
if (!result)
|
||||
{
|
||||
WFD_ERROR("failed to start pam conversation: %s", pam_strerror(handle, rc));
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
int rc = pam_authenticate(handle, PAM_DISALLOW_NULL_AUTHTOK);
|
||||
result = (PAM_SUCCESS == rc);
|
||||
if (!result)
|
||||
{
|
||||
WFD_INFO("failed to authenticate user \'%s\' (pam_authenticate): %s",
|
||||
username, pam_strerror(handle, rc));
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
int rc = pam_acct_mgmt(handle, PAM_DISALLOW_NULL_AUTHTOK);
|
||||
result = (PAM_SUCCESS == rc);
|
||||
if (!result)
|
||||
{
|
||||
WFD_INFO("failed to authenticate user \'%s\' (pam_acct_mgmt): %s",
|
||||
username, pam_strerror(handle, rc));
|
||||
}
|
||||
}
|
||||
|
||||
if (cleanup_handle)
|
||||
{
|
||||
pam_end(handle, 0);
|
||||
}
|
||||
}
|
||||
|
||||
WFD_INFO("authenticate user \'%s\': %s",
|
||||
(NULL != username) ? username : "<unknown>",
|
||||
result ? "success" : "failure");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static char const *
|
||||
wfd_pam_authenticator_get_type(
|
||||
void * data)
|
||||
{
|
||||
(void) data;
|
||||
return "username";
|
||||
}
|
||||
|
||||
static struct wfd_authenticator_vtable const
|
||||
wfd_pam_authenticator_vtable =
|
||||
{
|
||||
.dispose = &wfd_pam_authenticator_dispose,
|
||||
.authenticate = &wfd_pam_authenticator_authenticate,
|
||||
.get_type = &wfd_pam_authenticator_get_type
|
||||
};
|
||||
|
||||
bool
|
||||
wfd_pam_authenticator_create(
|
||||
struct wfd_settings * settings,
|
||||
struct wfd_authenticator * authenticator)
|
||||
{
|
||||
struct wfd_pam_authenticator * data = malloc(sizeof(struct wfd_pam_authenticator));
|
||||
data->service_name = strdup(wfd_settings_get_string_or_default(settings, "service_name", "webfused"));
|
||||
|
||||
authenticator->vtable = &wfd_pam_authenticator_vtable;
|
||||
authenticator->data = data;
|
||||
return true;
|
||||
}
|
||||
25
src/webfused/auth/pam_authenticator.h
Normal file
25
src/webfused/auth/pam_authenticator.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef WFD_AUTH_PAM_AUTHENTICATOR_H
|
||||
#define WFD_AUTH_PAM_AUTHENTICATOR_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct wfd_authenticator;
|
||||
struct wfd_settings;
|
||||
|
||||
extern bool
|
||||
wfd_pam_authenticator_create(
|
||||
struct wfd_settings * settings,
|
||||
struct wfd_authenticator * authenticator);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user