[gnome-keyring] pam: Add some tests for the PAM module



commit 02d7fd262a5bff089925029cae85c3586a850986
Author: Stef Walter <stefw gnome org>
Date:   Thu Mar 6 12:00:06 2014 +0100

    pam: Add some tests for the PAM module
    
    These require you to install some pam configs into /etc/pam.d. You
    can do it with the following commands:
    
    $ make enable-pam-tests
    $ make disable-pam-tests

 HACKING                                       |    6 +
 Makefile.am                                   |    2 +
 pam/Makefile.am                               |   54 +++
 pam/fixtures/gnome-keyring-test-auth-start    |    8 +
 pam/fixtures/gnome-keyring-test-no-start      |    8 +
 pam/fixtures/gnome-keyring-test-session-start |    8 +
 pam/fixtures/login.keyring                    |  Bin 0 -> 180 bytes
 pam/mock-pam.c                                |  125 ++++++
 pam/test-pam.c                                |  518 +++++++++++++++++++++++++
 9 files changed, 729 insertions(+), 0 deletions(-)
---
diff --git a/HACKING b/HACKING
index 7de873a..fa14a17 100644
--- a/HACKING
+++ b/HACKING
@@ -101,6 +101,12 @@ You check for memory errors by doing:
 
 $ make check-memory
 
+To test the pam code, you must first place some custom PAM configuration
+in your /etc/pam.d. This will not be used by anything else. To do this:
+
+$ sudo make enable-pam-tests
+$ sudo make disable-pam-tests
+
 
 ----------------------------------------------------------------------------------
   CODING STYLE
diff --git a/Makefile.am b/Makefile.am
index 1aa51bc..de06e2d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -129,6 +129,8 @@ SED_SUBST = sed \
        -e 's,[ ]prefix[@],$(prefix),g' \
        -e 's,[ ]abs_srcdir[@],$(abs_srcdir),g' \
        -e 's,[ ]srcdir[@],$(srcdir),g' \
+       -e 's,[ ]builddir[@],$(builddir),g' \
+       -e 's,[ ]abs_builddir[@],$(abs_builddir),g' \
        -e 's,[ ]PACKAGE[@],$(PACKAGE),g' \
        -e 's,[ ]VERSION[@],$(VERSION),g' \
        $(NULL)
diff --git a/pam/Makefile.am b/pam/Makefile.am
index 8707ab6..5c83c00 100644
--- a/pam/Makefile.am
+++ b/pam/Makefile.am
@@ -18,3 +18,57 @@ pam_gnome_keyring_la_LIBADD = \
 pam_gnome_keyring_la_LDFLAGS = \
        -module -avoid-version \
        -export-symbols-regex 'pam_sm_'
