keyboxd: Add options --openpgp and --x509 to SEARCH.

* kbx/keyboxd.h (struct server_control_s): Replace the two request
objects by just one.  Add filter flags.
* kbx/kbxserver.c (cmd_search): Add options --openpgp and --x509.
(cmd_killkeyboxd): Do not return GPG_ERR_EOF.
* kbx/frontend.c (kbxd_release_session_info): Adjust for the new
request object.
(kbxd_search, kbxd_store, kbxd_delete): Ditto.
* kbx/backend-sqlite.c (struct be_sqlite_local_s): Add filter flags.
(run_sql_prepare): Add optional arg 'extra'.  Change callers.
(run_sql_bind_ntext): New.
(run_sql_bind_text): Just call run_sql_bind_ntext.
(run_select_statement): Add ctrl arg.  Implement the filter flags.

* g10/call-keyboxd.c (keydb_search): Use the --openpgp option.
--

As soon as we implement X.509 we need to have a way to return only
openpgp or x.509 certificates.  Gpg/gpgsm will then use the respective
flag.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2020-09-10 12:05:21 +02:00
parent 3cf9bb4d73
commit 29977e21d1
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
5 changed files with 127 additions and 62 deletions

View File

@ -687,36 +687,36 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
switch (desc->mode)
{
case KEYDB_SEARCH_MODE_EXACT:
snprintf (line, sizeof line, "SEARCH =%s", desc[0].u.name);
snprintf (line, sizeof line, "SEARCH --openpgp -- =%s", desc[0].u.name);
break;
case KEYDB_SEARCH_MODE_SUBSTR:
snprintf (line, sizeof line, "SEARCH *%s", desc[0].u.name);
snprintf (line, sizeof line, "SEARCH --openpgp -- *%s", desc[0].u.name);
break;
case KEYDB_SEARCH_MODE_MAIL:
snprintf (line, sizeof line, "SEARCH <%s", desc[0].u.name);
snprintf (line, sizeof line, "SEARCH --openpgp -- <%s", desc[0].u.name);
break;
case KEYDB_SEARCH_MODE_MAILSUB:
snprintf (line, sizeof line, "SEARCH @%s", desc[0].u.name);
snprintf (line, sizeof line, "SEARCH --openpgp -- @%s", desc[0].u.name);
break;
case KEYDB_SEARCH_MODE_MAILEND:
snprintf (line, sizeof line, "SEARCH .%s", desc[0].u.name);
snprintf (line, sizeof line, "SEARCH --openpgp -- .%s", desc[0].u.name);
break;
case KEYDB_SEARCH_MODE_WORDS:
snprintf (line, sizeof line, "SEARCH +%s", desc[0].u.name);
snprintf (line, sizeof line, "SEARCH --openpgp -- +%s", desc[0].u.name);
break;
case KEYDB_SEARCH_MODE_SHORT_KID:
snprintf (line, sizeof line, "SEARCH 0x%08lX",
snprintf (line, sizeof line, "SEARCH --openpgp -- 0x%08lX",
(ulong)desc->u.kid[1]);
break;
case KEYDB_SEARCH_MODE_LONG_KID:
snprintf (line, sizeof line, "SEARCH 0x%08lX%08lX",
snprintf (line, sizeof line, "SEARCH --openpgp -- 0x%08lX%08lX",
(ulong)desc->u.kid[0], (ulong)desc->u.kid[1]);
break;
@ -725,28 +725,28 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
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 0x%s", hexfpr);
snprintf (line, sizeof line, "SEARCH --openpgp -- 0x%s", hexfpr);
}
break;
case KEYDB_SEARCH_MODE_ISSUER:
snprintf (line, sizeof line, "SEARCH #/%s", desc[0].u.name);
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", desc[0].u.name);
snprintf (line, sizeof line, "SEARCH --openpgp -- #%s", desc[0].u.name);
break;
case KEYDB_SEARCH_MODE_SUBJECT:
snprintf (line, sizeof line, "SEARCH /%s", desc[0].u.name);
snprintf (line, sizeof line, "SEARCH --openpgp -- /%s", desc[0].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 &%s", hexgrip);
snprintf (line, sizeof line, "SEARCH --openpgp -- &%s", hexgrip);
}
break;
@ -754,12 +754,12 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
{
unsigned char hexubid[UBID_LEN * 2 + 1];
bin2hex (desc[0].u.ubid, UBID_LEN, hexubid);
snprintf (line, sizeof line, "SEARCH ^%s", hexubid);
snprintf (line, sizeof line, "SEARCH --openpgp -- ^%s", hexubid);
}
break;
case KEYDB_SEARCH_MODE_FIRST:
snprintf (line, sizeof line, "SEARCH");
snprintf (line, sizeof line, "SEARCH --openpgp");
break;
case KEYDB_SEARCH_MODE_NEXT:

View File

@ -70,6 +70,10 @@ struct be_sqlite_local_s
/* The search mode represented by the current select command. */
KeydbSearchMode select_mode;
/* The flags active when the select was first done. */
unsigned int filter_opgp : 1;
unsigned int filter_x509 : 1;
/* The select statement has been executed with success. */
int select_done;
@ -288,18 +292,29 @@ run_sql_reset (sqlite3_stmt *stmt)
}
/* Run an SQL prepare for SQLSTR and return a statement at R_STMT. */
/* Run an SQL prepare for SQLSTR and return a statement at R_STMT. If
* EXTRA is not NULL that part is appended to the SQL statement. */
static gpg_error_t
run_sql_prepare (const char *sqlstr, sqlite3_stmt **r_stmt)
run_sql_prepare (const char *sqlstr, const char *extra, sqlite3_stmt **r_stmt)
{
gpg_error_t err;
int res;
char *buffer = NULL;
if (extra)
{
buffer = strconcat (sqlstr, extra, NULL);
if (!buffer)
return gpg_error_from_syserror ();
sqlstr = buffer;
}
res = sqlite3_prepare_v2 (database_hd, sqlstr, -1, r_stmt, NULL);
if (res)
err = diag_prepare_err (res, sqlstr);
else
err = 0;
xfree (buffer);
return err;
}
@ -356,12 +371,13 @@ run_sql_bind_int64 (sqlite3_stmt *stmt, int no, sqlite3_int64 value)
/* Helper to bind a string parameter to a statement. VALUE is allowed
* to be NULL to bind NULL. */
static gpg_error_t
run_sql_bind_text (sqlite3_stmt *stmt, int no, const char *value)
run_sql_bind_ntext (sqlite3_stmt *stmt, int no,
const char *value, size_t valuelen)
{
gpg_error_t err;
int res;
res = sqlite3_bind_text (stmt, no, value, value? strlen (value):0,
res = sqlite3_bind_text (stmt, no, value, value? valuelen:0,
SQLITE_TRANSIENT);
if (res)
err = diag_bind_err (res, stmt);
@ -371,6 +387,15 @@ run_sql_bind_text (sqlite3_stmt *stmt, int no, const char *value)
}
/* Helper to bind a string parameter to a statement. VALUE is allowed
* to be NULL to bind NULL. */
static gpg_error_t
run_sql_bind_text (sqlite3_stmt *stmt, int no, const char *value)
{
return run_sql_bind_ntext (stmt, no, value, value? strlen (value):0);
}
/* Helper to bind a string parameter to a statement. VALUE is allowed
* to be NULL to bind NULL. A non-NULL VALUE is clamped with percent
* signs. */
@ -457,7 +482,7 @@ run_sql_statement_bind_ubid (const char *sqlstr, const unsigned char *ubid)
gpg_error_t err;
sqlite3_stmt *stmt;
err = run_sql_prepare (sqlstr, &stmt);
err = run_sql_prepare (sqlstr, NULL, &stmt);
if (err)
goto leave;
if (ubid)
@ -651,11 +676,13 @@ be_sqlite_release_local (be_sqlite_local_t ctx)
/* Run a select for the search given by (DESC,NDESC). The data is not
* returned but stored in the request item. */
static gpg_error_t
run_select_statement (be_sqlite_local_t ctx,
run_select_statement (ctrl_t ctrl, be_sqlite_local_t ctx,
KEYDB_SEARCH_DESC *desc, unsigned int ndesc)
{
gpg_error_t err = 0;
unsigned int descidx;
const char *extra = NULL;
descidx = 0; /* Fixme: take from context. */
if (descidx >= ndesc)
@ -672,8 +699,17 @@ run_select_statement (be_sqlite_local_t ctx,
sqlite3_finalize (ctx->select_stmt);
ctx->select_stmt = NULL;
}
else if (ctx->filter_opgp != ctrl->filter_opgp
|| ctx->filter_x509 != ctrl->filter_x509)
{
/* The filter flags changed, thus we can't reuse the statement. */
sqlite3_finalize (ctx->select_stmt);
ctx->select_stmt = NULL;
}
ctx->select_mode = desc[descidx].mode;
ctx->filter_opgp = ctrl->filter_opgp;
ctx->filter_x509 = ctrl->filter_x509;
/* Prepare the select and bind the parameters. */
if (ctx->select_stmt)
@ -683,7 +719,17 @@ run_select_statement (be_sqlite_local_t ctx,
goto leave;
}
else
err = 0;
{
if (ctx->filter_opgp && ctx->filter_x509)
extra = " AND ( p.type = 1 OR p.type = 2 )";
else if (ctx->filter_opgp && !ctx->filter_x509)
extra = " AND p.type = 1";
else if (!ctx->filter_opgp && ctx->filter_x509)
extra = " AND p.type = 2";
err = 0;
}
switch (desc[descidx].mode)
{
@ -697,7 +743,7 @@ run_select_statement (be_sqlite_local_t ctx,
err = run_sql_prepare ("SELECT p.ubid, p.type, p.keyblob"
" FROM pubkey as p, userid as u"
" WHERE p.ubid = u.ubid AND u.uid = ?1",
&ctx->select_stmt);
extra, &ctx->select_stmt);
if (!err)
err = run_sql_bind_text (ctx->select_stmt, 1, desc[descidx].u.name);
break;
@ -707,7 +753,7 @@ run_select_statement (be_sqlite_local_t ctx,
err = run_sql_prepare ("SELECT p.ubid, p.type, p.keyblob"
" FROM pubkey as p, userid as u"
" WHERE p.ubid = u.ubid AND u.addrspec = ?1",
&ctx->select_stmt);
extra, &ctx->select_stmt);
if (!err)
err = run_sql_bind_text (ctx->select_stmt, 1, desc[descidx].u.name);
break;
@ -717,7 +763,7 @@ run_select_statement (be_sqlite_local_t ctx,
err = run_sql_prepare ("SELECT p.ubid, p.type, p.keyblob"
" FROM pubkey as p, userid as u"
" WHERE p.ubid = u.ubid AND u.addrspec LIKE ?1",
&ctx->select_stmt);
extra, &ctx->select_stmt);
if (!err)
err = run_sql_bind_text_like (ctx->select_stmt, 1,
desc[descidx].u.name);
@ -728,7 +774,7 @@ run_select_statement (be_sqlite_local_t ctx,
err = run_sql_prepare ("SELECT p.ubid, p.type, p.keyblob"
" FROM pubkey as p, userid as u"
" WHERE p.ubid = u.ubid AND u.uid LIKE ?1",
&ctx->select_stmt);
extra, &ctx->select_stmt);
if (!err)
err = run_sql_bind_text_like (ctx->select_stmt, 1,
desc[descidx].u.name);
@ -776,7 +822,7 @@ run_select_statement (be_sqlite_local_t ctx,
err = run_sql_prepare ("SELECT p.ubid, p.type, p.keyblob"
" FROM pubkey as p, fingerprint as f"
" WHERE p.ubid = f.ubid AND f.kid = ?1",
&ctx->select_stmt);
extra, &ctx->select_stmt);
if (!err)
err = run_sql_bind_int64 (ctx->select_stmt, 1,
kid_from_u32 (desc[descidx].u.kid));
@ -787,7 +833,7 @@ run_select_statement (be_sqlite_local_t ctx,
err = run_sql_prepare ("SELECT p.ubid, p.type, p.keyblob"
" FROM pubkey as p, fingerprint as f"
" WHERE p.ubid = f.ubid AND f.fpr = ?1",
&ctx->select_stmt);
extra, &ctx->select_stmt);
if (!err)
err = run_sql_bind_blob (ctx->select_stmt, 1,
desc[descidx].u.fpr, desc[descidx].fprlen);
@ -798,7 +844,7 @@ run_select_statement (be_sqlite_local_t ctx,
err = run_sql_prepare ("SELECT p.ubid, p.type, p.keyblob"
" FROM pubkey as p, fingerprint as f"
" WHERE p.ubid = f.ubid AND f.keygrip = ?1",
&ctx->select_stmt);
extra, &ctx->select_stmt);
if (!err)
err = run_sql_bind_blob (ctx->select_stmt, 1,
desc[descidx].u.grip, KEYGRIP_LEN);
@ -807,9 +853,9 @@ run_select_statement (be_sqlite_local_t ctx,
case KEYDB_SEARCH_MODE_UBID:
if (!ctx->select_stmt)
err = run_sql_prepare ("SELECT ubid, type, keyblob"
" FROM pubkey"
" FROM pubkey as p"
" WHERE ubid = ?1",
&ctx->select_stmt);
extra, &ctx->select_stmt);
if (!err)
err = run_sql_bind_blob (ctx->select_stmt, 1,
desc[descidx].u.ubid, UBID_LEN);
@ -817,9 +863,20 @@ run_select_statement (be_sqlite_local_t ctx,
case KEYDB_SEARCH_MODE_FIRST:
if (!ctx->select_stmt)
err = run_sql_prepare ("SELECT ubid, type, keyblob"
" FROM pubkey ORDER by ubid",
&ctx->select_stmt);
{
if (ctx->filter_opgp && ctx->filter_x509)
extra = " WHERE ( p.type = 1 OR p.type = 2 ) ORDER by ubid";
else if (ctx->filter_opgp && !ctx->filter_x509)
extra = " WHERE p.type = 1 ORDER by ubid";
else if (!ctx->filter_opgp && ctx->filter_x509)
extra = " WHERE p.type = 2 ORDER by ubid";
else
extra = " ORDER by ubid";
err = run_sql_prepare ("SELECT ubid, type, keyblob"
" FROM pubkey as p",
extra, &ctx->select_stmt);
}
break;
case KEYDB_SEARCH_MODE_NEXT:
@ -878,7 +935,7 @@ be_sqlite_search (ctrl_t ctrl,
if (!ctx->select_done)
{
/* Initial search - run the select. */
err = run_select_statement (ctx, desc, ndesc);
err = run_select_statement (ctrl, ctx, desc, ndesc);
if (err)
goto leave;
ctx->select_done = 1;
@ -981,7 +1038,7 @@ store_into_pubkey (enum kbxd_store_modes mode,
else /* Auto */
sqlstr = ("INSERT OR REPLACE INTO pubkey(ubid,type,keyblob)"
" VALUES(:1,:2,:3)");
err = run_sql_prepare (sqlstr, &stmt);
err = run_sql_prepare (sqlstr, NULL, &stmt);
if (err)
goto leave;
err = run_sql_bind_blob (stmt, 1, ubid, UBID_LEN);
@ -1016,7 +1073,7 @@ store_into_fingerprint (const unsigned char *ubid, int subkey,
sqlstr = ("INSERT OR REPLACE INTO fingerprint(fpr,kid,keygrip,subkey,ubid)"
" VALUES(:1,:2,:3,:4,:5)");
err = run_sql_prepare (sqlstr, &stmt);
err = run_sql_prepare (sqlstr, NULL, &stmt);
if (err)
goto leave;
err = run_sql_bind_blob (stmt, 1, fpr, fprlen);
@ -1057,7 +1114,7 @@ store_into_userid (const unsigned char *ubid, enum pubkey_types pktype,
sqlstr = ("INSERT OR REPLACE INTO userid(uid,addrspec,type,ubid)"
" VALUES(:1,:2,:3,:4)");
err = run_sql_prepare (sqlstr, &stmt);
err = run_sql_prepare (sqlstr, NULL, &stmt);
if (err)
goto leave;

View File

@ -167,10 +167,8 @@ kbxd_release_session_info (ctrl_t ctrl)
{
if (!ctrl)
return;
be_release_request (ctrl->opgp_req);
ctrl->opgp_req = NULL;
be_release_request (ctrl->x509_req);
ctrl->x509_req = NULL;
be_release_request (ctrl->db_req);
ctrl->db_req = NULL;
}
@ -204,16 +202,16 @@ kbxd_search (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, unsigned int ndesc,
take_read_lock (ctrl);
/* Allocate a handle object if none exists for this context. */
if (!ctrl->opgp_req)
if (!ctrl->db_req)
{
ctrl->opgp_req = xtrycalloc (1, sizeof *ctrl->opgp_req);
if (!ctrl->opgp_req)
ctrl->db_req = xtrycalloc (1, sizeof *ctrl->db_req);
if (!ctrl->db_req)
{
err = gpg_error_from_syserror ();
goto leave;
}
}
request = ctrl->opgp_req;
request = ctrl->db_req;
if (!the_database.db_type)
{
@ -341,16 +339,16 @@ kbxd_store (ctrl_t ctrl, const void *blob, size_t bloblen,
take_read_write_lock (ctrl);
/* Allocate a handle object if none exists for this context. */
if (!ctrl->opgp_req)
if (!ctrl->db_req)
{
ctrl->opgp_req = xtrycalloc (1, sizeof *ctrl->opgp_req);
if (!ctrl->opgp_req)
ctrl->db_req = xtrycalloc (1, sizeof *ctrl->db_req);
if (!ctrl->db_req)
{
err = gpg_error_from_syserror ();
goto leave;
}
}
request = ctrl->opgp_req;
request = ctrl->db_req;
if (!the_database.db_type)
{
@ -431,16 +429,16 @@ kbxd_delete (ctrl_t ctrl, const unsigned char *ubid)
take_read_write_lock (ctrl);
/* Allocate a handle object if none exists for this context. */
if (!ctrl->opgp_req)
if (!ctrl->db_req)
{
ctrl->opgp_req = xtrycalloc (1, sizeof *ctrl->opgp_req);
if (!ctrl->opgp_req)
ctrl->db_req = xtrycalloc (1, sizeof *ctrl->db_req);
if (!ctrl->db_req)
{
err = gpg_error_from_syserror ();
goto leave;
}
}
request = ctrl->opgp_req;
request = ctrl->db_req;
if (!the_database.db_type)
{

View File

@ -277,22 +277,25 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
static const char hlp_search[] =
"SEARCH [--no-data] [[--more] PATTERN]\n"
"SEARCH [--no-data] [--openpgp|--x509] [[--more] PATTERN]\n"
"\n"
"Search for the keys identified by PATTERN. With --more more\n"
"patterns to be used for the search are expected with the next\n"
"command. With --no-data only the search status is returned but\n"
"not the actual data. See also \"NEXT\".";
"not the actual data. With --openpgp or --x509 only the respective\n"
"keys are returned. See also \"NEXT\".";
static gpg_error_t
cmd_search (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
int opt_more, opt_no_data;
int opt_more, opt_no_data, opt_openpgp, opt_x509;
gpg_error_t err;
unsigned int n, k;
opt_no_data = has_option (line, "--no-data");
opt_more = has_option (line, "--more");
opt_openpgp = has_option (line, "--openpgp");
opt_x509 = has_option (line, "--x509");
line = skip_options (line);
ctrl->server_local->search_any_found = 0;
@ -380,6 +383,8 @@ cmd_search (assuan_context_t ctx, char *line)
ctrl->server_local->inhibit_data_logging_now = 0;
ctrl->server_local->inhibit_data_logging_count = 0;
ctrl->no_data_return = opt_no_data;
ctrl->filter_opgp = opt_openpgp;
ctrl->filter_x509 = opt_x509;
err = prepare_outstream (ctrl);
if (err)
;
@ -643,7 +648,7 @@ cmd_killkeyboxd (assuan_context_t ctx, char *line)
ctrl->server_local->stopme = 1;
assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
return gpg_error (GPG_ERR_EOF);
return 0;
}

View File

@ -106,13 +106,18 @@ struct server_control_s
unsigned long client_pid;
int client_uid;
/* Two database request objects used with a connection. They are
/* The database request object used with a connection. It is
* auto-created as needed. */
db_request_t opgp_req;
db_request_t x509_req;
db_request_t db_req;
/* Flags for the current request. */
unsigned int no_data_return : 1; /* Used by SEARCH and NEXT. */
/* If the any of the filter flags are set a search returns only
* results with a blob type matching one of these filter flags. */
unsigned int filter_opgp : 1;
unsigned int filter_x509 : 1;
/* Used by SEARCH and NEXT. */
unsigned int no_data_return : 1;
};