From e552688b70889a4879ef16ce38bc8c95e6f447c7 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 19 Sep 2012 14:35:36 -0500 Subject: Steal a bunch of test infrastructure from libpam-icaclient --- tests/Makefile.am | 65 +++++++++++++++++++++++++ tests/mock_guest.c | 51 ++++++++++++++++++++ tests/mock_guest.h | 24 +++++++++ tests/mock_pam.c | 110 ++++++++++++++++++++++++++++++++++++++++++ tests/mock_pam.h | 23 +++++++++ tests/test-freerdp-wrapper.cc | 67 +++++++++++++++++++++++++ 6 files changed, 340 insertions(+) create mode 100644 tests/Makefile.am create mode 100644 tests/mock_guest.c create mode 100644 tests/mock_guest.h create mode 100644 tests/mock_pam.c create mode 100644 tests/mock_pam.h create mode 100644 tests/test-freerdp-wrapper.cc (limited to 'tests') diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000..e687799 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,65 @@ +CLEANFILES = +DISTCLEANFILES = +EXTRA_DIST = + +TESTS = \ + test-auth-check \ + test-icaclient-wrapper + +check_PROGRAMS = $(TESTS) + +########################## +# Google Test Test Suite # +########################## +check_LIBRARIES = libgtest.a + +AM_CPPFLAGS = $(GTEST_CPPFLAGS) \ + $(REMOTE_APPS_MANAGER_CFLAGS) \ + -I${top_srcdir}/src -Wall -Werror +AM_CXXFLAGS = $(GTEST_CXXFLAGS) \ + $(REMOTE_APPS_MANAGER_CFLAGS) + +AM_CFLAGS = \ + -Wall \ + -g + +nodist_libgtest_a_SOURCES = \ + $(GTEST_SOURCE)/src/gtest-all.cc \ + $(GTEST_SOURCE)/src/gtest_main.cc + +libgtest_a_CPPFLAGS = \ + $(GTEST_CPPFLAGS) -w \ + $(AM_CPPFLAGS) +libgtest_a_CXXFLAGS = \ + $(AM_CXXFLAGS) + +test_auth_check_SOURCES = \ + test-auth-check.cc + +test_auth_check_LDADD = \ + $(top_builddir)/src/pam_ica.la \ + libgtest.a + +test_auth_check_CXXFLAGS = \ + $(AM_CXXFLAGS) \ + -I${top_srcdir}/src + +test_auth_check_LDFLAGS = \ + -pthread + +test_icaclient_wrapper_SOURCES = \ + mock_pam.c \ + mock_guest.c \ + test-icaclient-wrapper.cc + +test_icaclient_wrapper_LDADD = \ + $(top_builddir)/src/pam_ica.la \ + libgtest.a + +test_icaclient_wrapper_CXXFLAGS = \ + $(AM_CXXFLAGS) \ + -I${top_srcdir}/src + +test_icaclient_wrapper_LDFLAGS = \ + -pthread + diff --git a/tests/mock_guest.c b/tests/mock_guest.c new file mode 100644 index 0000000..2cf04b3 --- /dev/null +++ b/tests/mock_guest.c @@ -0,0 +1,51 @@ +/* + * Copyright © 2012 Canonical Ltd. All rights reserved. + * + * Author(s): David Barth + * + */ + +#include +#include +#include +#include + +static struct passwd guest = { "guest", + "password", + 500, 500, + "M. Guest", + "/tmp", + "/bin/true" }; +struct passwd * +getpwnam (const char *username) +{ return &guest; } + +int +setgroups(size_t size, const gid_t *list) +{ + errno = EPERM; + return -1; +} + +int +setgid(gid_t gid) +{ return 0; } + +int +setuid(uid_t uid) +{ return 0; } + +int +setegid(gid_t gid) +{ return 0; } + +int +seteuid(uid_t uid) +{ return 0; } + +int chmod(const char *path, mode_t mode) +{ return 0; } + +int chown(const char *path, uid_t owner, gid_t group) +{ return 0; } + diff --git a/tests/mock_guest.h b/tests/mock_guest.h new file mode 100644 index 0000000..c4179b9 --- /dev/null +++ b/tests/mock_guest.h @@ -0,0 +1,24 @@ +/* + * Copyright © 2012 Canonical Ltd. All rights reserved. + * + * Author(s): David Barth + * + */ + +#ifndef __MOCK_GUEST_H__ +#define __MOCK_GUEST_H__ + +#include +#include +#include + +struct passwd *getpwnam (const char *username); +int setgroups(size_t size, const gid_t *list); +int setgid(gid_t gid); +int setuid(uid_t uid); +int setegid(gid_t gid); +int seteuid(uid_t uid); +int chmod(const char *path, mode_t mode); +int chown(const char *path, uid_t owner, gid_t group); + +#endif diff --git a/tests/mock_pam.c b/tests/mock_pam.c new file mode 100644 index 0000000..6368b84 --- /dev/null +++ b/tests/mock_pam.c @@ -0,0 +1,110 @@ +/* + * Copyright © 2012 Canonical Ltd. All rights reserved. + * + * Author(s): David Barth + * + */ + +#include +#include + +#include "mock_pam.h" + +struct pam_handle { + void *item[PAM_NUM_ITEMS]; + + struct pam_conv *conv; + + /* note: the other fields have been omitted */ +}; + +int fake_conv (int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr) +{ + struct pam_response *response = NULL; + response = malloc (sizeof (struct pam_response)); + + if (response == NULL) + return PAM_BUF_ERR; + + response->resp_retcode = 0; + + if (strcmp((*msg)->msg, "login:") == 0) + response->resp = strdup ("guest"); /* IMPORTANT: this needs to be in /etc/passwd */ + else if (strcmp((*msg)->msg, "remote login:") == 0) + response->resp = strdup ("ruser"); + else if (strcmp((*msg)->msg, "remote host:") == 0) + response->resp = strdup ("protocol://rhost/dummy"); + else if (strcmp((*msg)->msg, "password:") == 0) + response->resp = strdup ("password"); + else if (strcmp((*msg)->msg, "domain:") == 0) + response->resp = strdup ("domain"); + else + return PAM_SYMBOL_ERR; /* leaks... */ + + *resp = response; + + return PAM_SUCCESS; +} + +struct pam_conv static_conv = { &fake_conv, (void *)NULL }; + +pam_handle_t *pam_handle_new (void) +{ + pam_handle_t *newh = malloc (sizeof (pam_handle_t)); + + if (newh != NULL) { + newh->conv = &static_conv; + memset(newh->item, 0, sizeof(void *) * PAM_NUM_ITEMS); + } + + return newh; +} + +int pam_get_item (const pam_handle_t *pamh, int type, const void **value) +{ + if (pamh == NULL) + return PAM_SYSTEM_ERR; + + if (type == PAM_CONV) + *value = pamh->conv; + else if (pamh->item[type] != NULL) + *value = pamh->item[type]; + else + *value = NULL; /* will result in a prompt conversation */ + + return PAM_SUCCESS; +} + +int pam_set_item (pam_handle_t *pamh, int type, const void *value) +{ + if (pamh == NULL) + return PAM_SYSTEM_ERR; + + void **slot, *tmp; + size_t nsize, osize; + + slot = &pamh->item[type]; + osize = nsize = 0; + + if (*slot != NULL) + osize = strlen((const char *)*slot) + 1; + if (value != NULL) + nsize = strlen((const char *)value) + 1; + + if (*slot != NULL) { + memset(*slot, 0xd0, osize); + free(*slot); + } + + if (value != NULL) { + if ((tmp = malloc(nsize)) == NULL) + return PAM_BUF_ERR; + memcpy(tmp, value, nsize); + } else { + tmp = NULL; + } + *slot = tmp; + + return PAM_SUCCESS; +} diff --git a/tests/mock_pam.h b/tests/mock_pam.h new file mode 100644 index 0000000..eb88a2e --- /dev/null +++ b/tests/mock_pam.h @@ -0,0 +1,23 @@ +/* + * Copyright © 2012 Canonical Ltd. All rights reserved. + * + * Author(s): David Barth + * + */ + +#ifndef __MOCK_PAM_H__ +#define __MOCK_PAM_H__ + +#include +#include +#include + +#define PAM_NUM_ITEMS PAM_AUTHTOK_TYPE + +typedef struct pam_handle pam_handle_t; + +pam_handle_t *pam_handle_new (void); +int pam_get_item (const pam_handle_t *pamh, int type, const void **value); +int pam_set_item (pam_handle_t *pamh, int type, const void *value); + +#endif diff --git a/tests/test-freerdp-wrapper.cc b/tests/test-freerdp-wrapper.cc new file mode 100644 index 0000000..889aedb --- /dev/null +++ b/tests/test-freerdp-wrapper.cc @@ -0,0 +1,67 @@ +/* + * Copyright © 2012 Canonical Ltd. All rights reserved. + * + * Author(s): David Barth + * + */ + +#include + +extern "C" { + +#include "mock_pam.h" +#include "mock_guest.h" + + int freerdpclient_wrapper (int argc, char * argv[]); +} + +namespace { + + // The fixture for testing class Foo. + class FreerdpclientWrapperTest : public ::testing::Test { + protected: + // You can remove any or all of the following functions if its body + // is empty. + + FreerdpclientWrapperTest() { + // You can do set-up work for each test here. + setenv("HOME", "/tmp", 1 /* overwrite */); + } + + virtual ~FreerdpclientWrapperTest() { + // You can do clean-up work that doesn't throw exceptions here. + } + + // If the constructor and destructor are not enough for setting up + // and cleaning up each test, you can define the following methods: + + virtual void SetUp() { + // Code here will be called immediately after the constructor (right + // before each test). + unlink("/tmp/.freerdp-socket"); + } + + virtual void TearDown() { + // Code here will be called immediately after each test (right + // before the destructor). + unlink("/tmp/.freerdp-socket"); + } + + // Objects declared here can be used by all tests in the test case for Foo. + }; + + TEST_F(FreerdpclientWrapperTest, canLinkTheWholeGang) { + EXPECT_EQ (1, 1); // right, that's trivial, but that means + // that I got all of the wrapper and pam to link there + } + + TEST_F(FreerdpclientWrapperTest, canCallPamOpenSession) { + const char *argv[] = { NULL }; + + pam_handle_t *pamh = pam_handle_new (); + + EXPECT_EQ (PAM_SUCCESS, + pam_sm_open_session (pamh, 0, 0, argv)); + } + +} -- cgit v1.2.3