diff options
author | Werner Koch <[email protected]> | 2020-09-10 10:05:21 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2020-09-10 10:08:48 +0000 |
commit | 29977e21d18188e16e50fee95a95e05fdbd97caf (patch) | |
tree | 153025c422ab7eec318ff4c8ecfeee4914388087 | |
parent | gpg-connect-agent: Catch signals so that SIGPIPE is ignored. (diff) | |
download | gnupg-29977e21d18188e16e50fee95a95e05fdbd97caf.tar.gz gnupg-29977e21d18188e16e50fee95a95e05fdbd97caf.zip |
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 <[email protected]>
-rw-r--r-- | g10/call-keyboxd.c | 30 | ||||
-rw-r--r-- | kbx/backend-sqlite.c | 103 | ||||
-rw-r--r-- | kbx/frontend.c | 30 | ||||
-rw-r--r-- | kbx/kbxserver.c | 13 | ||||
-rw-r--r-- | kbx/keyboxd.h | 13 |
5 files changed, 127 insertions, 62 deletions
diff --git a/g10/call-keyboxd.c b/g10/call-keyboxd.c index 31bccefec..e0ee26e6b 100644 --- a/g10/call-keyboxd.c +++ b/g10/call-keyboxd.c @@ -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: diff --git a/kbx/backend-sqlite.c b/kbx/backend-sqlite.c index 67d40f0b6..c4e54298e 100644 --- a/kbx/backend-sqlite.c +++ b/kbx/backend-sqlite.c @@ -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); @@ -372,6 +388,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. */ static gpg_error_t @@ -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; diff --git a/kbx/frontend.c b/kbx/frontend.c index ea7d2e23f..48b6fffa2 100644 --- a/kbx/frontend.c +++ b/kbx/frontend.c @@ -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) { diff --git a/kbx/kbxserver.c b/kbx/kbxserver.c index 4a5e1f48a..264c3be4e 100644 --- a/kbx/kbxserver.c +++ b/kbx/kbxserver.c @@ -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; } diff --git a/kbx/keyboxd.h b/kbx/keyboxd.h index f0b705aad..22988bf1b 100644 --- a/kbx/keyboxd.h +++ b/kbx/keyboxd.h @@ -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; }; |