Testing of gsecret_service_ensure and friends

This commit is contained in:
Stef Walter 2011-09-25 22:59:43 +02:00 committed by Stef Walter
parent 51896081f0
commit 6b4d7b6484
7 changed files with 204 additions and 28 deletions

View File

@ -24,16 +24,15 @@ dist-hook:
fi
if WITH_COVERAGE
check-coverage: clear-coverage check coverage
coverage:
mkdir -p coverage
$(LCOV) --directory . --capture --output-file coverage/coverage.info
$(GENHTML) --output-directory coverage/coverage coverage/coverage.info
$(GENHTML) --output-directory coverage coverage/coverage.info
$(LCOV) --directory . --zerocounters
@echo "file://$(abs_top_builddir)/coverage/index.html"
clear-coverage:
$(LCOV) --directory . --zerocounters
.PHONY: coverage
endif

View File

@ -34,8 +34,12 @@ EGG_SECURE_GLIB_DEFINITIONS ();
EGG_SECURE_DECLARE (secret_service);
#define ALGORITHMS_AES "dh-ietf1024-sha256-aes128-cbc-pkcs7"
#define ALGORITHMS_PLAIN "plain"
typedef struct {
gchar *path;
const gchar *algorithms;
#ifdef WITH_GCRYPT
gcry_mpi_t prime;
gcry_mpi_t privat;
@ -156,6 +160,28 @@ _gsecret_service_bare_instance (GDBusConnection *connection,
return service;
}
const gchar *
gsecret_service_get_session_algorithms (GSecretService *self)
{
GSecretSession *session;
g_return_val_if_fail (GSECRET_IS_SERVICE (self), NULL);
session = g_atomic_pointer_get (&self->pv->session);
return session ? session->algorithms : NULL;
}
const gchar *
gsecret_service_get_session_path (GSecretService *self)
{
GSecretSession *session;
g_return_val_if_fail (GSECRET_IS_SERVICE (self), NULL);
session = g_atomic_pointer_get (&self->pv->session);
return session ? session->path : NULL;
}
#ifdef WITH_GCRYPT
static GVariant *
@ -186,7 +212,7 @@ request_open_session_aes (GSecretSession *session)
buffer, n_buffer, TRUE,
gcry_free, buffer);
return g_variant_new ("sv", "dh-ietf1024-sha256-aes128-cbc-pkcs7", argument);
return g_variant_new ("(sv)", ALGORITHMS_AES, argument);
}
static gboolean
@ -195,20 +221,23 @@ response_open_session_aes (GSecretSession *session,
{
gconstpointer buffer;
GVariant *argument;
const gchar *sig;
gsize n_buffer;
gcry_mpi_t peer;
gcry_error_t gcry;
gpointer ikm;
gsize n_ikm;
if (G_VARIANT_TYPE ("vo") != g_variant_get_type (response)) {
g_warning ("invalid OpenSession() response from daemon with signature: %s",
g_variant_get_type_string (response));
sig = g_variant_get_type_string (response);
g_return_val_if_fail (sig != NULL, FALSE);
if (!g_str_equal (sig, "(vo)")) {
g_warning ("invalid OpenSession() response from daemon with signature: %s", sig);
return FALSE;
}
g_assert (session->path == NULL);
g_variant_get (response, "vo", &argument, &session->path);
g_variant_get (response, "(vo)", &argument, &session->path);
buffer = g_variant_get_fixed_array (argument, &n_buffer, sizeof (guchar));
gcry = gcry_mpi_scan (&peer, GCRYMPI_FMT_USG, buffer, n_buffer, NULL);
@ -232,6 +261,7 @@ response_open_session_aes (GSecretSession *session,
g_return_val_if_reached (FALSE);
egg_secure_free (ikm);
session->algorithms = ALGORITHMS_AES;
return TRUE;
}
@ -241,7 +271,7 @@ static GVariant *
request_open_session_plain (GSecretSession *session)
{
GVariant *argument = g_variant_new_string ("");
return g_variant_new ("sv", "plain", argument);
return g_variant_new ("(sv)", "plain", argument);
}
static gboolean
@ -249,20 +279,25 @@ response_open_session_plain (GSecretSession *session,
GVariant *response)
{
GVariant *argument;
const gchar *sig;
if (G_VARIANT_TYPE ("vo") != g_variant_get_type (response)) {
sig = g_variant_get_type_string (response);
g_return_val_if_fail (sig != NULL, FALSE);
if (!g_str_equal (sig, "(vo)")) {
g_warning ("invalid OpenSession() response from daemon with signature: %s",
g_variant_get_type_string (response));
return FALSE;
}
g_assert (session->path == NULL);
g_variant_get (response, "vo", &argument, &session->path);
g_variant_get (response, "(vo)", &argument, &session->path);
g_variant_unref (argument);
g_assert (session->key == NULL);
g_assert (session->n_key == 0);
session->algorithms = ALGORITHMS_PLAIN;
return TRUE;
}
@ -395,7 +430,7 @@ gsecret_service_ensure_session (GSecretService *self,
closure = g_new (OpenSessionClosure, 1);
closure->cancellable = cancellable ? g_object_ref (cancellable) : cancellable;
closure->session = g_new (GSecretSession, 1);
closure->session = g_new0 (GSecretSession, 1);
g_simple_async_result_set_op_res_gpointer (res, closure, open_session_closure_free);
g_dbus_proxy_call (G_DBUS_PROXY (self), "OpenSession",

View File

@ -72,6 +72,10 @@ GSecretService * gsecret_service_instance_sync (GDBusConnection *c
GError **error);
#endif
const gchar * gsecret_service_get_session_algorithms (GSecretService *self);
const gchar * gsecret_service_get_session_path (GSecretService *self);
void gsecret_service_ensure_session (GSecretService *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,

View File

@ -0,0 +1,7 @@
#!/usr/bin/env python
import mock
service = mock.SecretService()
service.algorithms = { "plain": mock.PlainAlgorithm() }
service.listen()

View File

@ -31,6 +31,10 @@ class NotSupported(dbus.exceptions.DBusException):
def __init__(self, msg):
dbus.exceptions.DBusException.__init__(self, msg, name="org.freedesktop.DBus.Error.NotSupported")
class InvalidArgs(dbus.exceptions.DBusException):
def __init__(self, msg):
dbus.exceptions.DBusException.__init__(self, msg, name="org.freedesktop.DBus.Error.InvalidArgs")
unique_identifier = 0
def next_identifier():
global unique_identifier
@ -39,11 +43,15 @@ def next_identifier():
class PlainAlgorithm():
def negotiate(self, service, sender, param):
if type (param) != dbus.String:
raise InvalidArgs("invalid argument passed to OpenSession")
session = SecretSession(service, sender, None)
return (dbus.String("", variant_level=1), session)
class AesAlgorithm():
def negotiate(self, service, sender, param):
if type (param) != dbus.ByteArray:
raise InvalidArgs("invalid argument passed to OpenSession")
publi, privat = dh.generate_pair()
peer = dh.bytes_to_number(param)
ikm = dh.derive_key(privat, peer)
@ -72,9 +80,11 @@ class SecretService(dbus.service.Object):
"dh-ietf1024-sha256-aes128-cbc-pkcs7": AesAlgorithm(),
}
def __init__(self, name=bus_name):
bus = bus = dbus.SessionBus()
self.bus_name = dbus.service.BusName(name)
def __init__(self, name=None):
if name == None:
name = bus_name
bus = dbus.SessionBus()
self.bus_name = dbus.service.BusName(name, allow_replacement=True, replace_existing=True)
dbus.service.Object.__init__(self, self.bus_name, '/org/freedesktop/secrets')
self.sessions = { }
@ -102,7 +112,6 @@ class SecretService(dbus.service.Object):
@dbus.service.method('org.freedesktop.Secret.Service', byte_arrays=True, sender_keyword='sender')
def OpenSession(self, algorithm, param, sender=None):
assert type(algorithm) == dbus.String
assert type(param) == dbus.ByteArray
if algorithm not in self.algorithms:
raise NotSupported("algorithm %s is not supported" % algorithm)

View File

@ -17,6 +17,8 @@
#include "gsecret-service.h"
#include "gsecret-private.h"
#include "egg/egg-testing.h"
#include <glib.h>
#include <errno.h>
@ -31,18 +33,20 @@ typedef struct {
} Test;
static void
setup_normal (Test *test,
gconstpointer unused)
setup (Test *test,
gconstpointer data)
{
GError *error = NULL;
const gchar *mock_script = data;
gchar *argv[] = {
"python", "./mock-service-normal.py",
"python", (gchar *)mock_script,
"--name", MOCK_NAME,
NULL
};
g_spawn_async (SRCDIR, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &test->pid, &error);
g_assert_no_error (error);
g_usleep (100 * 1000);
test->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
g_assert_no_error (error);
@ -64,16 +68,130 @@ teardown (Test *test,
}
static void
test_ensure_sync (Test *test,
gconstpointer unused)
test_ensure (Test *test,
gconstpointer unused)
{
GError *error = NULL;
const gchar *path;
g_assert_cmpstr (gsecret_service_get_session_path (test->service), ==, NULL);
g_assert_cmpstr (gsecret_service_get_session_algorithms (test->service), ==, NULL);
path = gsecret_service_ensure_session_sync (test->service, NULL, &error);
g_assert_no_error (error);
g_assert (path != NULL);
g_printerr ("%s", path);
g_assert_cmpstr (gsecret_service_get_session_path (test->service), ==, path);
g_assert_cmpstr (gsecret_service_get_session_algorithms (test->service), ==, "dh-ietf1024-sha256-aes128-cbc-pkcs7");
}
static void
test_ensure_twice (Test *test,
gconstpointer unused)
{
GError *error = NULL;
const gchar *path;
g_assert_cmpstr (gsecret_service_get_session_path (test->service), ==, NULL);
g_assert_cmpstr (gsecret_service_get_session_algorithms (test->service), ==, NULL);
path = gsecret_service_ensure_session_sync (test->service, NULL, &error);
g_assert_no_error (error);
g_assert (path != NULL);
g_assert_cmpstr (gsecret_service_get_session_path (test->service), ==, path);
g_assert_cmpstr (gsecret_service_get_session_algorithms (test->service), ==, "dh-ietf1024-sha256-aes128-cbc-pkcs7");
path = gsecret_service_ensure_session_sync (test->service, NULL, &error);
g_assert_no_error (error);
g_assert (path != NULL);
g_assert_cmpstr (gsecret_service_get_session_path (test->service), ==, path);
g_assert_cmpstr (gsecret_service_get_session_algorithms (test->service), ==, "dh-ietf1024-sha256-aes128-cbc-pkcs7");
}
static void
test_ensure_plain (Test *test,
gconstpointer unused)
{
GError *error = NULL;
const gchar *path;
g_assert_cmpstr (gsecret_service_get_session_path (test->service), ==, NULL);
g_assert_cmpstr (gsecret_service_get_session_algorithms (test->service), ==, NULL);
path = gsecret_service_ensure_session_sync (test->service, NULL, &error);
g_assert_no_error (error);
g_assert (path != NULL);
g_assert_cmpstr (gsecret_service_get_session_path (test->service), ==, path);
g_assert_cmpstr (gsecret_service_get_session_algorithms (test->service), ==, "plain");
}
static void
on_complete_get_result (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GAsyncResult **ret = user_data;
g_assert (ret != NULL);
g_assert (*ret == NULL);
*ret = g_object_ref (result);
}
static void
test_ensure_async (Test *test,
gconstpointer unused)
{
GAsyncResult *result = NULL;
GError *error = NULL;
const gchar *path;
gsecret_service_ensure_session (test->service, NULL, on_complete_get_result, &result);
egg_test_wait_until (500);
g_assert (G_IS_ASYNC_RESULT (result));
path = gsecret_service_ensure_session_finish (test->service, result, &error);
g_assert_no_error (error);
g_assert (path != NULL);
g_assert_cmpstr (gsecret_service_get_session_path (test->service), ==, path);
g_assert_cmpstr (gsecret_service_get_session_algorithms (test->service), ==, "plain");
g_object_unref (result);
}
static void
test_ensure_async_twice (Test *test,
gconstpointer unused)
{
GAsyncResult *result = NULL;
GError *error = NULL;
const gchar *path;
gsecret_service_ensure_session (test->service, NULL, on_complete_get_result, &result);
egg_test_wait_until (500);
g_assert (G_IS_ASYNC_RESULT (result));
path = gsecret_service_ensure_session_finish (test->service, result, &error);
g_assert_no_error (error);
g_assert (path != NULL);
g_assert_cmpstr (gsecret_service_get_session_path (test->service), ==, path);
g_assert_cmpstr (gsecret_service_get_session_algorithms (test->service), ==, "plain");
g_object_unref (result);
result = NULL;
gsecret_service_ensure_session (test->service, NULL, on_complete_get_result, &result);
egg_test_wait_until (500);
g_assert (G_IS_ASYNC_RESULT (result));
path = gsecret_service_ensure_session_finish (test->service, result, &error);
g_assert_no_error (error);
g_assert (path != NULL);
g_assert_cmpstr (gsecret_service_get_session_path (test->service), ==, path);
g_assert_cmpstr (gsecret_service_get_session_algorithms (test->service), ==, "plain");
g_object_unref (result);
}
int
@ -83,7 +201,11 @@ main (int argc, char **argv)
g_set_prgname ("test-session");
g_type_init ();
g_test_add ("/session/ensure-sync", Test, NULL, setup_normal, test_ensure_sync, teardown);
g_test_add ("/session/ensure-aes", Test, "mock-service-normal.py", setup, test_ensure, teardown);
g_test_add ("/session/ensure-twice", Test, "mock-service-normal.py", setup, test_ensure_twice, teardown);
g_test_add ("/session/ensure-plain", Test, "mock-service-only-plain.py", setup, test_ensure_plain, teardown);
g_test_add ("/session/ensure-async", Test, "mock-service-only-plain.py", setup, test_ensure_async, teardown);
g_test_add ("/session/ensure-async-twice", Test, "mock-service-only-plain.py", setup, test_ensure_async_twice, teardown);
return g_test_run ();
return egg_tests_run_in_thread_with_loop ();
}

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-09-25 21:16+0200\n"
"POT-Creation-Date: 2011-09-25 22:56+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -22,8 +22,8 @@ msgstr ""
msgid "Received invalid secret from the secret storage"
msgstr ""
#: ../library/gsecret-service.c:308 ../library/gsecret-service.c:348
#: ../library/gsecret-service.c:508
#: ../library/gsecret-service.c:343 ../library/gsecret-service.c:383
#: ../library/gsecret-service.c:543
#, c-format
msgid "Couldn't communicate with the secret storage"
msgstr ""