From 25ad3c22d79d06c16a5fc652b0a6e3ffd99ad2b6 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 24 Sep 2020 10:27:19 +0200 Subject: [PATCH] keyboxd: Implement multiple search descriptions. * kbx/kbx-client-util.c (kbx_client_data_simple): New. * kbx/backend-sqlite.c (struct be_sqlite_local_s): Add field descidx. (be_sqlite_search): Use that. * g10/call-keyboxd.c (keydb_search): Implement multi mode. -- With that change the keyboxd is at par with the keybox code. Signed-off-by: Werner Koch --- g10/call-keyboxd.c | 160 ++++++++++++++++++++++++------------------ kbx/backend-sqlite.c | 13 +++- kbx/kbx-client-util.c | 10 +++ kbx/kbx-client-util.h | 1 + 4 files changed, 112 insertions(+), 72 deletions(-) diff --git a/g10/call-keyboxd.c b/g10/call-keyboxd.c index b54dbffc4..bb9901ab9 100644 --- a/g10/call-keyboxd.c +++ b/g10/call-keyboxd.c @@ -702,95 +702,115 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, err = gpg_error (GPG_ERR_INV_ARG); goto leave; } + for (i = 0; i < ndesc; i++) + if (desc->mode == KEYDB_SEARCH_MODE_FIRST) + { + /* If any description has mode FIRST, this item trumps all + * other descriptions. */ + snprintf (line, sizeof line, "SEARCH --openpgp"); + goto do_search; + } - /* FIXME: Implement --multi */ - switch (desc->mode) + for ( ; ndesc; desc++, ndesc--) { - case KEYDB_SEARCH_MODE_EXACT: - snprintf (line, sizeof line, "SEARCH --openpgp -- =%s", desc[0].u.name); - break; + const char *more = ndesc > 1 ? "--openpgp --more" : "--openpgp"; - case KEYDB_SEARCH_MODE_SUBSTR: - snprintf (line, sizeof line, "SEARCH --openpgp -- *%s", desc[0].u.name); - break; + switch (desc->mode) + { + case KEYDB_SEARCH_MODE_EXACT: + snprintf (line, sizeof line, "SEARCH %s -- =%s", more, desc->u.name); + break; - case KEYDB_SEARCH_MODE_MAIL: - snprintf (line, sizeof line, "SEARCH --openpgp -- <%s", desc[0].u.name); - break; + case KEYDB_SEARCH_MODE_SUBSTR: + snprintf (line, sizeof line, "SEARCH %s -- *%s", more, desc->u.name); + break; - case KEYDB_SEARCH_MODE_MAILSUB: - snprintf (line, sizeof line, "SEARCH --openpgp -- @%s", desc[0].u.name); - break; + case KEYDB_SEARCH_MODE_MAIL: + snprintf (line, sizeof line, "SEARCH %s -- <%s", more, desc->u.name); + break; - case KEYDB_SEARCH_MODE_MAILEND: - snprintf (line, sizeof line, "SEARCH --openpgp -- .%s", desc[0].u.name); - break; + case KEYDB_SEARCH_MODE_MAILSUB: + snprintf (line, sizeof line, "SEARCH %s -- @%s", more, desc->u.name); + break; - case KEYDB_SEARCH_MODE_WORDS: - snprintf (line, sizeof line, "SEARCH --openpgp -- +%s", desc[0].u.name); - break; + case KEYDB_SEARCH_MODE_MAILEND: + snprintf (line, sizeof line, "SEARCH %s -- .%s", more, desc->u.name); + break; - case KEYDB_SEARCH_MODE_SHORT_KID: - snprintf (line, sizeof line, "SEARCH --openpgp -- 0x%08lX", - (ulong)desc->u.kid[1]); - break; + case KEYDB_SEARCH_MODE_WORDS: + snprintf (line, sizeof line, "SEARCH %s -- +%s", more, desc->u.name); + break; - case KEYDB_SEARCH_MODE_LONG_KID: - snprintf (line, sizeof line, "SEARCH --openpgp -- 0x%08lX%08lX", - (ulong)desc->u.kid[0], (ulong)desc->u.kid[1]); - break; + case KEYDB_SEARCH_MODE_SHORT_KID: + snprintf (line, sizeof line, "SEARCH %s -- 0x%08lX", more, + (ulong)desc->u.kid[1]); + break; - case KEYDB_SEARCH_MODE_FPR: - { - unsigned char hexfpr[MAX_FINGERPRINT_LEN * 2 + 1]; - log_assert (desc[0].fprlen <= MAX_FINGERPRINT_LEN); - bin2hex (desc[0].u.fpr, desc[0].fprlen, hexfpr); - snprintf (line, sizeof line, "SEARCH --openpgp -- 0x%s", hexfpr); - } - break; + case KEYDB_SEARCH_MODE_LONG_KID: + snprintf (line, sizeof line, "SEARCH %s -- 0x%08lX%08lX", more, + (ulong)desc->u.kid[0], (ulong)desc->u.kid[1]); + break; - case KEYDB_SEARCH_MODE_ISSUER: - snprintf (line, sizeof line, "SEARCH --openpgp -- #/%s", desc[0].u.name); - break; + case KEYDB_SEARCH_MODE_FPR: + { + unsigned char hexfpr[MAX_FINGERPRINT_LEN * 2 + 1]; + log_assert (desc->fprlen <= MAX_FINGERPRINT_LEN); + bin2hex (desc->u.fpr, desc->fprlen, hexfpr); + snprintf (line, sizeof line, "SEARCH %s -- 0x%s", more, hexfpr); + } + break; - case KEYDB_SEARCH_MODE_ISSUER_SN: - case KEYDB_SEARCH_MODE_SN: - snprintf (line, sizeof line, "SEARCH --openpgp -- #%s", desc[0].u.name); - break; + case KEYDB_SEARCH_MODE_ISSUER: + snprintf (line, sizeof line, "SEARCH %s -- #/%s", more, desc->u.name); + break; - case KEYDB_SEARCH_MODE_SUBJECT: - snprintf (line, sizeof line, "SEARCH --openpgp -- /%s", desc[0].u.name); - break; + case KEYDB_SEARCH_MODE_ISSUER_SN: + case KEYDB_SEARCH_MODE_SN: + snprintf (line, sizeof line, "SEARCH %s -- #%s", more, desc->u.name); + break; - case KEYDB_SEARCH_MODE_KEYGRIP: - { - unsigned char hexgrip[KEYGRIP_LEN * 2 + 1]; - bin2hex (desc[0].u.grip, KEYGRIP_LEN, hexgrip); - snprintf (line, sizeof line, "SEARCH --openpgp -- &%s", hexgrip); - } - break; + case KEYDB_SEARCH_MODE_SUBJECT: + snprintf (line, sizeof line, "SEARCH %s -- /%s", more, desc->u.name); + break; - case KEYDB_SEARCH_MODE_UBID: - { - unsigned char hexubid[UBID_LEN * 2 + 1]; - bin2hex (desc[0].u.ubid, UBID_LEN, hexubid); - snprintf (line, sizeof line, "SEARCH --openpgp -- ^%s", hexubid); - } - break; + case KEYDB_SEARCH_MODE_KEYGRIP: + { + unsigned char hexgrip[KEYGRIP_LEN * 2 + 1]; + bin2hex (desc->u.grip, KEYGRIP_LEN, hexgrip); + snprintf (line, sizeof line, "SEARCH %s -- &%s", more, hexgrip); + } + break; - case KEYDB_SEARCH_MODE_FIRST: - snprintf (line, sizeof line, "SEARCH --openpgp"); - break; + case KEYDB_SEARCH_MODE_UBID: + { + unsigned char hexubid[UBID_LEN * 2 + 1]; + bin2hex (desc->u.ubid, UBID_LEN, hexubid); + snprintf (line, sizeof line, "SEARCH %s -- ^%s", more, hexubid); + } + break; - case KEYDB_SEARCH_MODE_NEXT: - log_debug ("%s: mode next - we should not get to here!\n", __func__); - snprintf (line, sizeof line, "NEXT"); - break; + case KEYDB_SEARCH_MODE_NEXT: + log_debug ("%s: mode next - we should not get to here!\n", __func__); + snprintf (line, sizeof line, "NEXT"); + break; - default: - err = gpg_error (GPG_ERR_INV_ARG); - goto leave; + case KEYDB_SEARCH_MODE_FIRST: + log_debug ("%s: mode first - we should not get to here!\n", __func__); + /*fallthru*/ + default: + err = gpg_error (GPG_ERR_INV_ARG); + goto leave; + } + + if (ndesc > 1) + { + err = kbx_client_data_simple (hd->kbl->kcd, line); + if (err) + goto leave; + } } + while (ndesc); + do_search: hd->last_ubid_valid = 0; diff --git a/kbx/backend-sqlite.c b/kbx/backend-sqlite.c index 6ba1886d6..0b5155a8f 100644 --- a/kbx/backend-sqlite.c +++ b/kbx/backend-sqlite.c @@ -78,6 +78,9 @@ struct be_sqlite_local_s unsigned int filter_opgp : 1; unsigned int filter_x509 : 1; + /* The current description index. */ + unsigned int descidx; + /* The select statement has been executed with success. */ int select_done; @@ -690,7 +693,7 @@ run_select_statement (ctrl_t ctrl, be_sqlite_local_t ctx, unsigned char kidbuf[8]; - descidx = 0; /* Fixme: take from context. */ + descidx = ctx->descidx; if (descidx >= ndesc) { err = gpg_error (GPG_ERR_EOF); @@ -985,6 +988,7 @@ be_sqlite_search (ctrl_t ctrl, /* Reset */ ctx->select_done = 0; ctx->select_eof = 0; + ctx->descidx = 0; err = 0; goto leave; } @@ -996,6 +1000,7 @@ be_sqlite_search (ctrl_t ctrl, goto leave; } + again: if (!ctx->select_done) { /* Initial search - run the select. */ @@ -1131,7 +1136,11 @@ be_sqlite_search (ctrl_t ctrl, } else if (gpg_err_code (err) == GPG_ERR_SQL_DONE) { - /* FIXME: Move on to the next description index. */ + if (++ctx->descidx < ndesc) + { + ctx->select_done = 0; + goto again; + } err = gpg_error (GPG_ERR_EOF); ctx->select_eof = 1; } diff --git a/kbx/kbx-client-util.c b/kbx/kbx-client-util.c index e301ae025..f7477661f 100644 --- a/kbx/kbx-client-util.c +++ b/kbx/kbx-client-util.c @@ -339,6 +339,16 @@ kbx_client_data_release (kbx_client_data_t kcd) } +/* Send a simple Assuan command to the server. */ +gpg_error_t +kbx_client_data_simple (kbx_client_data_t kcd, const char *command) +{ + /* log_debug ("%s: sending command '%s'\n", __func__, command); */ + return assuan_transact (kcd->ctx, command, + NULL, NULL, NULL, NULL, NULL, NULL); +} + + /* Send the COMMAND down to the keyboxd associated with KCD. * STATUS_CB and STATUS_CB_VALUE are the usual status callback as used * by assuan_transact. After this function has returned success diff --git a/kbx/kbx-client-util.h b/kbx/kbx-client-util.h index 1cc68b5a0..07cf78ec7 100644 --- a/kbx/kbx-client-util.h +++ b/kbx/kbx-client-util.h @@ -28,6 +28,7 @@ typedef struct kbx_client_data_s *kbx_client_data_t; gpg_error_t kbx_client_data_new (kbx_client_data_t *r_kcd, assuan_context_t ctx, int dlines); void kbx_client_data_release (kbx_client_data_t kcd); +gpg_error_t kbx_client_data_simple (kbx_client_data_t kcd, const char *command); gpg_error_t kbx_client_data_cmd (kbx_client_data_t kcd, const char *command, gpg_error_t (*status_cb)(void *opaque, const char *line),