+
+# -----------------------------------------------------------------------------
+# PAM tests
+
+pam_CONFIGS = \
+       pam/fixtures/gnome-keyring-test-auth-start \
+       pam/fixtures/gnome-keyring-test-no-start \
+       pam/fixtures/gnome-keyring-test-session-start \
+       $(NULL)
+
+EXTRA_DIST += pam/fixtures
+
+enable-pam-tests:
+       for t in $(notdir $(pam_CONFIGS)); do \
+               $(SED_SUBST) $(srcdir)/pam/fixtures/$$t > $(sysconfdir)/pam.d/$$t; \
+       done
+
+disable-pam-tests:
+       for t in $(notdir $(pam_CONFIGS)); do \
+               $(RM) -f $(sysconfdir)/pam.d/$$t; \
+       done
+
+noinst_LTLIBRARIES += pam_mock.la
+
+pam_mock_la_SOURCES = pam/mock-pam.c
+pam_mock_la_LIBADD = \
+       -lpam
+pam_mock_la_LDFLAGS = \
+       -module -avoid-version \
+       -export-symbols-regex 'pam_sm_' \
+       -rpath /force/shared
+
+pam_CFLAGS = \
+       -DSYSCONFDIR=\"$(sysconfdir)\" \
+       $(NULL)
+
+pam_LIBS = \
+       libgkd-control-client.la \
+       libgkd-test.la \
+       libegg.la \
+       libegg-test.la \
+       $(GIO_LIBS) \
+       $(GLIB_LIBS) \
+       -lpam
+
+pam_TESTS = \
+       test-pam
+
+test_pam_SOURCES = pam/test-pam.c
+test_pam_LDADD = $(pam_LIBS)
+test_pam_CFLAGS = $(pam_CFLAGS)
+
+check_PROGRAMS += $(pam_TESTS)
+TESTS += $(pam_TESTS)
diff --git a/pam/fixtures/gnome-keyring-test-auth-start b/pam/fixtures/gnome-keyring-test-auth-start
new file mode 100644
index 0000000..57d9344
--- /dev/null
+++ b/pam/fixtures/gnome-keyring-test-auth-start
@@ -0,0 +1,8 @@
+auth        required      @abs_builddir@/.libs/pam_mock.so
+auth        required      @abs_builddir@/.libs/pam_gnome_keyring.so auto_start
+
+password    required      @abs_builddir@/.libs/pam_mock.so
+password    required      @abs_builddir@/.libs/pam_gnome_keyring.so use_authtok
+
+session     required      @abs_builddir@/.libs/pam_mock.so
+session     required      @abs_builddir@/.libs/pam_gnome_keyring.so
diff --git a/pam/fixtures/gnome-keyring-test-no-start b/pam/fixtures/gnome-keyring-test-no-start
new file mode 100644
index 0000000..dee22ca
--- /dev/null
+++ b/pam/fixtures/gnome-keyring-test-no-start
@@ -0,0 +1,8 @@
+auth        required      @abs_builddir@/.libs/pam_mock.so
+auth        required      @abs_builddir@/.libs/pam_gnome_keyring.so
+
+password    required      @abs_builddir@/.libs/pam_mock.so
+password    required      @abs_builddir@/.libs/pam_gnome_keyring.so use_authtok
+
+session     required      @abs_builddir@/.libs/pam_mock.so
+session     required      @abs_builddir@/.libs/pam_gnome_keyring.so
diff --git a/pam/fixtures/gnome-keyring-test-session-start b/pam/fixtures/gnome-keyring-test-session-start
new file mode 100644
index 0000000..38a3946
--- /dev/null
+++ b/pam/fixtures/gnome-keyring-test-session-start
@@ -0,0 +1,8 @@
+auth        required      @abs_builddir@/.libs/pam_mock.so
+auth        required      @abs_builddir@/.libs/pam_gnome_keyring.so
+
+password    required      @abs_builddir@/.libs/pam_mock.so
+password    required      @abs_builddir@/.libs/pam_gnome_keyring.so use_authtok
+
+session     required      @abs_builddir@/.libs/pam_mock.so
+session     required      @abs_builddir@/.libs/pam_gnome_keyring.so auto_start
diff --git a/pam/fixtures/login.keyring b/pam/fixtures/login.keyring
new file mode 100644
index 0000000..f53ed5d
Binary files /dev/null and b/pam/fixtures/login.keyring differ
diff --git a/pam/mock-pam.c b/pam/mock-pam.c
new file mode 100644
index 0000000..59f2da2
--- /dev/null
+++ b/pam/mock-pam.c
@@ -0,0 +1,125 @@
+/*
+   Copyright (C) 2014 Red Hat Inc.
+
+   The Gnome Keyring Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome Keyring Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   <http://www.gnu.org/licenses/>.
+
+   Author: Stef Walter <stefw gnome org>
+*/
+
+#include "config.h"
+
+#include <security/pam_appl.h>
+#include <security/pam_modules.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+static int
+prompt_password (pam_handle_t *ph,
+                 const char *prompt,
+                 int password_type)
+{
+       const struct pam_conv *conv;
+       struct pam_message msg;
+       struct pam_response *resp;
+       const struct pam_message *msgs[1];
+       const void *item;
+       char *password;
+       int ret;
+
+       /* Get the conversation function */
+       ret = pam_get_item (ph, PAM_CONV, &item);
+       if (ret != PAM_SUCCESS)
+               return ret;
+
+       /* Setup a message */
+       memset (&msg, 0, sizeof (msg));
+       memset (&resp, 0, sizeof (resp));
+       msg.msg_style = PAM_PROMPT_ECHO_OFF;
+       msg.msg = prompt;
+       msgs[0] = &msg;
+
+       /* Call away */
+       conv = (const struct pam_conv*)item;
+       ret = (conv->conv) (1, msgs, &resp, conv->appdata_ptr);
+       if (ret != PAM_SUCCESS)
+               return ret;
+
+       password = resp[0].resp;
+       free (resp);
+
+       if (password == NULL)
+               return PAM_CONV_ERR;
+
+       /* Store it away for later use */
+       ret = pam_set_item (ph, password_type, password);
+       free (password);
+
+       if (ret == PAM_SUCCESS)
+               ret = pam_get_item (ph, password_type, &item);
+
+       return ret;
+}
+
+PAM_EXTERN int
+pam_sm_authenticate (pam_handle_t *ph,
+                     int unused,
+                     int argc,
+                     const char **argv)
+{
+       /* Just prompt for the password, accept any result */
+       return prompt_password (ph, "Password: ", PAM_AUTHTOK);
+}
+
+PAM_EXTERN int
+pam_sm_open_session (pam_handle_t *ph,
+                     int flags,
+                     int argc,
+                     const char **argv)
+{
+       return PAM_IGNORE;
+}
+
+PAM_EXTERN int
+pam_sm_close_session (pam_handle_t *ph,
+                      int flags,
+                      int argc,
+                      const char **argv)
+{
+       return PAM_IGNORE;
+}
+
+PAM_EXTERN int
+pam_sm_setcred (pam_handle_t *ph,
+                int flags,
+                int argc,
+                const char **argv)
+{
+       return PAM_SUCCESS;
+}
+
+PAM_EXTERN int
+pam_sm_chauthtok (pam_handle_t *ph,
+                  int flags,
+                  int argc,
+                  const char **argv)
+{
+       if (flags & PAM_PRELIM_CHECK)
+               return prompt_password (ph, "Old Password: ", PAM_OLDAUTHTOK);
+       else if (flags & PAM_UPDATE_AUTHTOK)
+               return prompt_password (ph, "New Password: ", PAM_AUTHTOK);
+       else
+               return PAM_IGNORE;
+}
diff --git a/pam/test-pam.c b/pam/test-pam.c
new file mode 100644
index 0000000..3fe6946
--- /dev/null
+++ b/pam/test-pam.c
@@ -0,0 +1,518 @@
+/*
+   Copyright (C) 2014 Red Hat Inc
+
+   The Gnome Keyring Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome Keyring Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   <http://www.gnu.org/licenses/>.
+
+   Author: Stef Walter <stefw gnome org>
+*/
+
+#include "config.h"
+
+#include "daemon/control/gkd-control.h"
+#include "daemon/gkd-test.h"
+
+#include "egg/egg-testing.h"
+#include "egg/egg-secure-memory.h"
+
+#include <security/pam_appl.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gio/gio.h>
+
+#include <sys/wait.h>
+#include <errno.h>
+#include <fcntl.h>
+
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
+
+typedef struct {
+       GTestDBus *dbus;
+       GDBusConnection *connection;
+       gchar *directory;
+       GPid pid;
+       gboolean skipping;
+       pam_handle_t *ph;
+       struct pam_conv conv;
+       const gchar *password;
+       const gchar *new_password;
+} Test;
+
+const gchar *PASS_ENVIRON[] = {
+       "DBUS_SESSION_ADDRESS",
+       "XDG_RUNTIME_DIR",
+       "XDG_DATA_HOME",
+       NULL
+};
+
+static void
+skip_test (Test *test,
+           const gchar *reason)
+{
+       test->skipping = TRUE;
+#if GLIB_CHECK_VERSION(2, 40, 0)
+       g_test_skip (reason);
+#else
+       if (g_test_verbose ())
+               g_print ("GTest: skipping: %s\n", reason);
+       else
+               g_print ("SKIP: %s ", reason);
+#endif
+}
+
+static int
+conv_func (int n,
+           const struct pam_message **msg,
+           struct pam_response **resp,
+           void *arg)
+{
+       struct pam_response *aresp;
+       Test *test = arg;
+       int i;
+
+       g_assert (n > 0 && n < PAM_MAX_NUM_MSG);
+       aresp = g_new0(struct pam_response, n);
+
+       for (i = 0; i < n; ++i) {
+               aresp[i].resp_retcode = 0;
+               aresp[i].resp = NULL;
+               switch (msg[i]->msg_style) {
+               case PAM_PROMPT_ECHO_OFF:
+                       if (test->password) {
+                               aresp[i].resp = strdup (test->password);
+                               test->password = NULL;
+                       } else if (test->new_password) {
+                               aresp[i].resp = strdup (test->new_password);
+                               test->new_password = NULL;
+                       }
+                       g_assert (aresp[i].resp != NULL);
+                       break;
+               case PAM_PROMPT_ECHO_ON:
+                       aresp[i].resp = strdup (test->password);
+                       g_assert (aresp[i].resp != NULL);
+                       break;
+               case PAM_ERROR_MSG:
+                       fputs(msg[i]->msg, stderr);
+                       if (strlen(msg[i]->msg) > 0 &&
+                           msg[i]->msg[strlen(msg[i]->msg) - 1] != '\n')
+                               fputc('\n', stderr);
+                       break;
+               case PAM_TEXT_INFO:
+                       fprintf(stdout, "# %s", msg[i]->msg);
+                       if (strlen(msg[i]->msg) > 0 &&
+                           msg[i]->msg[strlen(msg[i]->msg) - 1] != '\n')
+                               fputc('\n', stdout);
+                       break;
+               default:
+                       return PAM_CONV_ERR;
+               }
+       }
+       *resp = aresp;
+       return PAM_SUCCESS;
+}
+
+static void
+setup (Test *test,
+       gconstpointer user_data)
+{
+       const gchar *pam_conf = user_data;
+       GError *error = NULL;
+       gchar *contents;
+       gboolean found;
+       gchar *filename;
+       gchar *env;
+       int ret;
+
+       /* First check if we have the right pam config */
+       filename = g_build_filename (SYSCONFDIR, "pam.d", pam_conf, NULL);
+       g_file_get_contents (filename, &contents, NULL, &error);
+       g_free (filename);
+
+       if (error == NULL) {
+               found = (strstr (contents, BUILDDIR) &&
+                        strstr (contents, "pam_gnome_keyring.so"));
+               g_free (contents);
+               if (!found) {
+                       skip_test (test, "test pam config contents invalid");
+                       return;
+               }
+       } else if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) {
+               skip_test (test, "missing test pam config");
+               return;
+       }
+
+       g_assert_no_error (error);
+
+       test->dbus = g_test_dbus_new (G_TEST_DBUS_NONE);
+       g_test_dbus_up (test->dbus);
+
+       test->directory = egg_tests_create_scratch_directory (NULL, NULL);
+
+       g_setenv ("XDG_RUNTIME_DIR", test->directory, TRUE);
+
+       test->conv.conv = conv_func;
+       test->conv.appdata_ptr = test;
+       ret = pam_start (pam_conf, g_get_user_name (), &test->conv, &test->ph);
+       g_assert_cmpint (ret, ==, PAM_SUCCESS);
+
+       g_unsetenv ("GNOME_KEYRING_CONTROL");
+
+       g_assert_cmpint (pam_putenv (test->ph, "GSETTINGS_SCHEMA_DIR=" BUILDDIR "/schema"), ==, PAM_SUCCESS);
+       g_assert_cmpint (pam_putenv (test->ph, "G_DEBUG=fatal-warnings,fatal-criticals"), ==, PAM_SUCCESS);
+
+       env = g_strdup_printf ("GNOME_KEYRING_TEST_PATH=%s", test->directory);
+       g_assert_cmpint (pam_putenv (test->ph, env), ==, PAM_SUCCESS);
+       g_free (env);
+
+       env = g_strdup_printf ("DBUS_SESSION_BUS_ADDRESS=%s", g_test_dbus_get_bus_address (test->dbus));
+       g_assert_cmpint (pam_putenv (test->ph, env), ==, PAM_SUCCESS);
+       g_free (env);
+
+       test->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
+       g_assert_no_error (error);
+}
+
+static void
+teardown (Test *test,
+          gconstpointer unused)
+{
+       if (test->skipping)
+               return;
+
+       g_object_unref (test->connection);
+
+       pam_end (test->ph, PAM_SUCCESS);
+
+       if (test->pid) {
+               if (waitpid (test->pid, NULL, WNOHANG) != test->pid) {
+                       kill (test->pid, SIGTERM);
+                       g_assert_cmpint (waitpid (test->pid, NULL, 0), ==, test->pid);
+               }
+               g_spawn_close_pid (test->pid);
+       }
+
+       egg_tests_remove_scratch_directory (test->directory);
+       g_free (test->directory);
+
+       g_test_dbus_down (test->dbus);
+       g_object_unref (test->dbus);
+}
+
+static gboolean
+check_if_login_keyring_locked (Test *test)
+{
+       GVariant *retval;
+       GError *error = NULL;
+       GVariant *prop;
+       gboolean ret;
+
+       retval = g_dbus_connection_call_sync (test->connection,
+                                             "org.gnome.keyring",
+                                             "/org/freedesktop/secrets/collection/login",
+                                             "org.freedesktop.DBus.Properties",
+                                             "Get",
+                                             g_variant_new ("(ss)",
+                                                            "org.freedesktop.Secret.Collection", "Locked"),
+                                             G_VARIANT_TYPE ("(v)"),
+                                             G_DBUS_CALL_FLAGS_NO_AUTO_START, -1,
+                                             NULL, &error);
+       g_assert_no_error (error);
+       g_variant_get (retval, "(@v)", &prop);
+       ret = g_variant_get_boolean (g_variant_get_variant (prop));
+       g_variant_unref (retval);
+
+       return ret;
+}
+
+static gboolean
+check_if_login_item_1_exists (Test *test)
+{
+       GVariant *retval;
+       GError *error = NULL;
+       gchar *remote;
+
+       retval = g_dbus_connection_call_sync (test->connection,
+                                             "org.gnome.keyring",
+                                             "/org/freedesktop/secrets/collection/login/1",
+                                             "org.freedesktop.DBus.Properties",
+                                             "Get",
+                                             g_variant_new ("(ss)",
+                                                            "org.freedesktop.Secret.Item", "Locked"),
+                                             G_VARIANT_TYPE ("(v)"),
+                                             G_DBUS_CALL_FLAGS_NO_AUTO_START, -1,
+                                             NULL, &error);
+
+       if (error) {
+               remote = g_dbus_error_get_remote_error (error);
+               if (!remote || !g_str_equal (remote, "org.freedesktop.Secret.Error.NoSuchObject"))
+                       g_assert_no_error (error);
+               g_error_free (error);
+               return FALSE;
+       }
+
+       g_variant_unref (retval);
+       return TRUE;
+}
+
+static void
+test_starts_creates (Test *test,
+                     gconstpointer user_data)
+{
+       const char *pam_conf = user_data;
+       gboolean start_in_session;
+       const gchar *control;
+       gchar *login_keyring;
+
+       if (test->skipping)
+               return;
+
+       start_in_session = (strstr (pam_conf, "session") != NULL);
+
+       login_keyring = g_build_filename (test->directory, "login.keyring", NULL);
+       g_assert (!g_file_test (login_keyring, G_FILE_TEST_EXISTS));
+
+       test->password = "booo";
+       g_assert_cmpint (pam_authenticate (test->ph, 0), ==, PAM_SUCCESS);
+
+       if (start_in_session)
+               g_assert_cmpint (pam_open_session (test->ph, 0), ==, PAM_SUCCESS);
+
+       g_assert (pam_getenv (test->ph, "GNOME_KEYRING_CONTROL") != NULL);
+       control = pam_getenv (test->ph, "GNOME_KEYRING_CONTROL");
+
+       /* Initialize the daemon for real */
+       g_assert (gkd_control_initialize (control, "secrets", PASS_ENVIRON));
+
+       /* The keyring was created */
+       g_assert (g_file_test (login_keyring, G_FILE_TEST_IS_REGULAR));
+       g_free (login_keyring);
+
+       g_assert (check_if_login_keyring_locked (test) == FALSE);
+       g_assert (check_if_login_item_1_exists (test) == FALSE);
+
+       if (!start_in_session)
+               g_assert_cmpint (pam_open_session (test->ph, 0), ==, PAM_SUCCESS);
+
+       g_assert (gkd_control_quit (control, 0));
+}
+
+static void
+test_starts_exists (Test *test,
+                    gconstpointer user_data)
+{
+       const gchar *pam_conf = user_data;
+       const gchar *control;
+       gboolean start_in_session;
+
+       if (test->skipping)
+               return;
+
+       start_in_session = (strstr (pam_conf, "session") != NULL);
+
+       egg_tests_copy_scratch_file (test->directory, SRCDIR "/pam/fixtures/login.keyring");
+
+       test->password = "booo";
+       g_assert_cmpint (pam_authenticate (test->ph, 0), ==, PAM_SUCCESS);
+
+       if (start_in_session)
+               g_assert_cmpint (pam_open_session (test->ph, 0), ==, PAM_SUCCESS);
+
+       g_assert (pam_getenv (test->ph, "GNOME_KEYRING_CONTROL") != NULL);
+       control = pam_getenv (test->ph, "GNOME_KEYRING_CONTROL");
+
+       /* Initialize the daemon for real */
+       g_assert (gkd_control_initialize (control, "secrets", PASS_ENVIRON));
+
+       /* Lookup the item */
+       g_assert (check_if_login_keyring_locked (test) == FALSE);
+       g_assert (check_if_login_item_1_exists (test) == TRUE);
+
+       if (!start_in_session)
+               g_assert_cmpint (pam_open_session (test->ph, 0), ==, PAM_SUCCESS);
+
+       g_assert (gkd_control_quit (control, 0));
+}
+
+static void
+test_auth_nostart (Test *test,
+                   gconstpointer user_data)
+{
+       gchar *login_keyring;
+
+       if (test->skipping)
+               return;
+
+       test->password = "booo";
+       g_assert_cmpint (pam_authenticate (test->ph, 0), ==, PAM_SUCCESS);
+
+       g_assert (pam_getenv (test->ph, "GNOME_KEYRING_CONTROL") == NULL);
+
+       login_keyring = g_build_filename (test->directory, "login.keyring", NULL);
+       g_assert (!g_file_test (login_keyring, G_FILE_TEST_EXISTS));
+       g_free (login_keyring);
+}
+
+static void
+test_auth_running_unlocks (Test *test,
+                           gconstpointer user_data)
+{
+       const gchar *control;
+       gchar **env;
+       GPid pid;
+
+       const gchar *argv[] = {
+               BUILDDIR "/gnome-keyring-daemon", "--foreground", NULL,
+       };
+
+       if (test->skipping)
+               return;
+
+       egg_tests_copy_scratch_file (test->directory, SRCDIR "/pam/fixtures/login.keyring");
+
+       env = gkd_test_launch_daemon (test->directory, argv, &pid, NULL);
+       g_assert_cmpstr (g_environ_getenv (env, "GNOME_KEYRING_CONTROL"), !=, NULL);
+
+       control = g_environ_getenv (env, "GNOME_KEYRING_CONTROL");
+       g_setenv ("GNOME_KEYRING_CONTROL", control, TRUE);
+
+       g_assert (check_if_login_keyring_locked (test) == TRUE);
+
+       test->password = "booo";
+       g_assert_cmpint (pam_authenticate (test->ph, 0), ==, PAM_SUCCESS);
+
+       /* Lookup the item */
+       g_assert (check_if_login_keyring_locked (test) == FALSE);
+       g_assert (check_if_login_item_1_exists (test) == TRUE);
+
+       g_assert (gkd_control_quit (control, 0));
+       g_assert_cmpint (waitpid (pid, NULL, 0), ==, pid);
+
+       g_strfreev (env);
+}
+
+static void
+test_password_changes_running (Test *test,
+                               gconstpointer user_data)
+{
+       const gchar *control;
+       gchar **env;
+       GPid pid;
+
+       const gchar *argv[] = {
+               BUILDDIR "/gnome-keyring-daemon", "--foreground", NULL
+       };
+
+       if (test->skipping)
+               return;
+
+       egg_tests_copy_scratch_file (test->directory, SRCDIR "/pam/fixtures/login.keyring");
+
+       env = gkd_test_launch_daemon (test->directory, argv, &pid, NULL);
+       g_assert_cmpstr (g_environ_getenv (env, "GNOME_KEYRING_CONTROL"), !=, NULL);
+       control = g_environ_getenv (env, "GNOME_KEYRING_CONTROL");
+       g_setenv ("GNOME_KEYRING_CONTROL", control, TRUE);
+
+       test->password = "booo";
+       test->new_password = "changed";
+       g_assert_cmpint (pam_chauthtok (test->ph, 0), ==, PAM_SUCCESS);
+
+       /* Quit the daemon */
+       g_assert (gkd_control_quit (control, 0));
+       g_assert_cmpint (waitpid (pid, NULL, 0), ==, pid);
+       g_strfreev (env);
+
+       /* Start it again */
+       env = gkd_test_launch_daemon (test->directory, argv, &pid, NULL);
+       control = g_environ_getenv (env, "GNOME_KEYRING_CONTROL");
+       g_setenv ("GNOME_KEYRING_CONTROL", control, TRUE);
+
+       g_assert (gkd_control_unlock (control, "changed"));
+       g_assert (gkd_control_quit (control, 0));
+       g_assert_cmpint (waitpid (pid, NULL, 0), ==, pid);
+
+       g_strfreev (env);
+}
+
+static void
+test_password_changes_starts (Test *test,
+                              gconstpointer user_data)
+{
+       const gchar *control;
+       gchar **env;
+       GPid pid;
+
+       const gchar *argv[] = {
+               BUILDDIR "/gnome-keyring-daemon", "--foreground", NULL,
+       };
+
+       if (test->skipping)
+               return;
+
+       egg_tests_copy_scratch_file (test->directory, SRCDIR "/pam/fixtures/login.keyring");
+
+       test->password = "booo";
+       test->new_password = "changed";
+       g_assert_cmpint (pam_chauthtok (test->ph, 0), ==, PAM_SUCCESS);
+
+       /* Start it again */
+       env = gkd_test_launch_daemon (test->directory, argv, &pid,
+                                     "GNOME_KEYRING_TEST_SERVICE", "another.Bus.Name",
+                                     NULL);
+       control = g_environ_getenv (env, "GNOME_KEYRING_CONTROL");
+       g_setenv ("GNOME_KEYRING_CONTROL", control, TRUE);
+
+       g_assert (gkd_control_unlock (control, "changed"));
+       g_assert (gkd_control_quit (control, 0));
+       g_assert_cmpint (waitpid (pid, NULL, 0), ==, pid);
+
+       g_strfreev (env);
+}
+
+int
+main (int argc, char **argv)
+{
+       g_test_init (&argc, &argv, NULL);
+
+       g_test_add ("/pam/auth-no-start", Test,
+                   "gnome-keyring-test-no-start",
+                   setup, test_auth_nostart, teardown);
+
+       g_test_add ("/pam/auth-starts-creates-keyring", Test,
+                   "gnome-keyring-test-auth-start",
+                   setup, test_starts_creates, teardown);
+       g_test_add ("/pam/session-starts-creates-keyring", Test,
+                   "gnome-keyring-test-session-start",
+                   setup, test_starts_creates, teardown);
+
+       g_test_add ("/pam/auth-starts-unlocks-existing", Test,
+                   "gnome-keyring-test-auth-start",
+                   setup, test_starts_exists, teardown);
+       g_test_add ("/pam/session-starts-unlocks-existing", Test,
+                   "gnome-keyring-test-session-start",
+                   setup, test_starts_exists, teardown);
+
+       g_test_add ("/pam/auth-running-unlocks-existing", Test,
+                   "gnome-keyring-test-no-start",
+                   setup, test_auth_running_unlocks, teardown);
+
+       g_test_add ("/pam/password-changes-running", Test,
+                   "gnome-keyring-test-no-start",
+                   setup, test_password_changes_running, teardown);
+       g_test_add ("/pam/password-changes-starts", Test,
+                   "gnome-keyring-test-no-start",
+                   setup, test_password_changes_starts, teardown);
+
+       return g_test_run ();
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]