[libsecret] tool: Add a 'search' command for looking up items and details
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsecret] tool: Add a 'search' command for looking up items and details
- Date: Mon, 18 Feb 2013 14:22:39 +0000 (UTC)
commit 3b84dce476d353fcec6d91f796a6c778e6617d83
Author: Stef Walter <stefw gnome org>
Date: Fri Feb 15 14:18:50 2013 +0100
tool: Add a 'search' command for looking up items and details
The output format is meant to be parseable in the Desktop file format.
Update the documentation as well.
https://bugzilla.gnome.org/show_bug.cgi?id=693881
docs/man/secret-tool.xml | 28 ++++++++
tool/secret-tool.c | 160 ++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 182 insertions(+), 6 deletions(-)
---
diff --git a/docs/man/secret-tool.xml b/docs/man/secret-tool.xml
index 452db63..65508b5 100644
--- a/docs/man/secret-tool.xml
+++ b/docs/man/secret-tool.xml
@@ -39,6 +39,9 @@
<cmdsynopsis>
<command>secret-tool clear <arg choice="req">attribute</arg> <arg
choice="req">value</arg> ...</command>
</cmdsynopsis>
+ <cmdsynopsis>
+ <command>secret-tool search <arg choice="opt">--all</arg><arg
choice="req">attribute</arg> <arg choice="req">value</arg> ...</command>
+ </cmdsynopsis>
</refsynopsisdiv>
<refsect1>
@@ -106,6 +109,31 @@
</refsect1>
<refsect1>
+ <title>Search</title>
+
+ <para>This command searches for and prints details on matching
+ items in secret service. Specify the same attribute and value
+ pairs that you passed in when storing the password. You can use the
+ following options:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>--all</option></term>
+ <listitem><para>Return all matching results, rather than
+ just the one of the matches. Without this option, the
+ first unlocked match returned from the service will
+ be printed.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>--unlock</option></term>
+ <listitem><para>Unlock items that are locked and then
+ print out their details. Without this option, locked items
+ are skipped.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
<title>Exit status</title>
<para>On success 0 is returned, a non-zero failure code otherwise.</para>
diff --git a/tool/secret-tool.c b/tool/secret-tool.c
index 9f88ef5..0a1350f 100644
--- a/tool/secret-tool.c
+++ b/tool/secret-tool.c
@@ -14,6 +14,7 @@
#include "config.h"
+#include "secret-item.h"
#include "secret-password.h"
#include "secret-service.h"
#include "secret-value.h"
@@ -24,6 +25,7 @@
#include <locale.h>
#include <limits.h>
#include <stdlib.h>
+#include <string.h>
#define SECRET_ALIAS_PREFIX "/org/freedesktop/secrets/aliases/"
@@ -66,6 +68,7 @@ usage (void)
g_printerr ("usage: secret-tool store --label='label' attribute value ...\n");
g_printerr (" secret-tool lookup attribute value ...\n");
g_printerr (" secret-tool clear attribute value ...\n");
+ g_printerr (" secret-tool search [--all] [--details] attribute value ...\n");
exit (2);
}
@@ -150,17 +153,12 @@ secret_tool_action_clear (int argc,
}
static void
-write_password_stdout (SecretValue *value)
+write_password_data (SecretValue *value)
{
const gchar *at;
gsize length;
int r;
- if (!is_password_value (value)) {
- g_printerr ("%s: secret does not contain a textual password\n", g_get_prgname ());
- exit (1);
- }
-
at = secret_value_get (value, &length);
while (length > 0) {
@@ -176,6 +174,17 @@ write_password_stdout (SecretValue *value)
length -= r;
}
}
+}
+
+static void
+write_password_stdout (SecretValue *value)
+{
+ if (!is_password_value (value)) {
+ g_printerr ("%s: secret does not contain a textual password\n", g_get_prgname ());
+ exit (1);
+ }
+
+ write_password_data (value);
/* Add a new line if we're writing out to a tty */
if (isatty (1))
@@ -331,6 +340,143 @@ secret_tool_action_store (int argc,
return 0;
}
+static void
+print_item_when (const char *field,
+ guint64 when)
+{
+ GDateTime *dt;
+ gchar *value;
+
+ if (!when) {
+ value = g_strdup ("");
+ } else {
+ dt = g_date_time_new_from_unix_utc (when);
+ value = g_date_time_format (dt, "%Y-%m-%d %H:%M:%S");
+ g_date_time_unref (dt);
+ }
+
+ g_print ("%s = %s\n", field, value);
+ g_free (value);
+}
+
+static void
+print_item_details (SecretItem *item)
+{
+ SecretValue *secret;
+ GHashTableIter iter;
+ GHashTable *attributes;
+ gchar *value, *key;
+ guint64 when;
+ const gchar *part;
+ const gchar *path;
+
+ path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (item));
+ g_return_if_fail (path != NULL);
+
+ /* The item identifier */
+ part = strrchr (path, '/');
+ if (part == NULL)
+ part = path;
+ g_print ("[%s]\n", path);
+
+ /* The label */
+ value = secret_item_get_label (item);
+ g_print ("label = %s\n", value);
+ g_free (value);
+
+ /* The secret value */
+ secret = secret_item_get_secret (item);
+ g_print ("secret = ");
+ if (secret != NULL) {
+ write_password_data (secret);
+ secret_value_unref (secret);
+ }
+ g_print ("\n");
+
+ /* The dates */
+ when = secret_item_get_created (item);
+ print_item_when ("created", when);
+ when = secret_item_get_modified (item);
+ print_item_when ("modified", when);
+
+ /* The schema */
+ value = secret_item_get_schema_name (item);
+ g_print ("schema = %s\n", value);
+ g_free (value);
+
+ /* The attributes */
+ attributes = secret_item_get_attributes (item);
+ g_hash_table_iter_init (&iter, attributes);
+ while (g_hash_table_iter_next (&iter, (void **)&key, (void **)&value)) {
+ if (strcmp (key, "xdg:schema") != 0)
+ g_printerr ("attribute.%s = %s\n", key, value);
+ }
+ g_hash_table_unref (attributes);
+}
+
+static int
+secret_tool_action_search (int argc,
+ char *argv[])
+{
+ GError *error = NULL;
+ GOptionContext *context;
+ SecretService *service;
+ GHashTable *attributes;
+ SecretSearchFlags flags;
+ gboolean flag_all = FALSE;
+ gboolean flag_unlock = FALSE;
+ GList *items, *l;
+
+ /* secret-tool lookup name xxxx yyyy zzzz */
+ const GOptionEntry lookup_options[] = {
+ { "all", 'a', 0, G_OPTION_ARG_NONE, &flag_all,
+ N_("return all results, instead of just first one"), NULL },
+ { "unlock", 'a', 0, G_OPTION_ARG_NONE, &flag_unlock,
+ N_("unlock item results if necessary"), NULL },
+ { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &attribute_args,
+ N_("attribute value pairs of item to lookup"), NULL },
+ { NULL }
+ };
+
+ context = g_option_context_new ("attribute value ...");
+ g_option_context_add_main_entries (context, lookup_options, GETTEXT_PACKAGE);
+ if (!g_option_context_parse (context, &argc, &argv, &error)) {
+ g_printerr ("%s\n", error->message);
+ usage();
+ }
+
+ g_option_context_free (context);
+
+ attributes = attributes_from_arguments (attribute_args);
+ g_strfreev (attribute_args);
+
+ service = secret_service_get_sync (SECRET_SERVICE_NONE, NULL, &error);
+ if (error == NULL) {
+ flags = SECRET_SEARCH_LOAD_SECRETS;
+ if (flag_all)
+ flags |= SECRET_SEARCH_ALL;
+ if (flag_unlock)
+ flags |= SECRET_SEARCH_UNLOCK;
+ items = secret_service_search_sync (service, NULL, attributes, flags, NULL, &error);
+ if (error == NULL) {
+ for (l = items; l != NULL; l = g_list_next (l))
+ print_item_details (l->data);
+ g_list_free_full (items, g_object_unref);
+ }
+
+ g_object_unref (service);
+ }
+
+ g_hash_table_unref (attributes);
+
+ if (error != NULL) {
+ g_printerr ("%s: %s\n", g_get_prgname (), error->message);
+ return 1;
+ }
+
+ return 0;
+}
+
int
main (int argc,
char *argv[])
@@ -358,6 +504,8 @@ main (int argc,
action = secret_tool_action_lookup;
} else if (g_str_equal (argv[1], "clear")) {
action = secret_tool_action_clear;
+ } else if (g_str_equal (argv[1], "search")) {
+ action = secret_tool_action_search;
} else {
usage ();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]