diff --git a/tool/secret-tool.c b/tool/secret-tool.c index 9335e37..642d9c0 100644 --- a/tool/secret-tool.c +++ b/tool/secret-tool.c @@ -18,6 +18,8 @@ #include "libsecret/secret-password.h" #include "libsecret/secret-retrievable.h" #include "libsecret/secret-value.h" +#include "libsecret/secret-service.h" +#include "libsecret/secret-paths.h" #include @@ -28,6 +30,7 @@ #include #define SECRET_ALIAS_PREFIX "/org/freedesktop/secrets/aliases/" +#define SECRET_COLLECTION_PREFIX "/org/freedesktop/secrets/collection/" static gchar **attribute_args = NULL; static gchar *store_label = NULL; @@ -58,6 +61,13 @@ static const GOptionEntry CLEAR_OPTIONS[] = { { NULL } }; +/* secret-tool lock collections="xxxx" */ +static const GOptionEntry COLLECTION_OPTIONS[] = { + { "collection", 'c', 0, G_OPTION_ARG_STRING, &store_collection, + N_("collection in which to lock"), NULL }, + { NULL } +}; + typedef int (* SecretToolAction) (int argc, char *argv[]); static void usage (void) G_GNUC_NORETURN; @@ -69,6 +79,7 @@ usage (void) g_printerr (" secret-tool lookup attribute value ...\n"); g_printerr (" secret-tool clear attribute value ...\n"); g_printerr (" secret-tool search [--all] [--unlock] attribute value ...\n"); + g_printerr (" secret-tool lock --collection='collection'\n"); exit (2); } @@ -493,6 +504,61 @@ secret_tool_action_search (int argc, return 0; } +static int +secret_tool_action_lock (int argc, + char *argv[]) +{ + GError *error = NULL; + GList *locked = NULL; + GOptionContext *context; + g_autofree gchar *collection_path = NULL; + g_autolist (GList) collections = NULL; + g_autoptr (SecretService) service = NULL; + g_autoptr (SecretCollection) collection = NULL; + + service = secret_service_get_sync (SECRET_SERVICE_LOAD_COLLECTIONS, NULL, &error); + if (error != NULL) { + g_printerr ("%s: %s\n", g_get_prgname (), error->message); + g_error_free (error); + return 1; + } + + context = g_option_context_new ("collections"); + g_option_context_add_main_entries (context, COLLECTION_OPTIONS, GETTEXT_PACKAGE); + g_option_context_parse (context, &argc, &argv, &error); + + if (store_collection) { + + collection_path = g_strconcat (SECRET_COLLECTION_PREFIX, store_collection, NULL); + collection = secret_collection_new_for_dbus_path_sync (service, collection_path, SECRET_COLLECTION_NONE, NULL, &error); + g_free (store_collection); + g_free (collection_path); + + if (error != NULL) { + g_printerr ("%s: %s\n", g_get_prgname (), error->message); + g_error_free (error); + return 1; + } + + if (secret_collection_get_locked (collection) || collection == NULL) { + return 1; + } + + collections = g_list_append (collections, collection); + } else { + collections = secret_service_get_collections (service); + } + + secret_service_lock_sync (NULL, collections, 0, &locked, &error); + if (error != NULL) { + g_printerr ("%s: %s\n", g_get_prgname (), error->message); + g_error_free (error); + return 1; + } + + return 0; +} + int main (int argc, char *argv[]) @@ -518,6 +584,8 @@ main (int argc, action = secret_tool_action_clear; } else if (g_str_equal (argv[1], "search")) { action = secret_tool_action_search; + } else if (g_str_equal (argv[1], "lock")) { + action = secret_tool_action_lock; } else { usage (); }