aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/userids.c10
-rw-r--r--kbx/kbxserver.c94
-rw-r--r--kbx/keybox-search-desc.h1
3 files changed, 95 insertions, 10 deletions
diff --git a/common/userids.c b/common/userids.c
index 0f03896ee..9d866d583 100644
--- a/common/userids.c
+++ b/common/userids.c
@@ -115,6 +115,7 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
mode = KEYDB_SEARCH_MODE_MAILEND;
s++;
desc->u.name = s;
+ desc->name_used = 1;
break;
case '<': /* An email address. */
@@ -126,24 +127,28 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
if (!openpgp_hack)
s++;
desc->u.name = s;
+ desc->name_used = 1;
break;
case '@': /* Part of an email address. */
mode = KEYDB_SEARCH_MODE_MAILSUB;
s++;
desc->u.name = s;
+ desc->name_used = 1;
break;
case '=': /* Exact compare. */
mode = KEYDB_SEARCH_MODE_EXACT;
s++;
desc->u.name = s;
+ desc->name_used = 1;
break;
case '*': /* Case insensitive substring search. */
mode = KEYDB_SEARCH_MODE_SUBSTR;
s++;
desc->u.name = s;
+ desc->name_used = 1;
break;
case '+': /* Compare individual words. Note that this has not
@@ -151,6 +156,7 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
mode = KEYDB_SEARCH_MODE_WORDS;
s++;
desc->u.name = s;
+ desc->name_used = 1;
break;
case '/': /* Subject's DN. */
@@ -161,6 +167,7 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
goto out;
}
desc->u.name = s;
+ desc->name_used = 1;
mode = KEYDB_SEARCH_MODE_SUBJECT;
break;
@@ -178,6 +185,7 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
goto out;
}
desc->u.name = s;
+ desc->name_used = 1;
mode = KEYDB_SEARCH_MODE_ISSUER;
}
else
@@ -205,6 +213,7 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
goto out;
}
desc->u.name = s;
+ desc->name_used = 1;
mode = KEYDB_SEARCH_MODE_ISSUER_SN;
}
}
@@ -472,6 +481,7 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
if (!mode) /* Default to substring search. */
{
desc->u.name = s;
+ desc->name_used = 1;
mode = KEYDB_SEARCH_MODE_SUBSTR;
}
}
diff --git a/kbx/kbxserver.c b/kbx/kbxserver.c
index 0b76cde31..1949e6278 100644
--- a/kbx/kbxserver.c
+++ b/kbx/kbxserver.c
@@ -46,6 +46,13 @@
/**/: gpg_error (e))
+/* Helper to provide packing memory for search descriptions. */
+struct search_backing_store_s
+{
+ unsigned char *sn;
+ char *name;
+};
+
/* Control structure per connection. */
struct server_local_s
@@ -84,10 +91,13 @@ struct server_local_s
* cmd_search. If more than one pattern is required, cmd_search
* also allocates and sets multi_search_desc and
* multi_search_desc_len. If a search description has ever been
- * allocated the allocated size is stored at
- * multi_search_desc_size. */
+ * allocated the allocated size is stored at multi_search_desc_size.
+ * multi_search_store is allocated at the same size as
+ * multi_search_desc and used to provde backing store for the SN and
+ * NAME elements of KEYBOX_SEARCH_DESC. */
KEYBOX_SEARCH_DESC search_desc;
KEYBOX_SEARCH_DESC *multi_search_desc;
+ struct search_backing_store_s *multi_search_store;
unsigned int multi_search_desc_size;
unsigned int multi_search_desc_len;
@@ -345,6 +355,9 @@ cmd_search (assuan_context_t ctx, char *line)
{
/* More pattern are expected - store the current one and return
* success. */
+ KEYBOX_SEARCH_DESC *desc;
+ struct search_backing_store_s *store;
+
if (!ctrl->server_local->multi_search_desc_size)
{
n = 10;
@@ -355,13 +368,21 @@ cmd_search (assuan_context_t ctx, char *line)
err = gpg_error_from_syserror ();
goto leave;
}
+ ctrl->server_local->multi_search_store
+ = xtrycalloc (n, sizeof *ctrl->server_local->multi_search_store);
+ if (!ctrl->server_local->multi_search_store)
+ {
+ err = gpg_error_from_syserror ();
+ xfree (ctrl->server_local->multi_search_desc);
+ ctrl->server_local->multi_search_desc = NULL;
+ goto leave;
+ }
ctrl->server_local->multi_search_desc_size = n;
}
if (ctrl->server_local->multi_search_desc_len
== ctrl->server_local->multi_search_desc_size)
{
- KEYBOX_SEARCH_DESC *desc;
n = ctrl->server_local->multi_search_desc_size + 10;
desc = xtrycalloc (n, sizeof *desc);
if (!desc)
@@ -369,20 +390,62 @@ cmd_search (assuan_context_t ctx, char *line)
err = gpg_error_from_syserror ();
goto leave;
}
+ store = xtrycalloc (n, sizeof *store);
+ if (!desc)
+ {
+ err = gpg_error_from_syserror ();
+ xfree (desc);
+ goto leave;
+ }
for (k=0; k < ctrl->server_local->multi_search_desc_size; k++)
- desc[k] = ctrl->server_local->multi_search_desc[k];
+ {
+ desc[k] = ctrl->server_local->multi_search_desc[k];
+ store[k] = ctrl->server_local->multi_search_store[k];
+ }
xfree (ctrl->server_local->multi_search_desc);
+ xfree (ctrl->server_local->multi_search_store);
ctrl->server_local->multi_search_desc = desc;
+ ctrl->server_local->multi_search_store = store;
ctrl->server_local->multi_search_desc_size = n;
}
- /* Actually store. */
- ctrl->server_local->multi_search_desc
- [ctrl->server_local->multi_search_desc_len++]
- = ctrl->server_local->search_desc;
+ /* Actually store. We need to fix up the const pointers by
+ * copies from our backing store. */
+ desc = &(ctrl->server_local->multi_search_desc
+ [ctrl->server_local->multi_search_desc_len]);
+ store = &(ctrl->server_local->multi_search_store
+ [ctrl->server_local->multi_search_desc_len]);
+ *desc = ctrl->server_local->search_desc;
+ if (ctrl->server_local->search_desc.sn)
+ {
+ xfree (store->sn);
+ store->sn = xtrymalloc (ctrl->server_local->search_desc.snlen);
+ if (!store->sn)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ memcpy (store->sn, ctrl->server_local->search_desc.sn,
+ ctrl->server_local->search_desc.snlen);
+ desc->sn = store->sn;
+ }
+ if (ctrl->server_local->search_desc.name_used)
+ {
+ xfree (store->name);
+ store->name = xtrystrdup (ctrl->server_local->search_desc.u.name);
+ if (!store->name)
+ {
+ err = gpg_error_from_syserror ();
+ xfree (store->sn);
+ store->sn = NULL;
+ goto leave;
+ }
+ desc->u.name = store->name;
+ }
+ ctrl->server_local->multi_search_desc_len++;
if (opt_more)
{
- /* We need to be called aagain with more pattern. */
+ /* We need to be called again with more pattern. */
ctrl->server_local->search_expecting_more = 1;
goto leave;
}
@@ -456,7 +519,7 @@ cmd_next (assuan_context_t ctx, char *line)
;
else if (ctrl->server_local->multi_search_desc_len)
{
- /* The next condition should never be tru but we better handle
+ /* The next condition should never be true but we better handle
* the first/next transition anyway. */
if (ctrl->server_local->multi_search_desc[0].mode
== KEYDB_SEARCH_MODE_FIRST)
@@ -993,6 +1056,17 @@ kbxd_start_command_handler (ctrl_t ctrl, gnupg_fd_t fd, unsigned int session_id)
}
xfree (ctrl->server_local->multi_search_desc);
+ if (ctrl->server_local->multi_search_store)
+ {
+ size_t nn;
+
+ for (nn=0; nn < ctrl->server_local->multi_search_desc_size; nn++)
+ {
+ xfree (ctrl->server_local->multi_search_store[nn].sn);
+ xfree (ctrl->server_local->multi_search_store[nn].name);
+ }
+ xfree (ctrl->server_local->multi_search_store);
+ }
xfree (ctrl->server_local);
ctrl->server_local = NULL;
}
diff --git a/kbx/keybox-search-desc.h b/kbx/keybox-search-desc.h
index 9a0df2846..f312da99b 100644
--- a/kbx/keybox-search-desc.h
+++ b/kbx/keybox-search-desc.h
@@ -83,6 +83,7 @@ struct keydb_search_desc
unsigned char grip[KEYGRIP_LEN];
unsigned char ubid[UBID_LEN];
} u;
+ byte name_used;/* The union uses NAME. */
byte snhex; /* SN above is a hexstring and not binary. */
byte fprlen; /* Only used with KEYDB_SEARCH_MODE_FPR. */
int exact; /* Use exactly this key ('!' suffix in gpg). */