mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-21 10:09:57 +01:00
kbx: Fix keyboxd searching with multiple patterns.
* kbx/keybox-search-desc.h (struct keydb_search_desc): New flag name_used. * common/userids.c (classify_user_id): Set flag. * kbx/kbxserver.c (struct search_backing_store_s): New. (cmd_search): use a backing store for the const pointers. (kbxd_start_command_handler): Release the backing store. -- Well, the search object partly uses buffers but also const pointers (for strings and the serial number). This when assigning such objects to an another one we should really take a deep copy and not just copy the pointer. The more clean solution would have been to provide a storage option the search object but that needs checking the code at too many places so that I decided to use a separate backing store array here. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
044e5a3c38
commit
101ba4f18a
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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). */
|
||||
|
Loading…
x
Reference in New Issue
Block a user