aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sm/ChangeLog5
-rw-r--r--sm/keylist.c62
-rw-r--r--sm/server.c77
3 files changed, 119 insertions, 25 deletions
diff --git a/sm/ChangeLog b/sm/ChangeLog
index 756cb45f8..5b97cf13c 100644
--- a/sm/ChangeLog
+++ b/sm/ChangeLog
@@ -1,5 +1,10 @@
2002-03-06 Werner Koch <[email protected]>
+ * server.c (cmd_listkeys, cmd_listsecretkeys): Divert to
+ (do_listkeys): new. Add pattern parsing.
+
+ * keylist.c (gpgsm_list_keys): Handle selection pattern.
+
* gpgsm.c: New command --learn-card
* call-agent.c (learn_cb,gpgsm_agent_learn): New.
diff --git a/sm/keylist.c b/sm/keylist.c
index 0c8416810..6c57897de 100644
--- a/sm/keylist.c
+++ b/sm/keylist.c
@@ -227,28 +227,68 @@ void
gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
{
KEYDB_HANDLE hd;
+ KEYDB_SEARCH_DESC *desc = NULL;
+ STRLIST sl;
+ int ndesc;
KsbaCert cert = NULL;
int rc=0;
const char *lastresname, *resname;
int have_secret;
-#warning there is no key selection yet
- /* We must take care of quoting here */
hd = keydb_new (0);
if (!hd)
- rc = GNUPG_General_Error;
+ {
+ log_error ("keydb_new failed\n");
+ goto leave;
+ }
+
+ if (!names)
+ ndesc = 1;
else
- rc = keydb_search_first (hd);
- if (rc)
{
- if (rc != -1)
- log_error ("keydb_search_first failed: %s\n", gnupg_strerror (rc) );
+ for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++)
+ ;
+ }
+
+ desc = xtrycalloc (ndesc, sizeof *desc);
+ if (!ndesc)
+ {
+ log_error ("out of core\n");
goto leave;
}
+ if (!names)
+ desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
+ else
+ {
+ for (ndesc=0, sl=names; sl; sl = sl->next)
+ {
+ rc = keydb_classify_name (sl->d, desc+ndesc);
+ if (rc)
+ {
+ log_error ("key `%s' not found: %s\n",
+ sl->d, gnupg_strerror (rc));
+ rc = 0;
+ }
+ else
+ ndesc++;
+ }
+
+ }
+
+ /* it would be nice to see which of the given users did actually
+ match one in the keyring. To implement this we need to have a
+ found flag for each entry in desc and to set this we must check
+ all those entries after a match to mark all matched one -
+ currently we stop at the first match. To do this we need an
+ extra flag to enable this feature so */
+
lastresname = NULL;
- do
+ while (!(rc = keydb_search (hd, desc, ndesc)))
{
+ if (!names)
+ desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
+
rc = keydb_get_cert (hd, &cert);
if (rc)
{
@@ -296,12 +336,14 @@ gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
ksba_cert_release (cert);
cert = NULL;
}
- while (!(rc = keydb_search_next (hd)));
if (rc && rc != -1)
- log_error ("keydb_search_next failed: %s\n", gnupg_strerror (rc));
+ log_error ("keydb_search failed: %s\n", gnupg_strerror (rc));
leave:
ksba_cert_release (cert);
+ xfree (desc);
keydb_release (hd);
}
+
+
diff --git a/sm/server.c b/sm/server.c
index 065fc5acc..856eb56be 100644
--- a/sm/server.c
+++ b/sm/server.c
@@ -42,6 +42,32 @@ struct server_local_s {
CERTLIST recplist;
};
+
+
+/* note, that it is sufficient to allocate the target string D as
+ long as the source string S, i.e.: strlen(s)+1; */
+static void
+strcpy_escaped_plus (char *d, const unsigned char *s)
+{
+ while (*s)
+ {
+ if (*s == '%' && s[1] && s[2])
+ {
+ s++;
+ *d++ = xtoi_2 ( s);
+ s += 2;
+ }
+ else if (*s == '+')
+ *d++ = ' ', s++;
+ else
+ *d++ = *s++;
+ }
+ *d = 0;
+}
+
+
+
+
/* Check whether the option NAME appears in LINE */
static int
has_option (const char *line, const char *name)
@@ -370,35 +396,56 @@ cmd_message (ASSUAN_CONTEXT ctx, char *line)
}
-/* Note that the line contains a space separated list of pappern where
- each pappern is percent escaped and spaces may be replaced by
- '+'. */
static int
-cmd_listkeys (ASSUAN_CONTEXT ctx, char *line)
+do_listkeys (ASSUAN_CONTEXT ctx, char *line, int mode)
{
CTRL ctrl = assuan_get_pointer (ctx);
FILE *fp = assuan_get_data_fp (ctx);
+ char *p;
+ STRLIST list, sl;
if (!fp)
return set_error (General_Error, "no data stream");
- ctrl->with_colons = 1;
- gpgsm_list_keys (assuan_get_pointer (ctx), NULL, fp, 3);
+
+ /* break the line down into an STRLIST */
+ list = NULL;
+ for (p=line; *p; line = p)
+ {
+ while (*p && *p != ' ')
+ p++;
+ if (*p)
+ *p++ = 0;
+ if (*line)
+ {
+ sl = xtrymalloc (sizeof *sl + strlen (line));
+ if (!sl)
+ {
+ free_strlist (list);
+ return ASSUAN_Out_Of_Core;
+ }
+ sl->flags = 0;
+ strcpy_escaped_plus (sl->d, line);
+ sl->next = list;
+ list = sl;
+ }
+ }
+ ctrl->with_colons = 1;
+ gpgsm_list_keys (assuan_get_pointer (ctx), list, fp, 3);
+ free_strlist (list);
return 0;
}
static int
-cmd_listsecretkeys (ASSUAN_CONTEXT ctx, char *line)
+cmd_listkeys (ASSUAN_CONTEXT ctx, char *line)
{
- CTRL ctrl = assuan_get_pointer (ctx);
- FILE *fp = assuan_get_data_fp (ctx);
-
- ctrl->with_colons = 1;
- if (!fp)
- return set_error (General_Error, "no data stream");
- gpgsm_list_keys (assuan_get_pointer (ctx), NULL, fp, 2);
+ return do_listkeys (ctx, line, 3);
+}
- return 0;
+static int
+cmd_listsecretkeys (ASSUAN_CONTEXT ctx, char *line)
+{
+ return do_listkeys (ctx, line, 2);
}