mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19: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;
|
mode = KEYDB_SEARCH_MODE_MAILEND;
|
||||||
s++;
|
s++;
|
||||||
desc->u.name = s;
|
desc->u.name = s;
|
||||||
|
desc->name_used = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '<': /* An email address. */
|
case '<': /* An email address. */
|
||||||
@ -126,24 +127,28 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
|
|||||||
if (!openpgp_hack)
|
if (!openpgp_hack)
|
||||||
s++;
|
s++;
|
||||||
desc->u.name = s;
|
desc->u.name = s;
|
||||||
|
desc->name_used = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '@': /* Part of an email address. */
|
case '@': /* Part of an email address. */
|
||||||
mode = KEYDB_SEARCH_MODE_MAILSUB;
|
mode = KEYDB_SEARCH_MODE_MAILSUB;
|
||||||
s++;
|
s++;
|
||||||
desc->u.name = s;
|
desc->u.name = s;
|
||||||
|
desc->name_used = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '=': /* Exact compare. */
|
case '=': /* Exact compare. */
|
||||||
mode = KEYDB_SEARCH_MODE_EXACT;
|
mode = KEYDB_SEARCH_MODE_EXACT;
|
||||||
s++;
|
s++;
|
||||||
desc->u.name = s;
|
desc->u.name = s;
|
||||||
|
desc->name_used = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '*': /* Case insensitive substring search. */
|
case '*': /* Case insensitive substring search. */
|
||||||
mode = KEYDB_SEARCH_MODE_SUBSTR;
|
mode = KEYDB_SEARCH_MODE_SUBSTR;
|
||||||
s++;
|
s++;
|
||||||
desc->u.name = s;
|
desc->u.name = s;
|
||||||
|
desc->name_used = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '+': /* Compare individual words. Note that this has not
|
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;
|
mode = KEYDB_SEARCH_MODE_WORDS;
|
||||||
s++;
|
s++;
|
||||||
desc->u.name = s;
|
desc->u.name = s;
|
||||||
|
desc->name_used = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '/': /* Subject's DN. */
|
case '/': /* Subject's DN. */
|
||||||
@ -161,6 +167,7 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
desc->u.name = s;
|
desc->u.name = s;
|
||||||
|
desc->name_used = 1;
|
||||||
mode = KEYDB_SEARCH_MODE_SUBJECT;
|
mode = KEYDB_SEARCH_MODE_SUBJECT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -178,6 +185,7 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
desc->u.name = s;
|
desc->u.name = s;
|
||||||
|
desc->name_used = 1;
|
||||||
mode = KEYDB_SEARCH_MODE_ISSUER;
|
mode = KEYDB_SEARCH_MODE_ISSUER;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -205,6 +213,7 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
desc->u.name = s;
|
desc->u.name = s;
|
||||||
|
desc->name_used = 1;
|
||||||
mode = KEYDB_SEARCH_MODE_ISSUER_SN;
|
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. */
|
if (!mode) /* Default to substring search. */
|
||||||
{
|
{
|
||||||
desc->u.name = s;
|
desc->u.name = s;
|
||||||
|
desc->name_used = 1;
|
||||||
mode = KEYDB_SEARCH_MODE_SUBSTR;
|
mode = KEYDB_SEARCH_MODE_SUBSTR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,13 @@
|
|||||||
/**/: gpg_error (e))
|
/**/: 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. */
|
/* Control structure per connection. */
|
||||||
struct server_local_s
|
struct server_local_s
|
||||||
@ -84,10 +91,13 @@ struct server_local_s
|
|||||||
* cmd_search. If more than one pattern is required, cmd_search
|
* cmd_search. If more than one pattern is required, cmd_search
|
||||||
* also allocates and sets multi_search_desc and
|
* also allocates and sets multi_search_desc and
|
||||||
* multi_search_desc_len. If a search description has ever been
|
* multi_search_desc_len. If a search description has ever been
|
||||||
* allocated the allocated size is stored at
|
* allocated the allocated size is stored at multi_search_desc_size.
|
||||||
* 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 search_desc;
|
||||||
KEYBOX_SEARCH_DESC *multi_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_size;
|
||||||
unsigned int multi_search_desc_len;
|
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
|
/* More pattern are expected - store the current one and return
|
||||||
* success. */
|
* success. */
|
||||||
|
KEYBOX_SEARCH_DESC *desc;
|
||||||
|
struct search_backing_store_s *store;
|
||||||
|
|
||||||
if (!ctrl->server_local->multi_search_desc_size)
|
if (!ctrl->server_local->multi_search_desc_size)
|
||||||
{
|
{
|
||||||
n = 10;
|
n = 10;
|
||||||
@ -355,13 +368,21 @@ cmd_search (assuan_context_t ctx, char *line)
|
|||||||
err = gpg_error_from_syserror ();
|
err = gpg_error_from_syserror ();
|
||||||
goto leave;
|
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;
|
ctrl->server_local->multi_search_desc_size = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctrl->server_local->multi_search_desc_len
|
if (ctrl->server_local->multi_search_desc_len
|
||||||
== ctrl->server_local->multi_search_desc_size)
|
== ctrl->server_local->multi_search_desc_size)
|
||||||
{
|
{
|
||||||
KEYBOX_SEARCH_DESC *desc;
|
|
||||||
n = ctrl->server_local->multi_search_desc_size + 10;
|
n = ctrl->server_local->multi_search_desc_size + 10;
|
||||||
desc = xtrycalloc (n, sizeof *desc);
|
desc = xtrycalloc (n, sizeof *desc);
|
||||||
if (!desc)
|
if (!desc)
|
||||||
@ -369,20 +390,62 @@ cmd_search (assuan_context_t ctx, char *line)
|
|||||||
err = gpg_error_from_syserror ();
|
err = gpg_error_from_syserror ();
|
||||||
goto leave;
|
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++)
|
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_desc);
|
||||||
|
xfree (ctrl->server_local->multi_search_store);
|
||||||
ctrl->server_local->multi_search_desc = desc;
|
ctrl->server_local->multi_search_desc = desc;
|
||||||
|
ctrl->server_local->multi_search_store = store;
|
||||||
ctrl->server_local->multi_search_desc_size = n;
|
ctrl->server_local->multi_search_desc_size = n;
|
||||||
}
|
}
|
||||||
/* Actually store. */
|
/* Actually store. We need to fix up the const pointers by
|
||||||
ctrl->server_local->multi_search_desc
|
* copies from our backing store. */
|
||||||
[ctrl->server_local->multi_search_desc_len++]
|
desc = &(ctrl->server_local->multi_search_desc
|
||||||
= ctrl->server_local->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)
|
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;
|
ctrl->server_local->search_expecting_more = 1;
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -456,7 +519,7 @@ cmd_next (assuan_context_t ctx, char *line)
|
|||||||
;
|
;
|
||||||
else if (ctrl->server_local->multi_search_desc_len)
|
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. */
|
* the first/next transition anyway. */
|
||||||
if (ctrl->server_local->multi_search_desc[0].mode
|
if (ctrl->server_local->multi_search_desc[0].mode
|
||||||
== KEYDB_SEARCH_MODE_FIRST)
|
== 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);
|
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);
|
xfree (ctrl->server_local);
|
||||||
ctrl->server_local = NULL;
|
ctrl->server_local = NULL;
|
||||||
}
|
}
|
||||||
|
@ -83,6 +83,7 @@ struct keydb_search_desc
|
|||||||
unsigned char grip[KEYGRIP_LEN];
|
unsigned char grip[KEYGRIP_LEN];
|
||||||
unsigned char ubid[UBID_LEN];
|
unsigned char ubid[UBID_LEN];
|
||||||
} u;
|
} u;
|
||||||
|
byte name_used;/* The union uses NAME. */
|
||||||
byte snhex; /* SN above is a hexstring and not binary. */
|
byte snhex; /* SN above is a hexstring and not binary. */
|
||||||
byte fprlen; /* Only used with KEYDB_SEARCH_MODE_FPR. */
|
byte fprlen; /* Only used with KEYDB_SEARCH_MODE_FPR. */
|
||||||
int exact; /* Use exactly this key ('!' suffix in gpg). */
|
int exact; /* Use exactly this key ('!' suffix in gpg). */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user