From 490e0cd0bab8d8d06ffdc5b8977964d5a76a8df0 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 28 Nov 2019 11:19:33 +0100 Subject: [PATCH] kbx: Add new command DELETE. * kbx/kbxserver.c (cmd_delete): New. * kbx/frontend.c (kbxd_delete): New. * kbx/backend-kbx.c (be_kbx_delete): New. Signed-off-by: Werner Koch --- kbx/backend-kbx.c | 30 ++++++++++++++++++++++ kbx/backend.h | 2 ++ kbx/frontend.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++ kbx/frontend.h | 1 + kbx/kbxserver.c | 41 ++++++++++++++++++++++++++++++ 5 files changed, 138 insertions(+) diff --git a/kbx/backend-kbx.c b/kbx/backend-kbx.c index ff4f56773..25d4596af 100644 --- a/kbx/backend-kbx.c +++ b/kbx/backend-kbx.c @@ -425,3 +425,33 @@ be_kbx_update (ctrl_t ctrl, backend_handle_t backend_hd, ksba_cert_release (cert); return err; } + + +/* Delete the blob from the keybox. BACKEND_HD is the handle for + * this backend and REQUEST is the current database request object. */ +gpg_error_t +be_kbx_delete (ctrl_t ctrl, backend_handle_t backend_hd, db_request_t request) +{ + gpg_error_t err; + db_request_part_t part; + ksba_cert_t cert = NULL; + + (void)ctrl; + + log_assert (backend_hd && backend_hd->db_type == DB_TYPE_KBX); + log_assert (request); + + /* Find the specific request part or allocate it. */ + err = be_find_request_part (backend_hd, request, &part); + if (err) + goto leave; + + /* FIXME: We make use of the fact that we know that the caller + * already did a keybox search. This needs to be made more + * explicit. */ + err = keybox_delete (part->kbx_hd); + + leave: + ksba_cert_release (cert); + return err; +} diff --git a/kbx/backend.h b/kbx/backend.h index c372d9071..3aa848714 100644 --- a/kbx/backend.h +++ b/kbx/backend.h @@ -144,6 +144,8 @@ gpg_error_t be_kbx_insert (ctrl_t ctrl, backend_handle_t backend_hd, gpg_error_t be_kbx_update (ctrl_t ctrl, backend_handle_t backend_hd, db_request_t request, enum pubkey_types pktype, const void *blob, size_t bloblen); +gpg_error_t be_kbx_delete (ctrl_t ctrl, backend_handle_t backend_hd, + db_request_t request); #endif /*KBX_BACKEND_H*/ diff --git a/kbx/frontend.c b/kbx/frontend.c index de9373c8f..a8cbfc51e 100644 --- a/kbx/frontend.c +++ b/kbx/frontend.c @@ -469,3 +469,67 @@ kbxd_store (ctrl_t ctrl, const void *blob, size_t bloblen, log_clock ("%s: leave", __func__); return err; } + + + + +/* Delete; remove the blob identified by UBID. */ +gpg_error_t +kbxd_delete (ctrl_t ctrl, const unsigned char *ubid) +{ + gpg_error_t err; + db_request_t request; + unsigned int dbidx; + db_desc_t db; + + if (DBG_CLOCK) + log_clock ("%s: enter", __func__); + + take_read_write_lock (ctrl); + + /* Allocate a handle object if none exists for this context. */ + if (!ctrl->opgp_req) + { + ctrl->opgp_req = xtrycalloc (1, sizeof *ctrl->opgp_req); + if (!ctrl->opgp_req) + { + err = gpg_error_from_syserror (); + goto leave; + } + } + request = ctrl->opgp_req; + + /* FIXME: We force the use of the KBX backend. */ + for (dbidx=0; dbidx < no_of_databases; dbidx++) + if (databases[dbidx].db_type == DB_TYPE_KBX) + break; + if (!(dbidx < no_of_databases)) + { + err = gpg_error (GPG_ERR_NOT_INITIALIZED); + goto leave; + } + db = databases + dbidx; + + err = be_kbx_seek (ctrl, db->backend_handle, request, ubid); + if (!err) + ; /* Found - we can delete. */ + else if (gpg_err_code (err) == GPG_ERR_EOF) + { + err = gpg_error (GPG_ERR_NOT_FOUND); + goto leave; + } + else + { + log_debug ("%s: searching primary fingerprint failed: %s\n", + __func__, gpg_strerror (err)); + goto leave; + } + + err = be_kbx_delete (ctrl, db->backend_handle, request); + + leave: + release_lock (ctrl); + if (DBG_CLOCK) + log_clock ("%s: leave", __func__); + return err; +} diff --git a/kbx/frontend.h b/kbx/frontend.h index 45a8dbdbd..d7647ba44 100644 --- a/kbx/frontend.h +++ b/kbx/frontend.h @@ -41,6 +41,7 @@ gpg_error_t kbxd_search (ctrl_t ctrl, int reset); gpg_error_t kbxd_store (ctrl_t ctrl, const void *blob, size_t bloblen, enum kbxd_store_modes mode); +gpg_error_t kbxd_delete (ctrl_t ctrl, const unsigned char *ubid); #endif /*KBX_FRONTEND_H*/ diff --git a/kbx/kbxserver.c b/kbx/kbxserver.c index 511362004..5e603320a 100644 --- a/kbx/kbxserver.c +++ b/kbx/kbxserver.c @@ -522,6 +522,46 @@ cmd_store (assuan_context_t ctx, char *line) } +static const char hlp_delete[] = + "DELETE \n" + "\n" + "Delete a key into the database. The UBID identifies the key.\n"; +static gpg_error_t +cmd_delete (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err; + int n; + unsigned char ubid[UBID_LEN]; + + line = skip_options (line); + if (!*line) + { + err = set_error (GPG_ERR_INV_ARG, "UBID missing"); + goto leave; + } + + /* Skip an optional UBID identifier character. */ + if (*line == '^' && line[1]) + line++; + if ((n=hex2bin (line, ubid, UBID_LEN)) < 0) + { + err = set_error (GPG_ERR_INV_USER_ID, "invalid UBID"); + goto leave; + } + if (line[n]) + { + err = set_error (GPG_ERR_INV_ARG, "garbage after UBID"); + goto leave; + } + + err = kbxd_delete (ctrl, ubid); + + + leave: + return leave_cmd (ctx, err); +} + static const char hlp_getinfo[] = @@ -643,6 +683,7 @@ register_commands (assuan_context_t ctx) { "SEARCH", cmd_search, hlp_search }, { "NEXT", cmd_next, hlp_next }, { "STORE", cmd_store, hlp_store }, + { "DELETE", cmd_delete, hlp_delete }, { "GETINFO", cmd_getinfo, hlp_getinfo }, { "OUTPUT", NULL, hlp_output }, { "KILLKEYBOXD",cmd_killkeyboxd,hlp_killkeyboxd },