mirror of
https://github.com/falk-werner/webfused
synced 2024-10-27 20:44:08 +00:00
added pam authenticator
This commit is contained in:
parent
b53e002de0
commit
ca348795f3
@ -60,6 +60,7 @@ add_library(webfused-static STATIC
|
||||
src/webfused/auth/authenticator.c
|
||||
src/webfused/auth/factory.c
|
||||
src/webfused/auth/file_authenticator.c
|
||||
src/webfused/auth/pam_authenticator.c
|
||||
src/webfused/log/log.c
|
||||
src/webfused/log/logger.c
|
||||
src/webfused/log/manager.c
|
||||
@ -122,18 +123,19 @@ add_executable(alltests
|
||||
test/mock_logger.cc
|
||||
test/mock_credentials.cc
|
||||
test/mock_settings.cc
|
||||
test/mock_pam.cc
|
||||
test/test_config_factory.cc
|
||||
test/test_config.cc
|
||||
test/test_settings.cc
|
||||
test/test_auth_factory.cc
|
||||
test/test_file_authenticator.cc
|
||||
test/test_pam_authenticator.cc
|
||||
test/test_mountpoint_factory.cc
|
||||
test/test_log.cc
|
||||
test/test_log_manager.cc
|
||||
test/test_stderr_logger.cc
|
||||
test/test_syslog_logger.cc
|
||||
test/test_daemon.cc
|
||||
test/test_pam.cc
|
||||
)
|
||||
|
||||
target_include_directories(alltests PRIVATE
|
||||
@ -164,6 +166,12 @@ target_link_libraries(alltests PRIVATE
|
||||
-Wl,--wrap=wfd_config_set_logger
|
||||
-Wl,--wrap=wfd_config_set_user
|
||||
|
||||
-Wl,--wrap=pam_start
|
||||
-Wl,--wrap=pam_end
|
||||
-Wl,--wrap=pam_strerror
|
||||
-Wl,--wrap=pam_authenticate
|
||||
-Wl,--wrap=pam_acct_mgmt
|
||||
|
||||
webfused-static
|
||||
userdb
|
||||
${LIBCONFIG_LIBRARIES}
|
||||
|
17
README.md
17
README.md
@ -39,10 +39,10 @@ server:
|
||||
authentication:
|
||||
(
|
||||
{
|
||||
provider = "file"
|
||||
provider = "pam"
|
||||
settings:
|
||||
{
|
||||
file = "/etc/webfused/passwd"
|
||||
service_name = "webfused"
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -104,9 +104,10 @@ Otherwise, plain websockes without TLS are used.
|
||||
| provider | string | *-required-* | Name of the authentication provider (see below) |
|
||||
| settings | object | *-empty-* | Provider specific settings (see below)
|
||||
|
||||
Currently, only one provider is specified:
|
||||
Currently, the following providers are supported:
|
||||
|
||||
- *file*: file based authentication
|
||||
- *pam*: authentication based on Linux PAM
|
||||
|
||||
### File Authenticaton Provider
|
||||
|
||||
@ -114,7 +115,15 @@ Allows authentication against a file containing username and password.
|
||||
|
||||
| Setting | Type | Default value | Description |
|
||||
| -------- | ------ | ------------- | ------------------------------- |
|
||||
| file | string | *-empty-* | Path to the authentication file |
|
||||
| file | string | *-required-* | Path to the authentication file |
|
||||
|
||||
### PAM Authenticaton Provider
|
||||
|
||||
Allows authentication using Linux PAM.
|
||||
|
||||
| Setting | Type | Default value | Description |
|
||||
| ------------ | ------ | ------------- | ---------------------- |
|
||||
| service_name | string | webfused | PAM service identifier |
|
||||
|
||||
### Filesystems
|
||||
|
||||
|
@ -25,6 +25,13 @@ authentication:
|
||||
file = "/etc/webfused/passwd"
|
||||
}
|
||||
}
|
||||
# {
|
||||
# provider = "pam"
|
||||
# settings:
|
||||
# {
|
||||
# service_name = "webfused"
|
||||
# }
|
||||
# }
|
||||
)
|
||||
|
||||
filesystems:
|
||||
|
@ -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
|
99
test/mock_pam.cc
Normal file
99
test/mock_pam.cc
Normal file
@ -0,0 +1,99 @@
|
||||
#include "mock_pam.hpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
static webfused_test::IPam * wfd_MockPam = nullptr;
|
||||
|
||||
extern int __real_pam_start(
|
||||
char const * service_name,
|
||||
char const * user,
|
||||
struct pam_conv const * conversation,
|
||||
pam_handle_t * * handle);
|
||||
extern int __real_pam_end(pam_handle_t * handle, int status);
|
||||
extern int __real_pam_authenticate(pam_handle_t * handle, int flags);
|
||||
extern int __real_pam_acct_mgmt(pam_handle_t * handle, int flags);
|
||||
extern char const * __real_pam_strerror(pam_handle_t * handle, int errnum);
|
||||
|
||||
int __wrap_pam_start(
|
||||
char const * service_name,
|
||||
char const * user,
|
||||
struct pam_conv const * conversation,
|
||||
pam_handle_t * * handle)
|
||||
{
|
||||
if (nullptr == wfd_MockPam)
|
||||
{
|
||||
return __real_pam_start(service_name, user, conversation, handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
return wfd_MockPam->start(service_name, user, conversation, handle);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int __wrap_pam_end(pam_handle_t * handle, int status)
|
||||
{
|
||||
if (nullptr == wfd_MockPam)
|
||||
{
|
||||
return __real_pam_end(handle, status);
|
||||
}
|
||||
else
|
||||
{
|
||||
return wfd_MockPam->end(handle, status);
|
||||
}
|
||||
}
|
||||
|
||||
int __wrap_pam_authenticate(pam_handle_t * handle, int flags)
|
||||
{
|
||||
if (nullptr == wfd_MockPam)
|
||||
{
|
||||
return __real_pam_authenticate(handle, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
return wfd_MockPam->authenticate(handle, flags);
|
||||
}
|
||||
}
|
||||
|
||||
int __wrap_pam_acct_mgmt(pam_handle_t * handle, int flags)
|
||||
{
|
||||
if (nullptr == wfd_MockPam)
|
||||
{
|
||||
return __real_pam_acct_mgmt(handle, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
return wfd_MockPam->acct_mgmt(handle, flags);
|
||||
}
|
||||
}
|
||||
|
||||
char const * __wrap_pam_strerror(pam_handle_t * handle, int errnum)
|
||||
{
|
||||
if (nullptr == wfd_MockPam)
|
||||
{
|
||||
return __real_pam_strerror(handle, errnum);
|
||||
}
|
||||
else
|
||||
{
|
||||
return wfd_MockPam->strerror(handle, errnum);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
MockPam::MockPam()
|
||||
{
|
||||
wfd_MockPam = this;
|
||||
}
|
||||
|
||||
MockPam::~MockPam()
|
||||
{
|
||||
wfd_MockPam = nullptr;
|
||||
}
|
||||
|
||||
}
|
45
test/mock_pam.hpp
Normal file
45
test/mock_pam.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef WFD_MOCK_PAM_HPP
|
||||
#define WFD_MOCK_PAM_HPP
|
||||
|
||||
#include <security/pam_appl.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
class IPam
|
||||
{
|
||||
public:
|
||||
virtual ~IPam() = default;
|
||||
virtual int start(
|
||||
char const * service_name,
|
||||
char const * user,
|
||||
struct pam_conv const * conversation,
|
||||
pam_handle_t * * handle) = 0;
|
||||
virtual int end(pam_handle_t * handle, int status) = 0;
|
||||
virtual int authenticate(pam_handle_t * handle, int flags) = 0;
|
||||
virtual int acct_mgmt(pam_handle_t * handle, int flags) = 0;
|
||||
virtual char const * strerror(pam_handle_t * handle, int errnum) = 0;
|
||||
};
|
||||
|
||||
class MockPam: public IPam
|
||||
{
|
||||
public:
|
||||
MockPam();
|
||||
~MockPam() override;
|
||||
|
||||
MOCK_METHOD4(start, int (
|
||||
char const * service_name,
|
||||
char const * user,
|
||||
struct pam_conv const * conversation,
|
||||
pam_handle_t * * handle));
|
||||
|
||||
MOCK_METHOD2(end, int(pam_handle_t * handle, int status));
|
||||
MOCK_METHOD2(authenticate, int(pam_handle_t * handle, int flags));
|
||||
MOCK_METHOD2(acct_mgmt, int (pam_handle_t * handle, int flags));
|
||||
MOCK_METHOD2(strerror, char const * (pam_handle_t * handle, int errnum));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,13 +0,0 @@
|
||||
#include <security/pam_appl.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(pam, start)
|
||||
{
|
||||
pam_handle_t * handle = nullptr;
|
||||
struct pam_conv conv = { nullptr, nullptr };
|
||||
int rc = pam_start("test", nullptr, &conv, &handle);
|
||||
if (PAM_SUCCESS == rc)
|
||||
{
|
||||
pam_end(handle, 0);
|
||||
}
|
||||
}
|
277
test/test_pam_authenticator.cc
Normal file
277
test/test_pam_authenticator.cc
Normal file
@ -0,0 +1,277 @@
|
||||
#include "webfused/auth/pam_authenticator.h"
|
||||
#include "webfused/auth/authenticator.h"
|
||||
#include "webfused/config/settings.h"
|
||||
#include "webfused/auth/factory.h"
|
||||
|
||||
#include "mock_credentials.hpp"
|
||||
#include "mock_settings.hpp"
|
||||
#include "mock_pam.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
|
||||
using ::webfused_test::MockSettings;
|
||||
using ::webfused_test::MockCredentials;
|
||||
using ::webfused_test::MockPam;
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
using ::testing::StrEq;
|
||||
using ::testing::Invoke;
|
||||
using ::testing::StrictMock;
|
||||
|
||||
TEST(pam_authenticator, create)
|
||||
{
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, create_via_factory)
|
||||
{
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_authenticator_create("pam", nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, get_type)
|
||||
{
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
ASSERT_STREQ("username", wfd_authenticator_get_type(authenticator));
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, authenticate)
|
||||
{
|
||||
MockPam pam;
|
||||
EXPECT_CALL(pam, start(StrEq("webfused"), nullptr, _, _)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, authenticate(_, PAM_DISALLOW_NULL_AUTHTOK)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, acct_mgmt(_, PAM_DISALLOW_NULL_AUTHTOK)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, end(_, _)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, get(StrEq("username"))).Times(1).WillOnce(Return("bob"));
|
||||
EXPECT_CALL(creds, get(StrEq("password"))).Times(1).WillOnce(Return("secret"));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_TRUE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, authenticate_with_custom_service_name)
|
||||
{
|
||||
MockPam pam;
|
||||
EXPECT_CALL(pam, start(StrEq("brummni"), nullptr, _, _)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, authenticate(_, PAM_DISALLOW_NULL_AUTHTOK)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, acct_mgmt(_, PAM_DISALLOW_NULL_AUTHTOK)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, end(_, _)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
|
||||
MockSettings settings;
|
||||
EXPECT_CALL(settings, getStringOrDefault(StrEq("service_name"), StrEq("webfused")))
|
||||
.Times(1).WillOnce(Return("brummni"));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, get(StrEq("username"))).Times(1).WillOnce(Return("bob"));
|
||||
EXPECT_CALL(creds, get(StrEq("password"))).Times(1).WillOnce(Return("secret"));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_TRUE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
int valid_conversation(
|
||||
char const * service_name,
|
||||
char const * user,
|
||||
struct pam_conv const * conv,
|
||||
pam_handle_t * * handle)
|
||||
{
|
||||
(void) service_name;
|
||||
(void) user;
|
||||
(void) handle;
|
||||
|
||||
pam_message request_username = {PAM_PROMPT_ECHO_ON, "username"};
|
||||
pam_message request_password = {PAM_PROMPT_ECHO_OFF, "password"};
|
||||
pam_message const * messages[2] =
|
||||
{
|
||||
&request_username,
|
||||
&request_password
|
||||
};
|
||||
pam_response * responses;
|
||||
int rc = conv->conv(2, messages, &responses, conv->appdata_ptr);
|
||||
if (PAM_SUCCESS == rc)
|
||||
{
|
||||
free(responses);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, conversation_with_valid_messages)
|
||||
{
|
||||
MockPam pam;
|
||||
EXPECT_CALL(pam, start(StrEq("webfused"), nullptr, _, _))
|
||||
.Times(1).WillOnce(Invoke(&valid_conversation));
|
||||
EXPECT_CALL(pam, authenticate(_, PAM_DISALLOW_NULL_AUTHTOK)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, acct_mgmt(_, PAM_DISALLOW_NULL_AUTHTOK)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, end(_, _)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, get(StrEq("username"))).Times(1).WillOnce(Return("bob"));
|
||||
EXPECT_CALL(creds, get(StrEq("password"))).Times(1).WillOnce(Return("secret"));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_TRUE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
int invalid_conversation(
|
||||
char const * service_name,
|
||||
char const * user,
|
||||
struct pam_conv const * conv,
|
||||
pam_handle_t * * handle)
|
||||
{
|
||||
(void) service_name;
|
||||
(void) user;
|
||||
(void) handle;
|
||||
|
||||
pam_message invalid_request = {-1, "invalid"};
|
||||
pam_message const * messages[2] =
|
||||
{
|
||||
&invalid_request
|
||||
};
|
||||
pam_response * responses;
|
||||
int rc = conv->conv(1, messages, &responses, conv->appdata_ptr);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, conversation_with_invalid_messages)
|
||||
{
|
||||
MockPam pam;
|
||||
EXPECT_CALL(pam, start(StrEq("webfused"), nullptr, _, _))
|
||||
.Times(1).WillOnce(Invoke(&invalid_conversation));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, get(StrEq("username"))).Times(1).WillOnce(Return("bob"));
|
||||
EXPECT_CALL(creds, get(StrEq("password"))).Times(1).WillOnce(Return("secret"));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_FALSE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, authenticate_fail_authenticate)
|
||||
{
|
||||
MockPam pam;
|
||||
EXPECT_CALL(pam, start(StrEq("webfused"), nullptr, _, _)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, authenticate(_, PAM_DISALLOW_NULL_AUTHTOK)).Times(1).WillOnce(Return(-1));
|
||||
EXPECT_CALL(pam, end(_, _)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, get(StrEq("username"))).Times(1).WillOnce(Return("bob"));
|
||||
EXPECT_CALL(creds, get(StrEq("password"))).Times(1).WillOnce(Return("secret"));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_FALSE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, authenticate_fail_acct_mgmt)
|
||||
{
|
||||
MockPam pam;
|
||||
EXPECT_CALL(pam, start(StrEq("webfused"), nullptr, _, _)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, authenticate(_, PAM_DISALLOW_NULL_AUTHTOK)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, acct_mgmt(_, PAM_DISALLOW_NULL_AUTHTOK)).Times(1).WillOnce(Return(-1));
|
||||
EXPECT_CALL(pam, end(_, _)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, get(StrEq("username"))).Times(1).WillOnce(Return("bob"));
|
||||
EXPECT_CALL(creds, get(StrEq("password"))).Times(1).WillOnce(Return("secret"));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_FALSE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, authenticate_fail_missing_username)
|
||||
{
|
||||
StrictMock<MockPam> pam;
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, get(StrEq("username"))).Times(1).WillOnce(Return(nullptr));
|
||||
EXPECT_CALL(creds, get(StrEq("password"))).Times(1).WillOnce(Return("secret"));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_FALSE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, authenticate_fail_missing_password)
|
||||
{
|
||||
StrictMock<MockPam> pam;
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, get(StrEq("username"))).Times(1).WillOnce(Return("bob"));
|
||||
EXPECT_CALL(creds, get(StrEq("password"))).Times(1).WillOnce(Return(nullptr));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_FALSE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
@ -21,7 +21,13 @@ TEST(stderr_logger, init_via_manager)
|
||||
TEST(stderr_logger, log)
|
||||
{
|
||||
ASSERT_TRUE(wfd_stderr_logger_init(WFD_LOGLEVEL_ALL, NULL));
|
||||
WFD_INFO("some information");
|
||||
|
||||
WFD_FATAL("webfused test");
|
||||
WFD_ERROR("webfused test");
|
||||
WFD_WARN ("webfused test");
|
||||
WFD_INFO ("webfused test");
|
||||
WFD_DEBUG("webfused test");
|
||||
wfd_log(-1, "webfused test");
|
||||
|
||||
wfd_logger_close();
|
||||
}
|
@ -39,7 +39,13 @@ TEST(syslog_logger, init_via_manager)
|
||||
TEST(syslog_logger, log)
|
||||
{
|
||||
ASSERT_TRUE(wfd_syslog_logger_init(WFD_LOGLEVEL_ALL, NULL));
|
||||
WFD_INFO("some information");
|
||||
|
||||
WFD_FATAL("webfused test");
|
||||
WFD_ERROR("webfused test");
|
||||
WFD_WARN ("webfused test");
|
||||
WFD_INFO ("webfused test");
|
||||
WFD_DEBUG("webfused test");
|
||||
wfd_log(-1, "webfused test");
|
||||
|
||||
wfd_logger_close();
|
||||
}
|
Loading…
Reference in New Issue
Block a user