mirror of
https://gitlab.gnome.org/GNOME/libsecret.git
synced 2024-12-22 12:48:51 +00:00
secret-tool: Add tests for secret-tool using file backend
This commit is contained in:
parent
baedede55c
commit
e22eb7d540
@ -52,7 +52,10 @@ dist-hook: dist-check-valac
|
|||||||
distcleancheck_listfiles = \
|
distcleancheck_listfiles = \
|
||||||
find . -name '*.gc[dn][oa]' -prune -o -type f -print
|
find . -name '*.gc[dn][oa]' -prune -o -type f -print
|
||||||
|
|
||||||
TESTS_ENVIRONMENT = LD_LIBRARY_PATH=$(builddir)/.libs GI_TYPELIB_PATH=$(builddir)
|
TESTS_ENVIRONMENT = \
|
||||||
|
LD_LIBRARY_PATH=$(builddir)/.libs \
|
||||||
|
GI_TYPELIB_PATH=$(builddir) \
|
||||||
|
abs_top_builddir=$(abs_top_builddir)
|
||||||
TEST_EXTENSIONS = .py .js
|
TEST_EXTENSIONS = .py .js
|
||||||
|
|
||||||
# Default executable tests
|
# Default executable tests
|
||||||
|
@ -149,17 +149,24 @@ backend_get_impl_type (void)
|
|||||||
GIOExtension *e;
|
GIOExtension *e;
|
||||||
GIOExtensionPoint *ep;
|
GIOExtensionPoint *ep;
|
||||||
|
|
||||||
envvar = g_getenv ("SECRET_BACKEND");
|
|
||||||
if (envvar == NULL || *envvar == '\0')
|
|
||||||
extension_name = "service";
|
|
||||||
else
|
|
||||||
extension_name = envvar;
|
|
||||||
|
|
||||||
g_type_ensure (secret_service_get_type ());
|
g_type_ensure (secret_service_get_type ());
|
||||||
#ifdef WITH_GCRYPT
|
#ifdef WITH_GCRYPT
|
||||||
g_type_ensure (secret_file_backend_get_type ());
|
g_type_ensure (secret_file_backend_get_type ());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_GCRYPT
|
||||||
|
if (g_file_test ("/.flatpak-info", G_FILE_TEST_EXISTS))
|
||||||
|
extension_name = "file";
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
envvar = g_getenv ("SECRET_BACKEND");
|
||||||
|
if (envvar == NULL || *envvar == '\0')
|
||||||
|
extension_name = "service";
|
||||||
|
else
|
||||||
|
extension_name = envvar;
|
||||||
|
}
|
||||||
|
|
||||||
ep = g_io_extension_point_lookup (SECRET_BACKEND_EXTENSION_POINT_NAME);
|
ep = g_io_extension_point_lookup (SECRET_BACKEND_EXTENSION_POINT_NAME);
|
||||||
e = g_io_extension_point_get_extension_by_name (ep, extension_name);
|
e = g_io_extension_point_get_extension_by_name (ep, extension_name);
|
||||||
if (e == NULL) {
|
if (e == NULL) {
|
||||||
|
@ -21,6 +21,14 @@
|
|||||||
#include "secret-private.h"
|
#include "secret-private.h"
|
||||||
#include "secret-retrievable.h"
|
#include "secret-retrievable.h"
|
||||||
|
|
||||||
|
#include "egg/egg-secure-memory.h"
|
||||||
|
|
||||||
|
EGG_SECURE_DECLARE (secret_file_backend);
|
||||||
|
|
||||||
|
#include <gio/gunixfdlist.h>
|
||||||
|
#include <gio/gunixinputstream.h>
|
||||||
|
#include <glib-unix.h>
|
||||||
|
|
||||||
static void secret_file_backend_async_initable_iface (GAsyncInitableIface *iface);
|
static void secret_file_backend_async_initable_iface (GAsyncInitableIface *iface);
|
||||||
static void secret_file_backend_backend_iface (SecretBackendInterface *iface);
|
static void secret_file_backend_backend_iface (SecretBackendInterface *iface);
|
||||||
|
|
||||||
@ -138,6 +146,158 @@ on_collection_new_async (GObject *source_object,
|
|||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
gint io_priority;
|
||||||
|
GFile *file;
|
||||||
|
GInputStream *stream;
|
||||||
|
gchar *buffer;
|
||||||
|
} InitClosure;
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_closure_free (gpointer data)
|
||||||
|
{
|
||||||
|
InitClosure *init = data;
|
||||||
|
g_object_unref (init->file);
|
||||||
|
g_clear_object (&init->stream);
|
||||||
|
g_clear_pointer (&init->buffer, egg_secure_free);
|
||||||
|
g_slice_free (InitClosure, init);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PASSWORD_SIZE 64
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_read_all (GObject *source_object,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GInputStream *stream = G_INPUT_STREAM (source_object);
|
||||||
|
GTask *task = G_TASK (user_data);
|
||||||
|
InitClosure *init = g_task_get_task_data (task);
|
||||||
|
gsize bytes_read;
|
||||||
|
SecretValue *password;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (!g_input_stream_read_all_finish (stream, result, &bytes_read,
|
||||||
|
&error)) {
|
||||||
|
g_task_return_error (task, error);
|
||||||
|
g_object_unref (task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytes_read != PASSWORD_SIZE) {
|
||||||
|
g_task_return_new_error (task,
|
||||||
|
SECRET_ERROR,
|
||||||
|
SECRET_ERROR_PROTOCOL,
|
||||||
|
"invalid password returned from portal");
|
||||||
|
g_object_unref (task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
password = secret_value_new (init->buffer, bytes_read, "text/plain");
|
||||||
|
g_async_initable_new_async (SECRET_TYPE_FILE_COLLECTION,
|
||||||
|
init->io_priority,
|
||||||
|
g_task_get_cancellable (task),
|
||||||
|
on_collection_new_async,
|
||||||
|
task,
|
||||||
|
"file", init->file,
|
||||||
|
"password", password,
|
||||||
|
NULL);
|
||||||
|
secret_value_unref (password);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_portal_retrieve_secret (GObject *source_object,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GDBusConnection *connection = G_DBUS_CONNECTION (source_object);
|
||||||
|
GTask *task = G_TASK (user_data);
|
||||||
|
InitClosure *init = g_task_get_task_data (task);
|
||||||
|
GVariant *reply;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
reply = g_dbus_connection_call_with_unix_fd_list_finish (connection,
|
||||||
|
NULL,
|
||||||
|
result,
|
||||||
|
&error);
|
||||||
|
if (reply == NULL) {
|
||||||
|
g_task_return_error (task, error);
|
||||||
|
g_object_unref (task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
init->buffer = egg_secure_alloc (PASSWORD_SIZE);
|
||||||
|
|
||||||
|
g_input_stream_read_all_async (init->stream,
|
||||||
|
init->buffer, PASSWORD_SIZE,
|
||||||
|
G_PRIORITY_DEFAULT,
|
||||||
|
g_task_get_cancellable (task),
|
||||||
|
on_read_all,
|
||||||
|
task);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_bus_get (GObject *source_object,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GDBusConnection *connection;
|
||||||
|
GTask *task = G_TASK (user_data);
|
||||||
|
InitClosure *init = g_task_get_task_data (task);
|
||||||
|
GUnixFDList *fd_list;
|
||||||
|
gint fds[2];
|
||||||
|
gint fd_index;
|
||||||
|
GVariantBuilder options;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
connection = g_bus_get_finish (result, &error);
|
||||||
|
if (connection == NULL) {
|
||||||
|
g_task_return_error (task, error);
|
||||||
|
g_object_unref (task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_unix_open_pipe (fds, FD_CLOEXEC, &error)) {
|
||||||
|
g_object_unref (connection);
|
||||||
|
g_task_return_error (task, error);
|
||||||
|
g_object_unref (task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd_list = g_unix_fd_list_new ();
|
||||||
|
fd_index = g_unix_fd_list_append (fd_list, fds[1], &error);
|
||||||
|
close (fds[1]);
|
||||||
|
if (fd_index < 0) {
|
||||||
|
close (fds[0]);
|
||||||
|
g_object_unref (fd_list);
|
||||||
|
g_object_unref (connection);
|
||||||
|
g_task_return_error (task, error);
|
||||||
|
g_object_unref (task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
close (fds[1]);
|
||||||
|
init->stream = g_unix_input_stream_new (fds[0], TRUE);
|
||||||
|
|
||||||
|
g_variant_builder_init (&options, G_VARIANT_TYPE_VARDICT);
|
||||||
|
g_dbus_connection_call_with_unix_fd_list (connection,
|
||||||
|
"org.freedesktop.portal.Desktop",
|
||||||
|
"/org/freedesktop/portal/desktop",
|
||||||
|
"org.freedesktop.portal.Secret",
|
||||||
|
"RetrieveSecret",
|
||||||
|
g_variant_new ("(h@a{sv})",
|
||||||
|
fd_index,
|
||||||
|
g_variant_builder_end (&options)),
|
||||||
|
G_VARIANT_TYPE ("(o)"),
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1,
|
||||||
|
fd_list,
|
||||||
|
g_task_get_cancellable (task),
|
||||||
|
on_portal_retrieve_secret,
|
||||||
|
task);
|
||||||
|
g_object_unref (fd_list);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
secret_file_backend_real_init_async (GAsyncInitable *initable,
|
secret_file_backend_real_init_async (GAsyncInitable *initable,
|
||||||
int io_priority,
|
int io_priority,
|
||||||
@ -152,6 +312,7 @@ secret_file_backend_real_init_async (GAsyncInitable *initable,
|
|||||||
const gchar *envvar;
|
const gchar *envvar;
|
||||||
GTask *task;
|
GTask *task;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
InitClosure *init;
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
|
||||||
task = g_task_new (initable, cancellable, callback, user_data);
|
task = g_task_new (initable, cancellable, callback, user_data);
|
||||||
@ -190,23 +351,27 @@ secret_file_backend_real_init_async (GAsyncInitable *initable,
|
|||||||
}
|
}
|
||||||
|
|
||||||
envvar = g_getenv ("SECRET_FILE_TEST_PASSWORD");
|
envvar = g_getenv ("SECRET_FILE_TEST_PASSWORD");
|
||||||
if (envvar != NULL && *envvar != '\0')
|
if (envvar != NULL && *envvar != '\0') {
|
||||||
password = secret_value_new (envvar, -1, "text/plain");
|
password = secret_value_new (envvar, -1, "text/plain");
|
||||||
else {
|
g_async_initable_new_async (SECRET_TYPE_FILE_COLLECTION,
|
||||||
|
io_priority,
|
||||||
|
cancellable,
|
||||||
|
on_collection_new_async,
|
||||||
|
task,
|
||||||
|
"file", file,
|
||||||
|
"password", password,
|
||||||
|
NULL);
|
||||||
|
g_object_unref (file);
|
||||||
|
secret_value_unref (password);
|
||||||
|
} else if (g_file_test ("/.flatpak-info", G_FILE_TEST_EXISTS)) {
|
||||||
|
init = g_slice_new0 (InitClosure);
|
||||||
|
init->io_priority = io_priority;
|
||||||
|
init->file = file;
|
||||||
|
g_task_set_task_data (task, init, init_closure_free);
|
||||||
|
g_bus_get (G_BUS_TYPE_SESSION, cancellable, on_bus_get, task);
|
||||||
|
} else {
|
||||||
g_error ("master password is not retrievable");
|
g_error ("master password is not retrievable");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_async_initable_new_async (SECRET_TYPE_FILE_COLLECTION,
|
|
||||||
io_priority,
|
|
||||||
cancellable,
|
|
||||||
on_collection_new_async,
|
|
||||||
task,
|
|
||||||
"file", file,
|
|
||||||
"password", password,
|
|
||||||
NULL);
|
|
||||||
g_object_unref (file);
|
|
||||||
secret_value_unref (password);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -81,6 +81,10 @@ conf.set('_DEBUG', enable_debug)
|
|||||||
conf.set('HAVE_MLOCK', meson.get_compiler('c').has_function('mlock'))
|
conf.set('HAVE_MLOCK', meson.get_compiler('c').has_function('mlock'))
|
||||||
configure_file(output: 'config.h', configuration: conf)
|
configure_file(output: 'config.h', configuration: conf)
|
||||||
|
|
||||||
|
# Test environment
|
||||||
|
test_env = environment()
|
||||||
|
test_env.set('abs_top_builddir', meson.source_root())
|
||||||
|
|
||||||
# Subfolders
|
# Subfolders
|
||||||
subdir('po')
|
subdir('po')
|
||||||
subdir('egg')
|
subdir('egg')
|
||||||
|
@ -5,3 +5,7 @@ secret_tool_SOURCES = \
|
|||||||
|
|
||||||
secret_tool_LDADD = \
|
secret_tool_LDADD = \
|
||||||
libsecret-@SECRET_MAJOR@.la
|
libsecret-@SECRET_MAJOR@.la
|
||||||
|
|
||||||
|
if WITH_GCRYPT
|
||||||
|
TESTS += tool/test-secret-tool.sh
|
||||||
|
endif
|
||||||
|
@ -9,3 +9,9 @@ secret_tool = executable('secret-tool',
|
|||||||
c_args: libsecret_cflags,
|
c_args: libsecret_cflags,
|
||||||
install: true,
|
install: true,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if with_gcrypt and host_machine.system() != 'windows'
|
||||||
|
test('test-secret-tool.sh',
|
||||||
|
find_program('test-secret-tool.sh'),
|
||||||
|
env: test_env)
|
||||||
|
endif
|
||||||
|
102
tool/test-secret-tool.sh
Executable file
102
tool/test-secret-tool.sh
Executable file
@ -0,0 +1,102 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
testdir=$PWD/test-secret-tool-$$
|
||||||
|
test -d "$testdir" || mkdir "$testdir"
|
||||||
|
|
||||||
|
cleanup () {
|
||||||
|
rm -rf "$testdir"
|
||||||
|
}
|
||||||
|
trap cleanup 0
|
||||||
|
|
||||||
|
cd "$testdir"
|
||||||
|
|
||||||
|
SECRET_BACKEND=file
|
||||||
|
export SECRET_BACKEND
|
||||||
|
|
||||||
|
SECRET_FILE_TEST_PATH=$testdir/keyring
|
||||||
|
export SECRET_FILE_TEST_PATH
|
||||||
|
|
||||||
|
SECRET_FILE_TEST_PASSWORD=test
|
||||||
|
export SECRET_FILE_TEST_PASSWORD
|
||||||
|
|
||||||
|
: ${DIFF=diff}
|
||||||
|
|
||||||
|
echo 1..4
|
||||||
|
|
||||||
|
echo test1 | "$abs_top_builddir"/secret-tool store --label label1 foo bar
|
||||||
|
if test $? -eq 0; then
|
||||||
|
echo "ok 1 /secret-tool/store"
|
||||||
|
else
|
||||||
|
echo "not ok 1 /secret-tool/store"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo test2 | "$abs_top_builddir"/secret-tool store --label label2 foo bar apple orange
|
||||||
|
if test $? -eq 0; then
|
||||||
|
echo "ok 1 /secret-tool/store"
|
||||||
|
else
|
||||||
|
echo "not ok 1 /secret-tool/store"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo test1 > lookup.exp
|
||||||
|
"$abs_top_builddir"/secret-tool lookup foo bar > lookup.out
|
||||||
|
if ${DIFF} lookup.exp lookup.out > lookup.diff; then
|
||||||
|
echo "ok 2 /secret-tool/lookup"
|
||||||
|
else
|
||||||
|
echo "not ok 2 /secret-tool/lookup"
|
||||||
|
sed 's/^/# /' lookup.diff
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat > search.exp <<EOF
|
||||||
|
[no path]
|
||||||
|
label = label1
|
||||||
|
secret = test1
|
||||||
|
|
||||||
|
[no path]
|
||||||
|
label = label2
|
||||||
|
secret = test2
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
"$abs_top_builddir"/secret-tool search foo bar | sed '/^created\|^modified/d' > search.out
|
||||||
|
if test $? -ne 0; then
|
||||||
|
echo "not ok 3 /secret-tool/search"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ${DIFF} search.exp search.out > search.diff; then
|
||||||
|
echo "ok 3 /secret-tool/search"
|
||||||
|
else
|
||||||
|
echo "not ok 3 /secret-tool/search"
|
||||||
|
sed 's/^/# /' search.diff
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$abs_top_builddir"/secret-tool clear apple orange
|
||||||
|
if test $? -eq 0; then
|
||||||
|
echo "ok 4 /secret-tool/clear"
|
||||||
|
else
|
||||||
|
echo "not ok 4 /secret-tool/clear"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat > search-after-clear.exp <<EOF
|
||||||
|
[no path]
|
||||||
|
label = label1
|
||||||
|
secret = test1
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
"$abs_top_builddir"/secret-tool search foo bar | sed '/^created\|^modified/d' > search-after-clear.out
|
||||||
|
if test $? -ne 0; then
|
||||||
|
echo "not ok 5 /secret-tool/search-after-clear"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ${DIFF} search-after-clear.exp search-after-clear.out > search-after-clear.diff; then
|
||||||
|
echo "ok 5 /secret-tool/search-after-clear"
|
||||||
|
else
|
||||||
|
echo "not ok 5 /secret-tool/search-after-clear"
|
||||||
|
sed 's/^/# /' search-after-clear.diff
|
||||||
|
exit 1
|
||||||
|
fi
|
Loading…
Reference in New Issue
Block a user